ベクトル間の角度を計算する数値的に安定した方法


13

2つのベクトル間の角度に古典的な公式を適用する場合:

α=arccosv1v2v1v2

非常に小さい/鋭角の場合、精度が失われ、結果が正確ではないことがわかります。このStack Overflow answerで説明されているように、1つの解決策は代わりにアークタンジェントを使用することです。

α=arctan2(v1×v2,v1v2)

そして、これは実際により良い結果をもたらします。しかし、これがに非常に近い角度で悪い結果を与えるのではないかと思います。そうですか?もしそうなら、ブランチ内の公差をチェックせずに角度を正確に計算する式はありますか?π/2if


1
これは、2つのパラメーターの逆正接関数の実装に依存します。低速で安定したバージョンは、精度を維持するためにx / yとy / xの処理を条件付きで切り替えますが、高速なバージョンは適切な象限に物事を固定するため、1つのパラメーターバージョンよりも正確ではありません。
-origimbo

「精度の損失」を定義する必要があります。正しい答えがあり、代わりにが得られるとします。あなたが必要ですまたは十分ですか?αα+Δαπ
ステファノM

この場合、正しい答えは、を取得しました。両方ともです。α 10 8 « 1αα1081
アストロフアンル

回答:


18

私は以前にこのアプローチをテストしましたが、正しく動作したことを覚えていますが、この質問に対して具体的にテストしたことはありません。

私の知る限りとして、両方 及びV 1V 2、彼らはどちらかの入力がオフの場合、ほぼパラレル/垂直にatan2はあなたに良い精度を与えることができないであれば壊滅的なキャンセルに苦しむことができます。v1×v2v1v2

辺の長さが三角形の角度を見つけるように問題を再定式化することから始めますv 1 | b = | v 2 | およびc = | v 1v 2 | (これらはすべて、浮動小数点演算で正確に計算されます)。カハン(針のような三角形の面積と角度の計算ミス)により、ヘロンの公式にはよく知られたバリアントがあり、面積と角度(abの間)を計算できますa=|v1|b=|v2|c=|v1v2|ab)その辺の長さで指定された三角形の、数値的に安定して行います。この副問題の削減も正確であるため、このアプローチは任意の入力に対して機能するはずです。

その論文から引用(P.3参照)、仮定Bμ = { C - - Bを場合  B C 0 B - - C 場合  C > B 0 無効三角形それ以外の場合、a n g l e = 2 arctan ab

μ={c(ab),if bc0,b(ac),if c>b0,invalid triangle,otherwise
ここのすべての括弧は慎重に配置され、重要です。負の数の平方根をとる場合、入力辺の長さは三角形の辺の長さではありません。
angle=2arctan(((ab)+c)μ(a+(b+c))((ac)+b))

Kahanの論文には、他の式が失敗する値の例を含む、これがどのように機能するかの説明があります。最初の式は4ページのC です。αC

KahanのHeronの式をお勧めする主な理由は、非常に素晴らしいプリミティブを作成するためです。潜在的にトリッキーな平面ジオメトリの質問の多くは、任意の三角形の面積/角度を見つけることで削減できるため、問題を減らすことができる場合、それのための素敵な安定した式、そしてあなた自身で何かを考え出す必要はありません。

編集ステファノさんのコメントに続いて、私はのための相対誤差のプロットを作っV 2 = COS θ 罪のθ コード)。2行はの相対誤差であるθ = εθ = π / 2 - εε水平軸に沿って行きます。動作しているようです。 v1=(1,0)v2=(cosθ,sinθ)θ=ϵθ=π/2ϵϵここに画像の説明を入力してください


リンクと回答をありがとう!残念ながら、私が書いた2番目の式は記事に記載されていません。一方、この方法は2Dで投影する必要があるため、少し複雑になる可能性があります。
アストロフアンル

2
@astrojuanluここには2dへの投影はありません。2つの3dベクトルが何であれ、それらは単一の(平面)三角形を定義します。その辺の長さを知るだけで済みます。
キリル

あなたは正しい、私のコメントは意味をなさない。長さではなく座標で考えていました。再度、感謝します!
アストロフアンル

2
@astrojuanlu私はノートにしたいもう一つは:面積式はで正確であることを正式な証拠があるようですどのように計算するために、三角形の面積:フォーマル再訪、シルヴィーボルド Flocqを使用して、。
キリル

cc<ϵmin(a,b)(v1v2)

7

この質問に対する効率的な答えは、驚くほどではないが、Velvel Kahanによる別のメモである

α=2arctan(v1v1+v2v2,v1v1v2v2)

arctan(x,y)(x,y)

ここで、Kahanの式のMathematicaデモを行いました。)


arctan2

1
arctan(x,y)ATAN2(Y, X)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.