質問
3D空間に2つのポイント(aとb)と、nと呼ばれる固定軸/単位ベクトルがあるとします。
ポイントa(非回転)と回転ポイントbの間のユークリッド距離を最小化する回転行列を作成したい。
例:
Q := matrix_from_axis_and_angle (n, alpha);
find the unknown alpha that minimizes sqrt(|a - b*Q|)
ところで-解法/アルゴリズムを単位四元数で簡単に表現できる場合は、先に進んで使用します。私は質問を定式化するためにマトリックスを使用しました。なぜなら、それらはより広く使用されているからです。
ああ-私はいくつかの縮退したケースがあることを知っています(aまたはbはnectと正確に一致しています)。これらは無視できます。単一のソリューションを計算できる場合を探しています。
解決
かなり簡単です。単位ベクトルnは、点x0を通るnに平行な線の周りの回転を意味すると仮定します。 x0!=原点の場合、座標系を-x0だけ変換して、新しい座標系の原点0に相対するポイント a '
および b'
を取得し、代わりにそれらの2点を使用しますaとbの
1)ベクトルry = n x aを計算する
2)単位ベクトルuy =方向ryの単位ベクトルを計算する
3)単位ベクトルux = uy x nの計算
これで、右手座標系を形成する相互に垂直な単位ベクトルux、uy、nのトリプレットができました。次のことを示すことができます:
a = dot(a,n) * n + dot(a,ux) * ux
これは、単位ベクトルuyがaとnの両方に垂直なryに平行であるためです。 (ステップ1から)
4)単位ベクトルux、uyに沿ってbの成分を計算します。 aの成分は(ax、0)で、ax = dot(a、ux)です。 bのコンポーネントは(bx、by)で、bx = dot(b、ux)、by = dot(b、uy)です。右手座標系のため、axは常に正であるため、実際に計算する必要はありません。
5)theta = atan2(by、bx)を計算します。
あなたの回転行列は、n軸の周りの座標系(ux、uy、n)に対して角度-θだけ回転するものです。
aがnと平行の場合(ステップ1と2)、またはbがnと平行の場合(ステップ4、5)、これは退化した回答を生成します。
他のヒント
質問を次のように言い換えることができると思います:
ポイントから3D空間の2D円までの距離。
答えはこちら
にあります。必要な手順は次のとおりです:
- ベクトルnを中心に点bを回転させると、3D空間で2Dの円が得られます
- 上記を使用して、その円(および円上の点)までの距離を見つけます
- 円上の点は、探している回転した点bです。
- 回転角度を推測する
...または何か; ^)
aからnに沿った線へのベクトルがbからnに沿った線へのベクトルと上に並ぶ場合、距離は最小になります。
aとbをnに垂直な平面に投影し、2次元で問題を解決します。そこに到達する回転は、距離を最小化するために必要な回転です。
Pをnに垂直な平面とします。 aのP平面への射影を見つけることができます(bについても同様):
a' = a - (dot(a,n)) n
b' = b - (dot(b,n)) n
dot(a、n)はaとnのドット積です
a 'とb'はP平面にあります。
問題を2次元に減らしました。やった!
a 'とb'の間の(回転の)角度は、aに最も近くなるようにn軸の周りでbを振るのに必要な(回転の)角度に等しい。 (bがP平面に投影する影について考えてください。)
a 'とb'の角度は簡単に見つけることができます:
dot(a',b') = |a'| * |b'| * cos(theta)
シータを解きます。
ここで、シータとnが与えられた回転行列を見つけることができます: http://en.wikipedia.org/wiki/Rotation_matrix
Jason Sは、シータがわかれば、n軸を中心にbを時計回りまたは反時計回りに回転させる必要があることを正しく指摘しています。
(a x b)がnと同じ方向にある場合、量dot((a x b)、n)は正の量になり、(a x b)が反対方向にある場合は負の量になります。 (aもbもnと共線的でない限り、ゼロになることはありません。)
(a x b)がnと同じ方向にある場合、bはn軸を中心に角度thetaだけ時計回りに回転する必要があります。
(a x b)が反対方向にある場合、bはn軸を中心に角度-θだけ時計回りに回転する必要があります。