2012-02-08 4 views
4

ベクトルのxとzの値が同じであるという事実を知っていれば、 は、y平面の違いから '垂直'角度を測定することにのみ関係しています。ドットプロダクトの計算と比較してですか?次のように内積の方法を使用して1つの平面内の2つのベクトルの間の角度を効率的に取得するには?

私の現在のコードは次のとおりです。

float a_mag = a.magnitude(); 
float b_mag = b.magnitude(); 
float ab_dot = a.dot(b); 
float c = ab_dot/(a_mag * b_mag); 

// clamp d to from going beyond +/- 1 as acos(+1/-1) results in infinity 
if (c > 1.0f) { 
    c = 1.0; 
} else if (c < -1.0) { 
    c = -1.0; 
} 

return acos(c); 

私は、これらの平方根

+1

「acos(1)== 0」と「acos(-1)== PI」という微妙なことはどちらも無限大ではありません。関数 'acos'は' [-1、1] 'の間隔で定義され、この間隔を越えて' acos'は* undefined *です。 – 0605002

+0

説明をありがとう! – kbirk

+0

私は非常に基本的な質問をするつもりです。あなたは角度が必要ですか?非常に頻繁に、私は角度を取得すると、私は直ちにそれをベクトルに戻すか、まっすぐな代数的解決法が私がしていることに対してより良く働くことを見出します。 –

答えて

3

を取り除くことができるようにするのが大好きだあなたの二つのベクトルがu = (x, y1, z)v = (x, y2, z)に住んでいることを仮定2つのベクトルにまたがる平面に沿った2つの平面の間の角度に興味があります。あなたは内積と大きさを計算する必要があると思いますが、あなたは、いくつかの操作を保存することができます:

u.v = x.x + y1.y2 + z.z 
u^2 = x.x + y1.y1 + z.z 
v^2 = x.x + y2.y2 + z.z 

だから我々は、事前に計算する必要があります

float xz = x*x + z*z, y11 = y1*y1, y12 = y1*y2, y22 = y2*y2; 

float cosangle = (xz + y12)/sqrt((xz + y11) * (xz + y22)); 
float angle = acos(cosangle); 
+0

'v^2 = x.x + y2.y2 + z.z'ですね。 – 0605002

+0

@FlopCoder:うん - コピー/ペーストがいつもずっと進んでいるわけではない:-S –

+0

素晴らしい! 1 sqrt()ダウン!今度は別の関数で同じことをしますが、この場合を除いて、yの値の1つが常に0になるので、y12とy22の変数が必要になります。したがって、cosangle = xz/sqrt((xz + y11)* xz)になります。最終的なsqrt()を取り除く方法はありますか? – kbirk

1

をXとZの値が変更されていない場合は、計算は非常に簡単です:基本三角法を使用してください。

ポイントを​​と(x, y2, z)とします。ベクトルがZX平面で作る角度を知ることができます。角度をそれぞれt1t2とします。 1つの落とし穴あります

w = sqrt(x^2 + z^2) 
tan(t1) = y1/w 
So t1 = atan(y1/w) 
Similarly t2 = atan(y2/w) 
The angle is (t2 - t1) 

:次に、XおよびZの両方がゼロであり、tan sが未定義である...しかし、そのような些細な場合は、容易に別々に取り扱うことができます。

残念ながら、平方根を避ける方法はないようです。

関連する問題