オイラーの各軸(X/Y/Z軸)からクォータニオンへ変換する。
void XToQuaternion(Quaternion& q, float x){ q.x = sin(x * 0.5f); q.y = 0.0f; q.z = 0.0f; q.w = cos(x * 0.5f); }; void YToQuaternion(Quaternion& q, float y){ q.x = 0.0f; q.y = sin(y * 0.5f); q.z = 0.0f; q.w = cos(y * 0.5f); }; void ZToQuaternion(Quaternion& q, float z){ q.x = 0.0f; q.y = 0.0f; q.z = sin(z * 0.5f); q.w = cos(z * 0.5f); };
数式は「実例で学ぶゲーム3D数学」を参照。
- 作者: Fletcher Dunn,Ian Parberry,松田晃一
- 出版社/メーカー: オライリージャパン
- 発売日: 2008/10/04
- メディア: 大型本
- 購入: 21人 クリック: 141回
- この商品を含むブログ (41件) を見る
Euler angle(xyz/zxy/xzy/yxz/yzx/zyx) to quaternion.
void XYZToQuaternion(Quaternion& q, float x, float y, float z){ float cx = cos(x * 0.5f); float cy = cos(y * 0.5f); float cz = cos(z * 0.5f); float sx = sin(x * 0.5f); float sy = sin(y * 0.5f); float sz = sin(z * 0.5f); q.x=cy*cz*sx-cx*sy*sz; q.y=cy*sx*sz+cx*cz*sy; q.z=cx*cy*sz-cz*sx*sy; q.w=sx*sy*sz+cx*cy*cz; }; void ZXYToQuaternion(Quaternion& q, float x, float y, float z){ float cx = cos(x * 0.5f); float cy = cos(y * 0.5f); float cz = cos(z * 0.5f); float sx = sin(x * 0.5f); float sy = sin(y * 0.5f); float sz = sin(z * 0.5f); q.x=cx*sy*sz+cy*cz*sx; q.y=cx*cz*sy-cy*sx*sz; q.z=cx*cy*sz-cz*sx*sy; q.w=sx*sy*sz+cx*cy*cz; }; void XZYToQuaternion(Quaternion& q, float x, float y, float z){ float cx = cos(x * 0.5f); float cy = cos(y * 0.5f); float cz = cos(z * 0.5f); float sx = sin(x * 0.5f); float sy = sin(y * 0.5f); float sz = sin(z * 0.5f); q.x=cx*sy*sz+cy*cz*sx; q.y=cy*sx*sz+cx*cz*sy; q.z=cx*cy*sz-cz*sx*sy; q.w=cx*cy*cz-sx*sy*sz; }; void YXZToQuaternion(Quaternion& q, float x, float y, float z){ float cx = cos(x * 0.5f); float cy = cos(y * 0.5f); float cz = cos(z * 0.5f); float sx = sin(x * 0.5f); float sy = sin(y * 0.5f); float sz = sin(z * 0.5f); q.x=cy*cz*sx-cx*sy*sz; q.y=cy*sx*sz+cx*cz*sy; q.z=cx*cy*sz+cz*sx*sy; q.w=cx*cy*cz-sx*sy*sz; }; void YZXToQuaternion(Quaternion& q, float x, float y, float z){ float cx = cos(x * 0.5f); float cy = cos(y * 0.5f); float cz = cos(z * 0.5f); float sx = sin(x * 0.5f); float sy = sin(y * 0.5f); float sz = sin(z * 0.5f); q.x=cy*cz*sx-cx*sy*sz; q.y=cx*cz*sy-cy*sx*sz; q.z=cx*cy*sz+cz*sx*sy; q.w=sx*sy*sz+cx*cy*cz; }; void ZYXToQuaternion(Quaternion& q, float x, float y, float z){ float cx = cos(x * 0.5f); float cy = cos(y * 0.5f); float cz = cos(z * 0.5f); float sx = sin(x * 0.5f); float sy = sin(y * 0.5f); float sz = sin(z * 0.5f); q.x=cx*sy*sz+cy*cz*sx; q.y=cx*cz*sy-cy*sx*sz; q.z=cx*cy*sz+cz*sx*sy; q.w=cx*cy*cz-sx*sy*sz; };
数式の導出
Euler angle(xyz/zxy/xzy/yxz/yzx/zyx)からクォータニオンへ変換する数式は、wxMaximaで導出しています。
qmul(l,r) := [ l[1]*r[4] + l[4]*r[1] + l[2]*r[3] - l[3]*r[2] , l[2]*r[4] + l[4]*r[2] + l[3]*r[1] - l[1]*r[3] , l[3]*r[4] + l[4]*r[3] + l[1]*r[2] - l[2]*r[1] , l[4]*r[4] - l[1]*r[1] - l[2]*r[2] - l[3]*r[3] ]; qx:[sx ,0 ,0 ,cx]; qy:[0 ,sy ,0 ,cy]; qz:[0 ,0 ,sz ,cz]; printf(false,"==== xyz ===="); xyz:qmul(qmul(qz,qy),qx); printf(false,"==== zxy ===="); zxy:qmul(qmul(qy,qx),qz); printf(false,"==== xzy ===="); xzy:qmul(qmul(qy,qz),qx); printf(false,"==== yxz ===="); yxz:qmul(qmul(qz,qx),qy); printf(false,"==== yzx ===="); yzx:qmul(qmul(qx,qz),qy); printf(false,"==== zyx ===="); zyx:qmul(qmul(qx,qy),qz);
リンク
Euler から Quaternion へ変換する数式など。
Maths - Conversion Euler to Quaternion - Martin Baker