15

(3 次元) 2 つのベクトル間の符号付き角度を計算する方法を探していますが、これらのベクトル以外の情報はありません。この質問で回答されているように、ベクトルが垂直である平面の法線が与えられた場合、符号付き角度を計算するのは簡単です。しかし、その価値がなければこれを行う方法が見つかりません。2 つのベクトルの外積がそのような法線を生成することは明らかですが、上記の答えを使用して次の矛盾に遭遇しました。

signed_angle(x_dir, y_dir) == 90
signed_angle(y_dir, x_dir) == 90

2番目の結果が負になると予想されます。これは、正規化された入力を使用した次の疑似コードを考えると、外積cross(x_dir, y_dir)が の反対方向にあるという事実によるものです。cross(y_dir, x_dir)

signed_angle(Va, Vb)
    magnitude = acos(dot(Va, Vb))
    axis = cross(Va, Vb)
    dir = dot(Vb, cross(axis, Va))
    if dir < 0 then
        magnitude = -magnitude
    endif
    return magnitude

上記で dir が負になることはないと思います。

提案されたatan2ソリューションで同じ問題を見てきました。

私は作る方法を探しています:

signed_angle(a, b) == -signed_angle(b, a)
4

4 に答える 4

19

関連する数式:

  dot_product(a,b) == length(a) * length(b) * cos(angle)
  length(cross_product(a,b)) == length(a) * length(b) * sin(angle)

3Dベクトル間の角度をロバストにするには、実際の計算は次のようになります。

  s = length(cross_product(a,b))
  c = dot_product(a,b)
  angle = atan2(s, c)

単独で使用するacos(c)と、角度が小さい場合に深刻な精度の問題が発生します。計算sして使用atan2()すると、考えられるすべてのケースで堅牢な結果が得られます。

は常に非負であるためs、結果の角度は0からpiの範囲になります。常に同等の負の角度(angle - 2*pi)がありますが、それを好む幾何学的な理由はありません。

于 2012-04-13T16:54:49.837 に答える
3

Signed angle between two vectors without a reference plane

angle = acos(dotproduct(normalized(a), normalized(b)));

signed_angle(a, b) == -signed_angle(b, a)

I think that's impossible without some kind of reference vector.

于 2012-04-13T01:05:27.400 に答える
2

皆さんありがとう。ここのコメントを見直して、自分がやろうとしていたことを振り返ってみると、与えられた符号付き角度の標準的な公式を使用して、必要なことを達成できることに気付きました。署名付き角度関数の単体テストでハングアップしました。

参考までに、結果の角度を回転関数に戻しています。これは当然、signed_angle (入力ベクトルの外積) と同じ軸を使用し、正しい回転方向はその軸が向いている方向に従うという事実を説明できませんでした。

もっと簡単に言えば、これらは両方とも「正しいことを行い」、異なる方向に回転する必要があります。

rotate(cross(Va, Vb), signed_angle(Va, Vb), point)
rotate(cross(Vb, Va), signed_angle(Vb, Va), point)

最初の引数は回転軸で、2 番目の引数は回転量です。

于 2012-04-19T05:11:36.203 に答える
-2

一貫した結果が必要な場合は、法線に対してa × bb × aのいずれかを選択する任意の方法で十分です。おそらく、辞書編集的に小さいものを選択しますか?

(ただし、実際に解決しようとしている問題を説明したい場合があります。任意の 3-ベクトル間の一貫した符号付き角度を計算することを含まない解決策があるかもしれません。)

于 2012-04-13T10:49:19.690 に答える