つのXYZ座標を整列する方法


最近、私は手動追跡ARSに取り組んでいます.手に3 Dモデルを整列させるために、私は手などの3 Dモデルのような効果を作るために手の座標に3 Dモデルオブジェクトの座標と一致しなければならなかった.
それらを整列させるのは少し複雑ですので、ここでどうするか説明しましょう.

仮定


ターゲットXYZ(例えば手)と座標XYZ(例えば3 Dモデル)を整列させる必要があるとしましょう.xzとxyzのベクトルを既に知っている.X/Y/Zは直交し、正規化されている(長さは1 )、x/y/zもある.目標はxyzベクトルをxyzに並べることである.

XYZ原点位置をXYZ原点位置に設定するだけで、原点位置を揃えることはできません.
次の手順では、z/zとx/xを合わせますが、操作の順序は問題ではありません.Y/Y最初とZ/Zを次の位置に並べるかもしれません.

zをzに整列


まず、Z軸を合わせましょう.

クロスベクトルの周りの座標を回転させるために使用されるドット積およびアークコサインを有するクロスベクトルz × Zおよびθを計算する.回転を達成するために、quaternionを使用することができます.私たち自身で四元数を計算すると、通常複雑な3 D CGエンジンは、軸から回転し、角度を計算する組み込み関数を内蔵しています.本当に自分で実装したいなら、this articleを参照してください.

これは擬似コードの例です.あなたのプログラミング言語/3 D CGエンジン(例えばThree . js/Unity/Unrealエンジン)は、クロス/ドット/正規化/acos/fromaxisangleを持つべきです.
Vec3 z = ... // Your z
Vec3 Z = ... // Your Z
Vec3 axisZ = normalize(cross(z, Z)); // Normalized cross vector.
float angleZ = acos(dot(z, Z)); // The angle between z and Z --> theta in the image.
Quaternion qz = fromAxisAngle(axisZ, angleZ); // Later we will make other quaternions so let's name it qz.
今、私たちはZ軸からZ軸に整列する四元数qzを持っています.

xをxに整列する


四元数qzを座標に適用すると、次のイメージのようにX\/Y\/Z 'を持つ必要があります.

X/X軸の位置合わせは基本的にZ/Zと同じプロセスである.z/zが既に整列しているので、xとxは同じ平面上にある.X/Xが整列したとき、Y/Yは自動的に整列します.ただし、四元数qzをXベクトルに適用することを忘れないでください.回転したxベクトルをx'としましょう.

擬似コードはこのようになります.applyQuaternionは四元数をベクトルに適用する関数である.あなたのプログラミング言語/3 Dエンジンは同等であるべきです.
Vec3 rotatedX = applyQuaternion(x, qz); // x'
Vec3 X = ... // Your X
Vec3 axisX = normalize(cross(rotatedX, X));
float angleX = acos(dot(rotatedX, X)); // The angle between x' and X --> phi in the image
Quaternion qx = fromAxisAngle(axisX, angleX);
我々は次の四元数qxを持っている.

組み合わせ四元数


現在、我々はqzqxを持っています.四元数を組み合わせることによって、我々は最終的な四元数を持つことになる.multiplyQuaternionsは2つの四元数を一つに結合する関数である.あなたのプログラミング言語/3 Dエンジンは同等であるべきです.qz及びqxの注文が重要であることに注意してください.
Quaternion q = mltiplyQuaternions(qx, qz);
四元数qをX/Y/Zにそれぞれ適用することで、x/y/zと同じベクトルを得るでしょう.

付録:3 .JSコード


上記で擬似コードを示しました.私も、あなたに3に例を与えます.js
// Your coordinates.
// x/y/z are vectors that will be aligned FROM.
const x = new Vector3(...);
const y = new Vector3(...);
const z = new Vector3(...); // <-- You do not need this actually.

// X/Y/Z are vectors that will be aligned TO.
const X = new Vector3(...);
const Y = new Vector3(...);
const Z = new Vector3(...); // <-- You do not need this actually.


const axisZ = z.clone().cross(Z).normalize();
const angleZ = Math.acos(z.dot(Z));
const qz = new Quaternion().setFromAxisAngle(axisZ, angleZ);

const rotatedX = x.clone().applyQuaternion(qz);
const axisX = rotatedX.clone().cross(X).normalize();
const angleX = Math.acos(rotatedX.dot(X));
const qx = new Quaternion().setFromAxisAngle(axisX, angleX);

// Final quaternion
const q = new Quaternion().multiplyQuaternions(qx, qz);

// You can use q like this.
yourModel.rotation.setFromQuaternion(q)
必要に応じて私のDemoをチェックすることができます!