ラベル rotation の投稿を表示しています。 すべての投稿を表示
ラベル rotation の投稿を表示しています。 すべての投稿を表示

2010年12月22日水曜日

rotationが交換可能なときっす(2)

昨日の続きになるっす。
結論まで一気にやるっすね。
どうもぺんぎんっす( ◎v◎ )


昨日の記事を読んでない場合は読んでからの方が良いっすよ。
http://northernpenguin-ex.blogspot.com/2010/12/rotation.html

a * b と b * a の各要素を比較して
x要素について a.y * b.z = a.z * b.y -①
y要素について a.z * b.x = a.x * b.z -②
z要素について a.x * b.y = a.y * b.x -③
ここからスタートっす。

場合分けするっす。
I aがZERO_ROTATIONのとき
b.x、b.y、b.zの値によらず成り立つ。

II a.x≠0 かつ a.y=0 かつ a.z=0 のとき
②より b.z=0
③より b.y=0
②または③より b.xの値によらず成り立つ。
同様にして、
a.x=0 かつ a.y≠0 かつ a.z=0 のとき
 b.x = b.z = 0 のとき、b.yの値によらず成り立つ。
a.x=0 かつ a.y=0 かつ a.z≠0 のとき
 b.x = b.y = 0 のとき、b.zの値によらず成り立つ。

III a.x≠0 かつ a.y≠0 かつ a.z=0 のとき
②より b.z=0
 A b.y=0 のとき
 ③より b.x=0
 ∴ bはZERO_ROTATION
 B b.y≠0 のとき
 ③より b.x≠0
 ③の両辺を b.x * b.y で割ると
 
a.x / b.x = a.y / b.y
 uを0以外の実数として a.x / b.x = a.y / b.y = u とすると
 a.x = u * b.x
 a.y = u * b.y と書けるから
 A = (a.x, a.y, 0), B = (b.x, b.y, 0) とすると
 A = uB となる。
 ∴O = (0, 0, 0)とすると、BはOA上にある
同様にして、a.x≠0 かつ a.y=0 かつ a.z≠0 のとき
a.x=0 かつ a.y≠0 かつ a.z≠0 のときも
  bはZERO_ROTATION または
  BはOA上にある。

IV a.x≠0 かつ a.y≠0 かつ a.z≠0 のとき
 A b.z=0のとき
 ①より b.y=0
 ②より b.x=0
 ∴ bはZERO_ROTATION
 B b.z≠0のとき
 ①より b.y≠0
 ②より b.x≠0
 ①の両辺を b.y * b.z で割ると
 a.y / b.y = a.z / b.z -④
 ②の両辺を b.x * b.x で割ると
 a.z / b.z = a.x / b.x -⑤
 ③の両辺を b.x * b.y で割ると
 a.x / b.x = a.y / b.y -⑥
 ④⑤⑥より uを0以外の実数として
 b.x = u * a.x
 b.y = u * a.y
 b.z = u * a.z と書けるから
 A = (a.x, a.y, a.z), B = (b.x, b.y, b.z) とすると
 A = uB となる。
 ∴O = (0, 0, 0)とすると、BはOA上にある


これで場合分けが完了っす。
キーは「BはOA上にある」、これっす。
IIもa.x = u * b.x のカタチに出来るので、これもまとめられるっす。

OAとかOBっていうのは回転軸を表すベクトルっす。
というわけで結論は
「回転軸が同じなら交換可能」
っていうのが分かったっす。

2010年12月21日火曜日

rotationが交換可能なときっす

rotationではa * b と b * a が一致しないことが多いんっすけど、
逆に一致することもあるわけっす。
どんな条件があるのか考えてみたっす。
どうもぺんぎんっす( ◎v◎ )


まず、明らかなのは
 ・a = b のとき
 ・b = ZERO_ROTATION / a のとき
これらは見た瞬間に分かるっすね。
他の場合が無いか、考えてみるっす。

作戦はa * b と b * a を計算して、x、y、z、sの各要素を比較するっす。
式が4本出るので、そこから考えて行くっす。
とりあえず積を出すっす。
どっちか片方書けば、もう片方はaとbを入れ替えれば良いっすね。
というわけでa * bを計算するっす。
c = a * b とすると、
c.x = a.s * b.x + a.x * b.s + a.y * b.z - a.z * b.y
c.y = a.s * b.y + a.y * b.s + a.z * b.x - a.x * b.z
c.z = a.s * b.z + a.z * b.s + a.x * b.y - a.y * b.x
c.s = a.s * b.s - a.x * b.x - a.y * b.y - a.z * b.z

s要素はaとbを入れ替えても同じになるっすね。
ということは実質3本の式になるっす。
x、y、z要素についてもaとbを入れ替えたら同じになる部分は
緑で表示しておいたっす。
比較するときに両方で出てくるので、消える部分になるっす。

a * b と b * a の各要素を比較して
x要素について a.y * b.z = a.z * b.y -①
y要素について a.z * b.x = a.x * b.z -②
z要素について a.x * b.y = a.y * b.x -③
①②③を満たすようなbを選べばa * bとb * a は一致するっす。


もうちょっと変形しないと見えないっすね。

2010年11月23日火曜日

rotationも変わらないっすよね(1)

2か月半ぶりっすね。
講座が終わったので、こっちも書いていくっす。
まだもうちょっと講座関係の書きものが残ってるんっすけどね。
どうもぺんぎんっす( ◎v◎ )


PRIM_ROT_LOCALなんてフラグが追加されてたので、
ちょっと解説っぽいのを書いておくっす。
自分は元々rotationバグなんて無いと思ってるっすから、
そのことについてっす。

vectorもrotationも似たようなもんなので、vectorからっす。
珍しく図を描いてみたっす。
だいたい見れば分かるっすよね。
OがSIMの南西角、高度0mの(0, 0, 0)
Pがルートプリムの位置
Qが子プリムの位置っす。

SLPPの引数に入れるのはPQっす。
これの表し方にグローバル基準とかローカル基準とかあるっす。
どっちでも同じPQなのが注意点っすね。
ベクトルなら上に例のアレを付けるべきなんっすけど、
いろいろと面倒なので大文字で許してくださいっす。

まずは「グローバル」からっす。
これは単純っす。
PQをOPとOQで表せば良いっす。
PQ = OQ - OP
これでOKっす。
「Oから見てQの位置に移動させる」
っていうのをこの式は表わしてるっす。

次は「ローカル」っす
「P(ルートプリム)から見てQの位置に移動させる」
ということをしたいわけっすね。
ということは、QをOPだけ平行移動した点をQ'とすると
PQをOQ' + なんとか のカタチにすれば良いっす。
PQ = OQ - OP ―①
QをOPだけ平行移動した点がQ'だから
OQ + OP = OQ'―②
∴OQ = OQ' - OP ―③
③を①に代入すると
PQ = OQ' - OP - OP

具体的な数字を入れてみるっすかね。
(算数の話なので、floatなのに.0無いね!とかはナシっす)
O = (0, 0, 0), P = (1, 2, 3), Q = (4, 5, 6)
としてみるっす。
ルートプリムが今、Pの位置にあって、
子プリムをQの位置に移動させたいと思ってるわけっす。
「グローバル」でやってみるっす。
PQ = OQ - OP
   = (4, 5, 6) - (1, 2, 3)
   = (3, 3, 3)
「ローカル」でもやるっす。
OQ'は②式からOQ' = OQ + OP っす。
さっき書いた「Pから見てQの位置」っていうのはこの部分っす。
OQ' は計算すると (4, 5, 6) + (1, 2, 3) で (5, 7, 9) っすね。
PQ = OQ' - OP - OP
   = (5, 7, 9) - (1, 2, 3) - (1, 2, 3)
   = (3, 3, 3)
当然一致するわけっす。


ほら、何となくrotationと同じ雰囲気っすよね?
Free Avatar