Noh | エンジニア向け情報共有コミュニティ
Signup / Login

Quaternionから回転軸と回転角度を取り出す

y
yosi2024/08/23 5:36

three.js/src/math/Quaternion.jsのsetFromAxisAngleメソッドの実装を以下に示します。

setFromAxisAngle( axis, angle ) { // http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm // assumes axis is normalized const halfAngle = angle / 2, s = Math.sin( halfAngle ); this._x = axis.x * s; this._y = axis.y * s; this._z = axis.z * s; this._w = Math.cos( halfAngle ); this._onChangeCallback(); return this; }

setFromAxisAngleの逆の処理を行う関数を作成してください。Quaternionを引数に取り、axis, angleを返す関数とします。

A
Answerer AIPowered by gpt-3.5-turbo

以下に、setFromAxisAngleメソッドの逆の処理を行う関数の実装例を示します。

function getAxisAngleFromQuaternion(quaternion) { // 入力されたクォータニオンを正規化します const norm = Math.sqrt(quaternion.x * quaternion.x + quaternion.y * quaternion.y + quaternion.z * quaternion.z + quaternion.w * quaternion.w); const normalizedQuaternion = { x: quaternion.x / norm, y: quaternion.y / norm, z: quaternion.z / norm, w: quaternion.w / norm }; // クォータニオンから軸と角度を計算します const angle = 2 * Math.acos(normalizedQuaternion.w); const s = Math.sqrt(1 - normalizedQuaternion.w * normalizedQuaternion.w); let axis = { x: 0, y: 0, z: 0 }; if (s >= 0.0001) { axis.x = normalizedQuaternion.x / s; axis.y = normalizedQuaternion.y / s; axis.z = normalizedQuaternion.z / s; } return { axis, angle }; }

この関数を利用すると、次のようにQuaternionオブジェクトからaxisとangleを取得できます。

const quaternion = new Quaternion(); // クォータニオンの設定を行う // ... const { axis, angle } = getAxisAngleFromQuaternion(quaternion); console.log("axis:", axis); console.log("angle:", angle);

この例のgetAxisAngleFromQuaternion関数は、入力されたクォータニオンを正規化した上で、そのクォータニオンから軸と角度を計算しています。

y
yosi2024/08/23 5:37
https://github.com/mrdoob/three.js/blob/master/src/math/Quaternion.js#L275
y
yosi2024/08/23 6:01

getAxisAngleFromQuaternion内の処理の解説を行ってください。

A
Answerer AIPowered by gpt-3.5-turbo

こちらのgetAxisAngleFromQuaternion関数は、与えられたQuaternionオブジェクトから軸と角度を計算するための関数です。

まず、Quaternionオブジェクトを正規化します。Quaternionオブジェクトのx、y、z、wの値のノルム(長さ)を計算し、それぞれの値をノルムで割ることで、正規化を行います。これにより、クォータニオンの要素は単位ベクトルで表されるようになります。

次に、クォータニオンから軸と角度を計算します。式angle = 2 * acos(クォータニオンのw成分)により、クォータニオンの回転角度を求めます。また、式s = sqrt(1 - クォータニオンのw成分の2乗)により、回転軸の正規化用の値sを計算します。

最後に、sの値によって回転軸の各成分を計算します。sが0.0001以上の場合、回転軸は(クォータニオンのx成分/s, クォータニオンのy成分/s, クォータニオンのz成分/s)として計算されます。

関数は、計算した軸と角度をオブジェクトとして返します。

この関数を使用することで、与えられたQuaternionオブジェクトから回転軸と角度を取得することができます。

y
yosi2024/08/23 6:16

Math.sqrt(1 - normalizedQuaternion.w * normalizedQuaternion.w)を使って正規化することで軸を導出できる根拠を教えてください。

A
Answerer AIPowered by gpt-3.5-turbo

Math.sqrt(1 - normalizedQuaternion.w * normalizedQuaternion.w)を使って回転軸を導出する根拠は、回転クォータニオンがユニタリ(ノルムが1)であるためです。

回転クォータニオンのノルムは、x、y、z、wの成分から以下のように計算されます:Math.sqrt(x*x + y*y + z*z + w*w)

しかし、この式では回転軸のノルムが1になるわけではありません。回転クォータニオンのノルムを1にするためには、各成分をノルムで割る必要があります。

したがって、クォータニオンオブジェクトを正規化することで、次のような関係式が成り立つようになります:x*x + y*y + z*z + w*w = 1

また、クォータニオンのw成分がcos(θ/2)と関連する回転角度であることを考慮すると、(1 - normalizedQuaternion.w * normalizedQuaternion.w)sin(θ/2)の2乗に対応します。

回転軸の求め方として、クォータニオンのノルムを1とするため、sin(θ/2)に対応する値を求める必要があります。そのため、Math.sqrt(1 - normalizedQuaternion.w * normalizedQuaternion.w)を使用して回転軸のノルムを求めることができるのです。

この計算によって正規化された回転軸を使用することで、正しい回転の表現を得ることができます。

コメントするにはログインが必要です