8

3番目のベクトル(X)に垂直で、互いに垂直な2つのベクトルを計算する最良の(最速の)方法は何ですか?

これは、現在このベクトルを計算する方法です。

// HELPER - unit vector that is NOT parallel to X
x_axis = normalize(X);
y_axis = crossProduct(x_axis, HELPER);
z_axis = crossProduct(x_axis, y_axis);

これには無数の解決策があることを私は知っており、どれが私の解決策になるかは気にしません。

この質問の背後にあるもの: X 軸 (マトリックスの最初の列) がどの方向を指すべきかを知っている変換マトリックスを作成する必要があります。Y 軸と Z 軸 (2 列目と 3 列目) を計算する必要があります。ご存知のように、すべての軸は互いに垂直でなければなりません。

4

5 に答える 5

6

私が行ったこと、X<>0またはY<>0ある場合

  1. A = [-Y, X, 0]
  2. B = [-X*Z, -Y*Z, X*X+Y*Y]

次に、ベクトルを正規化します。

[ X,Y,Z]·[-Y,X,0] = -X*Y+Y*X = 0
[ X,Y,Z]·[-X*Z,-Y*Z,X*X+Y*Y] = -X*X*Z-Y*Y*Z+Z*(X*X+Y*Y) = 0
[-Y,X,0]·[-X*Z,-Y*Z,X*X+Y*Y] = Y*X*Z+X*Y*Z = 0

これは、ベクトルのnullspaceと呼ばれます。

もしX=0Y=0そしてA=[1,0,0]B=[0,1,0]

于 2012-05-22T14:04:14.923 に答える
3

これがそれを行う方法です。
それはおそらくそれを行う唯一の方法でもあります。他の方法は数学的に同等です。
crossProductの計算を開き、同じ乗算を2回以上実行しないようにすることで、数サイクルを節約できる可能性がありますが、それはマイクロ最適化の領域にはほど遠いものです。

注意すべきことの1つは、もちろんHELPERベクトルです。Xに平行である必要はないだけでなく、Xに非常に平行ではないこともお勧めします。XとHELPERがいくらか平行になると、浮動小数点の計算が不安定になり、不正確になります。 。XとHELPERの内積が0.9999のようなものである場合、何が起こるかをテストして確認できます。

于 2012-05-22T12:36:51.690 に答える
3

適切な HELPER を見つける方法があります (実際には、y_axis になる準備ができています)。

X = (ax, ay, az) としましょう。マグニチュードの大きいエレメントを2つ選び、交換し、そのうちの1つを無効にします。3 番目の要素 (最小の大きさ) をゼロに設定します。このベクトルは X に垂直です。

例:

(ax <= ay) および (ax <= az) の場合、HELPER = (0, -az, ay) (または (0, az, -ay))

X*ヘルパー = 0*0 - ay*az + az*ay = 0

(ay <= ax) および (ay <= az) の場合、HELPER = (az, 0, -ay)

于 2012-05-22T13:15:25.600 に答える
1

適切な HELPER ベクトルの場合:絶対値が最小の X の座標を見つけ、その座標軸を使用します。

absX = abs(X.x); absY = abs(X.y); absZ = abs(X.z);
if(absX < absY) {
  if(absZ < absX)
    HELPER = vector(0,0,1);
  else // absX <= absZ
    HELPER = vector(1,0,0);
} else { // absY <= absX
  if(absZ < absY)
    HELPER = vector(0,0,1);
  else // absY <= absZ
    HELPER = vector(0,1,0);
}

注: これは @MBo の回答と事実上非常に似ています: 最小の座標軸で外積を取ることは、最小の座標をゼロに設定し、大きい方の 2 つを交換し、1 つを否定することと同じです。

于 2012-05-22T18:17:23.740 に答える
0

単位ベクトルのすべての要素の最小最大マグナチュードは常に0.577より大きいと思うので、これでうまくいくかもしれません:

-> マグナチュードが 0.5 より大きい要素を見つけて、3D ベクトルから 2D ベクトルへの垂直ベクトルを見つける問題を軽減し、別の要素を無視して (代わりに 0 を使用)、2D ベクトルに垂直を適用します。残りの要素の式 (2D の x 軸 =(ax,ay) -> y 軸 =(-ay,ax))

let x-axis be represented by (ax,ay,az)

if (abs(ay) > 0.5) {
  y-axis = normalize((-ay,ax,0))
} else if (abs(az) > 0.5) {
  y-axis = normalize((0,-az,ay))
} else if (abs(ax) > 0.5) {
  y-axis = normalize((az,0,-ax))
} else {
  error("Impossible unit vector")
}
于 2012-09-02T03:00:38.210 に答える