2012-04-13 5 views
11

(3次元)2つのベクトル間の符号付き角度を計算する方法を探しています。 this questionで答えられるように、ベクトルが垂直である平面の法線が与えられると、符号付きの角度を計算するのは簡単です。しかし、私はその価値なしでこれを行う方法が見つけられません。参照平面のない2つのベクトル間の符号付き角度

私は2番目の結果が陰性であることが期待される
signed_angle(x_dir, y_dir) == 90 
signed_angle(y_dir, x_dir) == 90 

:それは2つのベクトルの外積は、通常、私は上記の答えを使用して、次の矛盾に遭遇してきたを生成することは明らかです。

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は、これまで以上のマイナスになると信じていない:これは外積cross(x_dir, y_dir)cross(y_dir, x_dir)の反対方向にあることに起因する、正規化された入力と、次の擬似コードを与えられました。

提案されているatan2ソリューションで同じ問題が発生しました。

私が作るための方法を探しています:

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

はこれではありません:http://www.jtaylor1142001.net/calcjat/Solutions/VDotProduct/VDPTheta3D.htmあなたが探しているのは? – Jack

+0

上記のコメントのリンクは機能しません – ephere

答えて

1

ありがとうございます。ここのコメントを見直し、私がやろうとしていたことを振り返ってみると、与えられた角度の標準的な公式を使って私がしなければならないことを実現することができました。私はちょうど私の符号付きアングル機能の単体テストにつきました。

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

もっと単純にこれらの両方は、単に「正しいことを行う」必要があり、入れて、異なる方向に回転:

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

最初の引数が回転し、第二の軸が回転する量であるところ。

3

は、基準面せずに2つのベクトル間の角度を締結

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

signed_angle(、 b)== -signed_angle(b、a)

何らかのリファレンスベクトルがなければ不可能だと思います。

+0

私はもう少し考えていましたが、これは正しいです。角度の符号は、参照として使用する回転軸に依存します。もちろん、2つの異なる軸があります.1つはクロス積の方向に、もう1つは反対方向にあります。 –

+0

@JeffE:はい、クロスプロダクトを使って "回転"軸を見つけることができますが、最初に向いていた方向、つまりaクロスbまたはbクロスaスワップベクトルでは判断できません。軸が反対方向を向くようになります。結果として、回転角度が0.pi範囲内にあるか、またはそれがππ* 2範囲内にあるかを決定することは不可能である。 – SigTerm

-2

あなたが望むすべては、一貫性の結果、×Bの間で行います通常のためのB×を選ぶその後、任意の方法がある場合。おそらく辞書編集的に小さいものを選ぶでしょうか?

(しかし、あなたは、あなたが実際に解決しようとしているかの問題を説明する場合があります。多分、任意の3 - ベクトル間の一貫性のある署名の角度を計算伴わない解決策があります)

18

関連する数式: 3-Dベクトル間の強固な角度については

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

、あなたの実際の計算は次のようになります。

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

あなたはを使用している場合だけでは、角度が小さい場合に厳しい精度の問題が発生します。 sを計算し、atan2()を使用すると、すべての可能なケースで堅牢な結果が得られます。

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

+0

ありがとう、私はacosについてそれを保つでしょう。私はそれがあなたがその機能を視覚化するときは明白だと思います。 – metatheorem

+0

警告:この関数は可換性であり、+ x方向(1 0 0)から+ y方向(0 1 0)までの角度は+ 90°でなければなりません。逆もまた+ yから+ xまでは-90°でなければならない。しかしこの関数では、 'f(x、y)== f(y、x)'となります。 's'は非負であり、そのクロスプロダクトがあなたの2人の間の方向についてあなたに語った唯一のものなので、違いを知ることはできません。 –

+0

2次元であれば、それは反交換可能である。しかし、3次元では、それは可換でなければなりません。なぜなら、3次元では、キラリティーを決定するために3番目のベクトルが必要だからです。最初の2つについて正と負の角度を区別する第3のベクトルがなければ、一方の方向を他方の方向よりも好む幾何学的理由はありません。 – comingstorm

関連する問題