質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

3DCG

コンピュータの演算により、3次元空間の仮想物体を、2次元平面上で表現する手法である。

DXライブラリ

DXライブラリとは、DirectXを使ったWindowsソフトの開発に必ず付いて回るDirectXやWindows関連のプログラムを使い易くまとめた形で利用できるようにしたC++言語用のゲームライブラリです。

Q&A

解決済

2回答

7632閲覧

回転軸の方向を表すベクトルの求め方が知りたい 周回軌道のように回る回転 三次元

退会済みユーザー

退会済みユーザー

総合スコア0

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

3DCG

コンピュータの演算により、3次元空間の仮想物体を、2次元平面上で表現する手法である。

DXライブラリ

DXライブラリとは、DirectXを使ったWindowsソフトの開発に必ず付いて回るDirectXやWindows関連のプログラムを使い易くまとめた形で利用できるようにしたC++言語用のゲームライブラリです。

0グッド

0クリップ

投稿2020/04/08 02:15

編集2020/04/19 04:35

DxLibですので座標系は 奥がz右がX上がYです。
回転軸の方向とはどのうような意味なのでしょうか? 調べましたが色々な分野が出来てしまい欲しい情報が手に入りませんUnityの提示画像のようなカメラがキャラクターの後ろをついて行くという3Dアクションゲームでよくある表現のカメラ回転を実装したいのですがクォータニオンを使いカメラの座標と回転軸の正規化ベクトルとラジアンを使って目的の方向に回転させるという処理の回転軸の意味と取得方法が知りたいです。
※その後回答から上に周回回転するベクトルはcamera - target;により解決しましたが 横に周回回転するベクトルを得る方法が知りたいです。

数式でいうことろの参考サイトの"クォータニオンに回転を与える"原点を中心とした軸ベクトルの意味です。

参考サイト: https://wgld.org/d/webgl/w031.html

pos 現在座標 カメラ
targetV は中心座標(カメラの注視点)Unity画像ではプレイヤーモデル
ang はθ

ですこの情報から回転軸の方向を取得できるのでしょうか?

とりえあず関数を作り必要そうな引数を用意しましたが計算方法がわからないため中身はまだ作れません
原点座標に変換して回転して最後にワールド座標に戻すという方法をrotate();関数で実行しています。

/*回転する座標、ラジアン、中心、軸*/ void Game::rotate(Vector *pos,const float ang, const Vector targetV,const Vector axis) { //Quaternion Prev(0, Vector(*x - mx, *y - my, *z - mz)); Quaternion P(0, Vector(pos->x, pos->y, pos->z));//回転させる点 Quaternion P2(0, Vector(pos->x - targetV.x, pos->y - targetV.y, pos->z - targetV.z));//回転させる点 Quaternion PP(0, Vector(targetV.x - pos->x, targetV.y - pos->y, targetV.z - pos->z));//回転させる点 Quaternion PP3(0,Vector(targetV.x , targetV.y , targetV.z ));//回転させる点 Quaternion Q(cos(ang / 2), Vector( axis.x * sin(ang / 2), axis.y * sin(ang / 2), axis.z * sin(ang / 2))); Quaternion R(cos(ang / 2), Vector(-axis.x * sin(ang / 2) , -axis.y * sin(ang / 2), -axis.z * sin(ang / 2))); Quaternion result = (R * P2) * Q;//順番が大事 ofs << "pos.x:" << pos->x << std::endl; ofs << "pos.y:" << pos->y << std::endl; ofs << "pos.z:" << pos->z << "\n" << std::endl; ofs << "result.x:" << result.v.x << std::endl; ofs << "result.y:" << result.v.y << std::endl; ofs << "result.z:" << result.v.z << "\n\n\n" << std::endl; pos->x = result.v.x + targetV.x; pos->y = result.v.y + targetV.y; pos->z = result.v.z + targetV.z; /* pos->x = result.v.x; pos->y = result.v.y; pos->z = result.v.z; */ } void Game::Update() { /*カメラ回転*/ if (Input::keyboard(KEY_INPUT_LEFT) > 0) { Vector a = Vector::cross((targetV - cameraPos),Vector(0,-1,0)); float f = sqrt(pow(a.x,2) + pow(a.y,2) + pow(a.z,2)); a.x = a.x / f; a.y = a.y / f; a.z = a.z / f; rotate(&cameraPos, ROTATE_SPEED, targetV, Vector(0, -1, 0)); //r += -ROTATE_SPEED; } else if (Input::keyboard(KEY_INPUT_RIGHT) > 0) { Vector a = Vector::cross(targetV - cameraPos, Vector(0, 1, 0)); float f = sqrt(pow(a.x, 2) + pow(a.y, 2) + pow(a.z, 2)); a.x = a.x / f; a.y = a.y / f; a.z = a.z / f; rotate(&cameraPos, ROTATE_SPEED, targetV, Vector(0, 1, 0)); } else if (Input::keyboard(KEY_INPUT_UP) > 0) { Vector a = Vector::cross(targetV - cameraPos, Vector(-1, 0, 0)); float f = sqrt(pow(a.x, 2) + pow(a.y, 2) + pow(a.z, 2)); a.x = a.x / f; a.y = a.y / f; a.z = a.z / f; rotate(&cameraPos, ROTATE_SPEED, targetV, Vector(-1,0,0)); DrawFormatString(100,100,GetColor(255,255,255),"UP"); } else if (Input::keyboard(KEY_INPUT_DOWN) > 0) { Vector a = Vector::cross(targetV - cameraPos, Vector(1, 0, 0)); float f = sqrt(pow(a.x, 2) + pow(a.y, 2) + pow(a.z, 2)); a.x = a.x / f; a.y = a.y / f; a.z = a.z / f; rotate(&cameraPos, ROTATE_SPEED, targetV, Vector(1, 0, 0)); } if (Input::keyboard(KEY_INPUT_W) > 0) { } else if (Input::keyboard(KEY_INPUT_S) > 0) { } // Vector aa = Vector::cross(Vector(3,4,1),Vector(3,7,5)); Vector a = Vector::cross((targetV - cameraPos), Vector(0, -1, 0)); float f = sqrt(pow(a.x, 2) + pow(a.y, 2) + pow(a.z, 2)); a.x = a.x / f; a.y = a.y / f; a.z = a.z / f; Vector tt = (targetV - cameraPos); DrawFormatString(100, 100, GetColor(255, 255, 255), "ベクトルの外積: %f , %f , %f ", a.x, a.y, a.z); DrawFormatString(100, 200, GetColor(255, 255, 255), "aaa : %f , %f , %f ",tt.x,tt.y,tt.z); // SetCameraPositionAndAngle(VGet(cameraPos.x, cameraPos.y, cameraPos.z), r, 0, 0); }

DxLibですが画面はUnity上で再現したものなのです。カメラを視覚的にわかりやすくするためにデバッグ用のカメラモデルと落としてきたり頂点を設定したりと結構大変なのでコードの集中するためUnityでイメージ画像としてキャプチャしました。

イメージ説明
イメージ説明
横から見た図↓
イメージ説明

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fana

2020/04/08 02:54

どのように回転させたいのか? 次第なので,所望の回転を説明する図として, {回転前の座標pos,回転後の座標, targetV, ang }が含まれる絵を示すとよいのではないかと思います.
stdio

2020/04/08 02:56

プログラムを提示して下さい。
fana

2020/04/08 03:01 編集

この質問は > この情報から回転軸の方向を取得できるのでしょうか? となっているので, コードを書く以前の(純然たる計算内容の)話であろうと思うので,プログラムの提示というのは必ずしも必要ではないのでは. {個々の情報が何なのか? どう使いたいのか?}(「注視点」ってのは,やりたい回転にどう影響する要素なの?とかそういう)という話さえ明確であれば.
fana

2020/04/08 03:04

あと,複数の座標系が存在する場合には,個々の要素がどの座標系での値なのかを明記した方がよいですね.
fana

2020/04/08 05:50

> カメラがキャラクターの後ろをついて行くという3Dアクションゲームでよくある表現のカメラ回転 実装しようとしている関数rotate()で行う「回転」というのは何になるのですか? 「ある時刻ではカメラがキャラクタの後ろらへんにあって,そこから(例えば次のフレームまでの間に)キャラクタの位置と姿勢が動いたときに,カメラがそれが追従して付いて行かなくてはならない」みたいな話における,(フレーム間での)カメラ位置姿勢の更新(のうちの姿勢のみ?)という話なのでしょうか?
退会済みユーザー

退会済みユーザー

2020/04/08 07:23

"カメラがそれが追従して付いて行かなくてはならない" ですがとりあえずtargetを中心にカメラを回転させたいですそのための回転軸とは何か?どうやって算出するのかの回転軸を算出するための関数になります。
stdio

2020/04/08 08:16 編集

回転軸とは正規化されたベクトルの事を指します。 どうやって算出するかと言われても、「ベクトル作れば」としか言えません。 ていうか、なんで画面がDXライブラリではないの? 私からすれば、「最初からそっちでやっておけよ」と言いたいです。
退会済みユーザー

退会済みユーザー

2020/04/08 09:51

DxLibですが画面はUnity上で再現したものなのです。カメラを視覚的にわかりやすくするためにデバッグ用のカメラモデルと落としてきたり頂点を設定したりと結構大変なのでコードの集中するためUnityでイメージ画像としてキャプチャしました。
guest

回答2

0

とりあえずtargetを中心にカメラを回転させたいですそのための回転軸とは何か?どうやって算出するのか

(↑質問への追記・修正の依頼 の欄より引用)

中心点の座標(target)だけ与えられて「回転しろ」と言われても,下図のように1点を中心にしてその周りを回転する方向というのは無数に存在するので困るわけです.

イメージ説明

回転軸とは,どちらに回転するのか?を示すための情報ですから,
どうすれば求まるのか?というのは,「どのように回転させたいのか?」という,やりたいこと次第です.

例えば,「地面からの高さを保ったまま動かしたい」みたいな話が追加で存在すれば,下図の様に回転させるべき方向が定まります.
このとき,「回転軸」というのは下図の赤い破線(と平行な軸)のことです.
回転の軌跡を円で書いたときに,その円が乗る平面と直交する方向ベクトルです.
竹とんぼで言えば,棒の部分の向きです.
この例であれば,この軸の方向を表すベクトルというのはわざわざ計算するまでもなく定数で与えることができるでしょう.
(単位ベクトルして表すとしたら,地面と鉛直な方向というのがY軸と平行なのであれば (0,1,0) あるいは (0,-1,0) として.)

イメージ説明

どちらに回転させるべきか? が.その時々のデータ値によって定まるような話である場合には,回転軸は適切な演算によって求めねばならないでしょうが,その計算内容というのは前述の通り「やりたいこと次第」ということになります.


ちなみに,上記の例での(0,1,0)とか(0,-1,0)という単位ベクトルというのは,軸の方向を表すベクトルであって,軸がどこにあるのか?という位置については何も表していません.

{pos,targetV,回転軸の方向を示す単位ベクトル}の値がある座標系の上で与えられているときに,
そこらでググって出てくるような回転の話を用いると,回転軸はその座標系の原点を通ることになります.
つまり,上図で言えば,targetVのXおよびZ座標が共に0である場合でないと,この図の丸い矢印のような回転軌跡にはなりません.
なので,この図のように「回転軸がtaregetVを通って欲しい」場合には,

  1. 位置targetVが原点になるような座標系にデータを一旦全て座標変換する
  2. その座標系の上で回転処理を行う
  3. 1.とは逆の座標変換を行って,元の座標系にデータを戻す

という処理を行えば良いです.
(上記の1.と3.は実際には単なる平行移動(加減算)です.)


図を貼るために,コメント内容をこちらに持って来ましたが,
下図のような回転の軸(axis)を算出する方法がわからないということですか?

イメージ説明

図内オレンジ色矢印で示した方向に回転を行いたいとすれば,そのためには「赤い「回転軸」と平行な単位ベクトルが得られればよい」という話までは,これまでのやりとりからOKかと思います.
青矢印はオレンジ色の円弧の接線方向ベクトルです.
この赤い軸は図内の緑破線と青矢印の両者に直交していますから,この軸の方向を向くベクトルというのは両者の方向を表すベクトルの外積から求まるというのもOKですか?
(OKじゃない場合は外積について復習されたい)

  • 前者(緑破線)は説明するまでもなく posとtargetVとを通る直線ですから,この方向のベクトルは余裕で算出できますな.
  • 後者(青矢印)の側に関しては,コメント内では「接線方向ベクトル」と述べましたが,オレンジの矢印と同じ平面上に乗っている(且つ緑破線と平行でない)ならば別に何でもよいのですぞ.求めたいものが回転の軌跡(オレンジ矢印)が乗る平面の法線なのであるから,当該平面を定めるために緑破線の他に平面に沿うベクトルがもう一本欲しいと言うだけの話ですからな.

で,こいつをどう用意するのか?に関しては,行いたい回転の方向に合わせて都度都度適切に用意するしかないので頑張ってどうぞ!,ということになります(ヒントはコメントに書いている).
ただし,ある特定の(方向の)回転に関してだけ考えればよくて,且つ,扱える範囲にも制約を設けて良いならば,例えば(0,1,0)とか固定で与えることが可能な世界は存在するでしょうから,コメントにて「まずは(0,1,0)でやってみたら?」とか言っているのはそういうことですぞ.
青矢印にある固定の方向を与えることを考えてみれば,targetVとposの位置関係次第ではこの青矢印と緑破線が平行になってしまい両者の外積から軸を算出できないということがわかるでしょう.しかしこれは逆に言えばそうなる位置関係を運用上避けることができるならば固定でもOKじゃん?という話ですぞ.

投稿2020/04/08 08:38

編集2020/04/10 09:51
fana

総合スコア11654

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fana

2020/04/08 09:04 編集

うーん,書き方がよくないかなぁ. 「回転軸」という語が,文章内の場所によって ・回転方向を定めるための(単位)方向ベクトル ・実際の回転の中心となる軸(位置と方向の両者を備える) のどっちを指しているのかがこの文章で読み取れるかどうか…?
退会済みユーザー

退会済みユーザー

2020/04/08 10:17 編集

上の側の図の方ですがクォータニオンに使う回転軸の場合targetVを通り周回すると思われますそのために回転軸をクォータニオンの数式に使うので算出する必要があると思うのですが実際のところどうなのでしょうか?質問内容を変えないように提示画像を追加しました。三枚目のようなカメラ軌道を作りたいです
退会済みユーザー

退会済みユーザー

2020/04/08 10:33 編集

上がる回転軸ベクトルです。
fana

2020/04/08 14:43

> クォータニオンに使う回転軸の場合targetVを通り周回する 四元数ならばそのような特殊効果が得られる的な話は存在しないものと認識しています.
fana

2020/04/08 14:48

(この回答の内容自体は,回転計算の実装に四元数を使うか否かとは無関係ですが) 四元数を使うとしたら,虚数成分を作る際に与える「回転軸」というのは, > 回転方向を定めるための(単位)方向ベクトル のことです.
退会済みユーザー

退会済みユーザー

2020/04/09 01:29

回転方向を定めるための(単位)方向ベクトルとはどのように算出するのでしょうか?上に行きたいので0,1,0ですがtarget の方向を向いているcameraPosの座標からY軸に向かう方向?が知りたいです
fana

2020/04/09 02:17

正直, 【何が不明点であるのか?】 がわかりません. ご自身で > 0,1,0ですが と書いていますし…???
退会済みユーザー

退会済みユーザー

2020/04/09 02:20

つまりcameraPosがtargetVを向いた時の上に回る軌道を描くための回転ベクトルの計算方法が知りたいです。
ozwk

2020/04/09 03:04

1. カメラの回転はカメラの位置座標の回転移動とカメラの座標系の回転を行わなければならない。この2つは演算方法が異なる。 2. クォータニオンの回転移動は原点中心である。原点中心以外でやりたいなら平行移動を別途行う必要がある。 3. 「よくある」カメラ操作というのは左右を向く回転(ワールド座標の上下方向軸)と、上下を向く回転(カメラの左右方向軸)の組み合わせである。 4. こんな面倒なことをミスなく実装するのは凡人には不可能。学習目的ならいきなり0からやるのではなく、ライブラリやフレームワークの力を使いまくって目的の動作を実現したところから徐々に自前での計算に移行したほうがいい。
退会済みユーザー

退会済みユーザー

2020/04/09 03:22 編集

質問ですがライブラリを使う場合はどうしたらいいのでしょうか?Dxライブラリなのでそこまで高度なライブラリがないのですが
ozwk

2020/04/09 03:22

そのままunityでunityが用意したものを少しずつ自分の実装に置き換えてください C++で1から実装とかいきなりレベル上げすぎるからイマイチ話が通じない質問を繰り返す羽目になるんです。
退会済みユーザー

退会済みユーザー

2020/04/09 07:04 編集

Unityでは実装できましたがAPIの力というか仕組みが強すぎるので参考にならないのです。 なるほど、わかりました。 質問ですが "位置targetVが原点になるような座標系にデータを一旦全て座標変換する" とは加減算とありますが それぞれの要素x,y,z,を引き算するのでしょうか? また原点をずらす?方法とはどうやるのでしょうか? 追記  int SetCameraPositionAndAngleを使えばできそうなので解決とします。
fana

2020/04/10 01:24

・当該座標変換は,あなたの別の質問で実装されていたのを見た記憶があります. ・この質問の内容が解決したようには見えませんが,一旦閉じるのも有りだと思います.(解決しない場合はどうすんの?っていう話が無いよね,このサイト.そういう場合は放置するしか?)
退会済みユーザー

退会済みユーザー

2020/04/10 01:26

やりたいことが伝わらないので閉めますw
fana

2020/04/10 02:10

A4の紙の上のどこかに点を描いたとして, その位置(座標)を「紙の左上の角から,右に何mm,下に何mm」として表現することもできるし, そうじゃなくて,任意の位置に直交する2本の線を描いてそれを座標系の定義(2本の線の交点が原点で,2本の線が2つの軸)だと見なして,その勝手に考えた座標系の上での座標として表現することもできる. 前者で表現されている座標値を後者の表現での座標値に読み変える(変換する)というのが,「座標変換」.ただそれだけの話. (ここで,2つの座標系の座標軸の方向が完全に一致しているならば,その計算内容は加減算なわけ) 多分,何かを難しく考えすぎなんじゃないかな,とは思うけども,それが何なのかがわかりませんでした.
退会済みユーザー

退会済みユーザー

2020/04/10 02:21

前の一次変換の数式になる原点と思わせる?座標の計算引き算をして計算後その答えに引き算した座標を足してると思いますがそれとにたようなことをやればいいと思ったのですが違うのでしょうか? https://teratail.com/questions/245295
fana

2020/04/10 02:34

それと同等のことをすれば良いと思います. そこの足し引きの「意味」が「何かわからんけど引いたり足したりしている」ではなく,「座標変換なのだ(+それを行う理由まで)」ということが理解できていれば,今後いろいろと応用も効くでしょう.
退会済みユーザー

退会済みユーザー

2020/04/10 02:41 編集

自分もそうだと思い提示コードの/*ここの行の計算*/の変数P2部の計算をしてみましたが周回してくれません。P2の計算をすることによってP2を原点だと思わせているはずです。Update();関数も見ましたが余計なものありません。つまりP2は注視点であり原点でもあるはずなのですが... ※提示コードの時点ではPにしていますがP2を試しました。
fana

2020/04/10 02:55

> その答えに引き算した座標を足してる が無いのでは?
退会済みユーザー

退会済みユーザー

2020/04/10 02:57

その答えというには変数resultですか?
fana

2020/04/10 03:03

あなたの文章から引用したのに,それがあなたの実装においてどの変数に該当するのかを私に訊きますか…? 現在の実装における「答え」というのは,最終的にposに突っ込まれているのではないのですか? であれば,pos (あるいはそこに突っ込んでいる result.v )がそれに該当するのではないでしょうか.
退会済みユーザー

退会済みユーザー

2020/04/10 03:11

posは原点を中心とした座標が求まってるのでそこにその差?であるP2.vの結果を足し算しましたが result.v + P2.v;しましたが結果が合わないのです。ものすごい大きい座標になってしまいおかしいので 逆にするなり色々触りましたが "現在座標 - 注視点で 原点と思わせる座標を算出しそれを最後に足すという"理解はできるのですが何故か実装できません
fana

2020/04/10 03:32

・pos' = pos - targetV ・pos'' = pos'を原点周りに回転した結果 ・最終結果 = pos'' + targetV ということになってますか? なってるのに結果がおかしいという場合,それは実装バグだと思います. 実装しているつもりの計算を紙上で行い,行っている(ハズの)計算内容自体が妥当であることをまずは確認してください.
退会済みユーザー

退会済みユーザー

2020/04/10 03:43 編集

治りました。が先ほどから実行時の初期座標の状態では左右上下に動きますが。たとえば左に動いたあと上に動くとその場所を中心にくるくる回ってしまい周回軌道のように回らず"カメラがチュウチュウトレイン状態"になってしまいます。axisの設定が悪いのでしょうか?
fana

2020/04/10 04:05 編集

よくわからんが,すげーエスパーしてみると…… 多分, 2点{pos,targetV}を通る直線と直交する単位ベクトルを「回転軸(の方向を示す単位ベクトル)」(引数axisかな)として与えれば,やりたいことになるのではなかろうか. (もちろん,前記「直交する単位ベクトル」は無限に存在するから,あともう1個条件を与えて,自由度を制限する必要がある.) 試しに,以下の2つのベクトルの外積を単位化してaxisに用いてみたらどうなるのかを見てみては? ・ tagetV - pos (これが前記「2点を通る直線」に相当) ・ 現在のカメラ座標系のY方向ベクトルをワールド座標系で書いたもの(これがもう1個の条件で,行いたい回転の軌跡(円)の接線方向ベクトル)  :これをすぐに用意できないなら,とりあえず最初はかわりに(0,1,0)とか与えてみれば,開始後しばらくの間だけは相応に動くかもしれない.(すなわち ,外積( targetV-pos, (0,1,0) ) を単位化したものをaxisとして用いる)
fana

2020/04/10 04:09

targetVがカメラの「注視点」なのだから, 「現在のカメラ座標系のX方向単位ベクトルをワールド座標系で書いたもの」をaxisに用いる,と言えば済んだか.
退会済みユーザー

退会済みユーザー

2020/04/10 04:52

axisを(0,-1,0)にしてみましたが上手くいきません。なぜでしょうか?axis(0,0,-1);は動きませんでしたw 単位ベクトルについては自分で調べました。カメラ座標を単位ベクトルに変換したら次はどうしたらいいのでしょうか? https://study-line.com/vector-tani/
fana

2020/04/10 09:54 編集

コメント(2020/04/10 12:59 )の内容を図入りで回答に追記しました.これ以上わかりやすく説明できる自信がないです. (途中から丁寧に書くのが面倒になってぶっきらぼうな文面になっていますが,ご容赦願いたく) 他の方からのより良い説明が得られることに期待する次第.
退会済みユーザー

退会済みユーザー

2020/04/14 12:26

遅くなりましたが意味はわかりましたがなぜ実装できないのでしょうか?原点座標をずらし最後に座標を戻すこをちゃんとrotate();関数で行っています   Vector a = Vector::cross((targetV - cameraPos),Vector(0,-1,0)); float f = sqrt(pow(a.x,2) + pow(a.y,2) + pow(a.z,2)); a.x = a.x / f; a.y = a.y / f; a.z = a.z / f; rotate(&cameraPos, ROTATE_SPEED, targetV, a);
fana

2020/04/15 03:27

本件は方法論に関する話と捉えていますので,特定の実装に関する不具合の話を含めたくないと考えています. 個人的には以下を行うことを推奨します. (1)正解がわかる入力パターン(:例えば回転角度45度とか90度みたいな,回転結果(=正解)が自明なパターン)に関して(複数パターンで),「手計算で」検算してみる. この時点で結果が合わないならば,残念ながらあなたの考えも私の回答も何もかもが間違っているということですから,それをいくら実装していても無駄ということなので. (2) (1)で計算内容(方法論)が妥当であることが確認できたならば,単なる実装バグである. →デバッグする.rotate()内の各途中段階のあるべき値も(1)の時点でわかっているから,ステップ実行なりして照合していき,どの段階で誤るかを突き止める.
退会済みユーザー

退会済みユーザー

2020/04/19 07:00 編集

失礼ですが自己解決したのですが挙動は正しいのでしょうか?DxLibのほうにコンソール出力したコードを移行してしっかり動いていますが数式上どうなのでしょうか?
退会済みユーザー

退会済みユーザー

2020/04/19 06:59 編集

上のコメントで以上です。間違えました。
fana

2020/04/21 03:12

なんというか,「"自己解決"とは何か?」という気分にはなりますが,とりあえず解決したようで何より. まぁ他の人に同じようなことをしない方が良いんじゃないかと思います.
guest

0

ベストアンサー

以前カメラを左右に動いて上下に動いたときにその場所をにカメラの座標がおかしな挙動をしたのですが
以下のようにget_axis();関数を設定しました。y引数にはVector(0,1,0),Vector(0,-1,0),を設定して単位化してrotate();関数に渡すことによってその場所場所での向き?を得ることができて左右に移動後も挙動が正しいことがわかりました。今まで最初はしっかり動いていたのはtarget座標がほぼ原点だったためかと思います。

/*単位化する関数*/ void normalize(Vector* v) { float magnitude = sqrt(Vector::dot(*v, *v)); v->x /= magnitude; v->y /= magnitude; v->z /= magnitude; } /*軸方向回転*/ Vector get_axis(Vector camera, Vector target, Vector y) { Vector rel = Vector( camera.x - target.x, camera.y - target.y, camera.z - target.z ); Vector n = Vector::cross(y, rel); normalize(&n);//単位化 return n; } /*回転する座標、ラジアン、中心、軸*/ void Game::rotate(Vector *pos,const float ang, const Vector targetV,const Vector axis) { //Quaternion Prev(0, Vector(*x - mx, *y - my, *z - mz)); Quaternion P(0, Vector(pos->x, pos->y, pos->z));//回転させる点 Quaternion P2(0, Vector(pos->x - targetV.x, pos->y - targetV.y, pos->z - targetV.z));//回転させる点 Quaternion PP(0, Vector(targetV.x - pos->x, targetV.y - pos->y, targetV.z - pos->z));//回転させる点 Quaternion PP3(0,Vector(targetV.x , targetV.y , targetV.z ));//回転させる点 Quaternion Q(cos(ang / 2), Vector( axis.x * sin(ang / 2), axis.y * sin(ang / 2), axis.z * sin(ang / 2))); Quaternion R(cos(ang / 2), Vector(-axis.x * sin(ang / 2) , -axis.y * sin(ang / 2), -axis.z * sin(ang / 2))); Quaternion result = (R * P2) * Q;//順番が大事 ofs << "pos.x:" << pos->x << std::endl; ofs << "pos.y:" << pos->y << std::endl; ofs << "pos.z:" << pos->z << "\n" << std::endl; ofs << "result.x:" << result.v.x << std::endl; ofs << "result.y:" << result.v.y << std::endl; ofs << "result.z:" << result.v.z << "\n\n\n" << std::endl; pos->x = result.v.x + targetV.x; pos->y = result.v.y + targetV.y; pos->z = result.v.z + targetV.z; } void Game::Update() { /*カメラ回転*/ if (Input::keyboard(KEY_INPUT_LEFT) > 0) { rotate(&cameraPos, ROTATE_SPEED, targetV, Vector(0,1,0)); } else if (Input::keyboard(KEY_INPUT_RIGHT) > 0) { rotate(&cameraPos, ROTATE_SPEED, targetV, Vector(0, -1, 0)); } else if (Input::keyboard(KEY_INPUT_UP) > 0) { // rotate(&cameraPos, ROTATE_SPEED, targetV, Vector(-1, 0, 0)); rotate(&cameraPos, ROTATE_SPEED, targetV, get_axis(cameraPos , targetV,Vector(0,1,0)) ); } else if (Input::keyboard(KEY_INPUT_DOWN) > 0) { rotate(&cameraPos, ROTATE_SPEED, targetV, get_axis(cameraPos, targetV, Vector(0, -1, 0))); } if (Input::keyboard(KEY_INPUT_W) > 0) { } else if (Input::keyboard(KEY_INPUT_S) > 0) { } }

投稿2020/04/19 06:58

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問