日々適当
hibitekitou

(算数)2つのベクトルの角度を求める 内積のお話

sansu |2005-03-09
ベクトルAとベクトルBの角度を求めるとき、内積を利用できる。すなわち、
内積の公式
である。XSIでは内積はdotで得られる。

c = A.dot (B)

で ベクトルaとbの内積cが得られる。そこで、以下のように書いてみた。A,Bとそれぞれ名づけられたNullがあらかじめ存在しいて、ベクトルOAとOBのなす角度を求めている。
Dim vecA,vecB,vecC,trans,dot,digAngle,Angle

set vecA = XSIMath.CreateVector3
set vecB = XSIMath.CreateVector3

set A = ActiveSceneRoot.findChild("A")
set B = ActiveSceneRoot.findChild("B")

A.Kinematics.Global.Transform.GetTranslation(vecA)
B.Kinematics.Global.Transform.GetTranslation(vecB)

logmessage "A:("& vecA.x &","& vecA.y &","& vecA.z &")"
logmessage "B:("& vecB.x &","& vecB.y &","& vecB.z &")"

'※1
dot = vecA.dot ( vecB )

'※2
cosAngle = dot/(vecA.length * vecB.length)

'※3
Angle = Atn((Sqr(1 - cosAngle^2)/cosAngle))

'※4
degAngle = XSIMath.RadiansToDegrees (Angle)

logmessage "Answer by dot:"& degAngle

'※5
Angle = vecA.Angle ( vecB )
degAngle = XSIMath.RadiansToDegrees(Angle)
logmessage "Answer by angle:"& degAngle
※1でvecAとvecBの内積を得ている。
※2で
内積の公式
の右辺を計算している。
※3でVBにはcosの逆関数が無いそうなので、唯一存在するtanの逆関数Atnからcosの逆関数を出している。
※4では、※3で出てくる値はラジアンなのでこれをRadianToDegreesでもって度数に直している。

これで角度を求められる。ただし、※3において、二つのベクトルのなす角が90度のとき0で除算することになり、エラーで止まる。


ところで、XSIには2つのベクトルの角度を求める便利なもんが存在しているので、※5のように

A.Angle (B)

を使った方がよほど簡単である(^^;;
コメント ( 0 )|Trackback ( 0 )

(算数)ベクトルの足し算と引き算 AddInPlace Add,SubInPlace,Sub

sansu |2005-03-09
ベクトルの足し算


なんか今更こんなんやるのもなんだけど、お勉強していきます。XSIでベクトル同士の足し算はAddInPlaceを使うそうです。

a.AddInPlace b

とすると、aにbが足されそれがaに入るようですね。

ということで、Nullを3つ配置して、それぞれをA,B,Cと命名しておき、OAにOBを足した結果がOCになるようなスクリプトを書くと以下のようになるんでしょうか?(Oは原点と思ってください。で、OAとかOBとかOCの上には→がついているイメージで(^^;)

Dim vecA,vecB,vecC,trans

set vecA = XSIMath.CreateVector3
set vecB = XSIMath.CreateVector3
set vecC = XSIMath.CreateVector3
'vecCはCの座標を取り出すし表示するために利用するだけ

set A = ActiveSceneRoot.findChild("A")
set B = ActiveSceneRoot.findChild("B")
set C = ActiveSceneRoot.findChild("C")

A.Kinematics.Global.Transform.GetTranslation(vecA)
B.Kinematics.Global.Transform.GetTranslation(vecB)

logmessage "A:("& vecA.x &","& vecA.y &","& vecA.z &")"
logmessage "B:("& vecB.x &","& vecB.y &","& vecB.z &")"

vecA.AddInPlace vecB

set trans = C.Kinematics.Global.Transform

trans.SetTranslation vecA

C.Kinematics.Global.Transform = trans

C.Kinematics.Global.Transform.GetTranslation(vecC)
logmessage "C:("& vecC.x &","& vecC.y &","& vecC.z &")"

この結果、例えば
'INFO : A:(3,3,3)
'INFO : B:(4,4,4)
'INFO : C:(7,7,7)
と出力されてきます。

追記。vecA + vecB の結果を直接vecCにぶち込むことも、Addを利用すれば可能でした(^^;

c.Add a,b

ですね。だから上のスクリプトは以下の内容でもよかったようです。
Dim vecA,vecB,vecC,trans

set vecA = XSIMath.CreateVector3
set vecB = XSIMath.CreateVector3
set vecC = XSIMath.CreateVector3

set A = ActiveSceneRoot.findChild("A")
set B = ActiveSceneRoot.findChild("B")
set C = ActiveSceneRoot.findChild("C")

A.Kinematics.Global.Transform.GetTranslation(vecA)
B.Kinematics.Global.Transform.GetTranslation(vecB)

logmessage "A:("& vecA.x &","& vecA.y &","& vecA.z &")"
logmessage "B:("& vecB.x &","& vecB.y &","& vecB.z &")"

vecC.Add vecA,vecB

set trans = C.Kinematics.Global.Transform

trans.SetTranslation vecC

C.Kinematics.Global.Transform = trans
logmessage "C:("& vecC.x &","& vecC.y &","& vecC.z &")"

引き算はAddに対しSub。だから、上のAddのスクリプト中のAddをSubに変えて、例えばAを(3,3,0)、Bを(3,-3,0)にしたとき、Cは(0,6,0)になる。
ベクトルの引き算
コメント ( 0 )|Trackback ( 0 )
  ・次ページ »