やりたいこと
「コンソール出力にて値を確認しています。 原点(0,0,0)を中心点とするクォータニオンによる回転はできるのですが中心点を原点とするクォータニオンによる回転の実装方法が
知りたいです。 上に移動することは出来ました?が 横に周回するときにtargetPosとcameraPosのY軸が値が違うときにY軸も動いてしまい動作がおかしいです。」
Vectorは三次元の座標です、Quaternionクラスはaが実部で三つは虚部(Vector)です,Vectorは自作クラスですcross,dotが関数として実装されていますが動作を確認したので正しいです。
#include "Vector.hpp"
#include <iostream>
using namespace std;
#define PI_F 3.14159265358979323846264338327950288f
/*単位化する関数*/
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 y = Vector(0, 1, 0);
// Vector y = Vector(1, 0, 1);
Vector n = Vector::cross(y, rel);
normalize(&n);
return n;
}
/*回転する座標、ラジアン、中心、軸*/
Vector 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;
return pos;
}
Vector cameraPos(-6, 20, -6.0f);//カメラ座標
//Vector targetPos(0, 5, 12.5f);//注視点座標
Vector targetPos(3, 5, 4);//注視点座標
//Vector targetPos(0,0,0);//注視点座標
const float ROTATE_SPEED = PI_F / 90;//回転スピード
Vector v = cameraPos;
int main()
{
printf("cemeraPos 初期座標: %.2f , %.2f , %.2f \n", cameraPos.x, cameraPos.y, cameraPos.z);
for(int i = 0; i < 100; i++){
Vector axis = get_axis(v, targetPos,Vector(1,0,1));
v = rotate(v, ROTATE_SPEED, targetPos, axis);
// v = rotate(v,ROTATE_SPEED,targetPos,Vector(0,-1,0));
printf("cameraPos 移動後座標: %d , %d , %d \n",(int)v.x, (int)v.y, (int)v.z);
}
int _ch = getchar();
return 0;
}