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でイメージ画像としてキャプチャしました。
回答2件
あなたの回答
tips
プレビュー