ニートが頑張るブログ

ニートが現実逃避するために創作活動など色々とカオスに頑張ってみる
ニートが頑張るブログ TOP  >  ニートメソッド >  ルールXYZ その2

ルールXYZ その2

無学&独学でニートが考えた
ParaFla×AS2.03Dのフラッシュを作る方法っぽい話です.


寝てる間になんか
改善方法を思いついた気がして
ヨッシャーっと頑張ってみたけど
実際大して軽くはならなかったというお話.





とりあえず今まではこんな感じに考えてやってました.



改めて説明するとこんな感じ.


各変換すべき座標の
実際の座標は,rx,ry,rzって名前の変数にしています.

Z軸は動かさない方針にしたので
X軸回転に使うサインとコサイン
Xsin=Math.sin((Xrot/ 180)* Math.PI);
Xcos=Math.cos((Xrot/ 180)* Math.PI);
Y軸回転に使うサインとコサイン
Ysin=Math.sin((Yrot/ 180)* Math.PI);
Ycos=Math.cos((Yrot/ 180)* Math.PI);

だけです.


実際に座標を変換するのは,こんな感じ.
順番はドッチでもいいんですがY→Xの順にしてます.

座標入力例
rx =100;
ry =100;
rz =100;
Y軸回転
yx = rx*_root.Ycos - rz*_root.Ysin;
yy = ry;
yz = rx*_root.Ysin + rz*_root.Ycos;
X軸回転
xx = yx;
xy = yy*_root.Xcos + yz*_root.Xsin;
xz = -yy*_root.Xsin + yz*_root.Xcos;




名前メチャクチャだけど,これで
xxが変換後のx座標
xyが変換後のy座標
xzが変換後のz座標です.

xzがカメラへの近さなので,
これを前後関係とか遠近感に使います.

zz = _root.p/(_root.p+xz);

これが遠近感の比率.これをxxとxyにかけて実際に移動します.
_x = xx*zz;
_y = -xy*zz;



あとこれに,カメラの中心の座標(_root.rx,_root.ry,_root.rz)を引くようにしたり
イコールでくっついてるだけの式を出来るだけ短くして
↓こんな感じになったので,各座標を変換させてました.

//最終的にこんな感じの式を各スプライトに持たせる (旧)
rx2=rx-_root.rx;
yy=ry-_root.ry;
rz2=rz-_root.rz;
yz = rx2*_root.Ysin + rz2*_root.Ycos;
xx = rx2*_root.Ycos - rz2*_root.Ysin;
xy = yy*_root.Xcos + yz*_root.Xsin;
xz = -yy*_root.Xsin + yz*_root.Xcos;
zz = _root.p/(_root.p+xz); //遠近感
_x = xx*zz;
_y = -xy*zz;




これが今までやってたことです.

で,今日寝てたらピコーンと
もっと賢そうな改善法を思いついた気がしたのです.

それは,
「X座標だけが1の点,
Y座標だけが1の点,
Z座標だけが1の点が.
それぞれ変換後に,どれだけのxyz座標になるかを
あらかじめ計算しておいて,それに応じて各座標を移動させるようにしたら
イチイチ全部の座標を2回ずつ軸回転とかしたりしなくてすむんじゃないか」

って発想でした.




実際にやってみるとこんな感じ.
rx=1;//単位
ry=0;
rz=0;
temp = rx*_root.Ysin + rz*_root.Ycos;
xx = rx*_root.Ycos -rz*_root.Ysin;    //xが1増えるたびにxがいかに増えるか
xy = ry*_root.Xcos + temp*_root.Xsin; //xが1増えるたびにyがいかに増えるか
xz =-ry*_root.Xsin + temp*_root.Xcos; //xが1増えるたびにzがいかに増えるか
rx=0;//単位
ry=1;
rz=0;
temp = rx*_root.Ysin + rz*_root.Ycos;
yx = rx*_root.Ycos -rz*_root.Ysin;    //yが1増えるたびにxがいかに増えるか
yy = ry*_root.Xcos + temp*_root.Xsin; //yが1増えるたびにyがいかに増えるか
yz =-ry*_root.Xsin + temp*_root.Xcos; //yが1増えるたびにzがいかに増えるか
rx=0;//単位
ry=0;
rz=1;
t = rx*_root.Ysin + rz*_root.Ycos;
zx = rx*_root.Ycos -rz*_root.Ysin;    //zが1増えるたびにxがいかに増えるか
zy = ry*_root.Xcos + temp*_root.Xsin; //zが1増えるたびにyがいかに増えるか
zz =-ry*_root.Xsin + temp*_root.Xcos; //zが1増えるたびにzがいかに増えるか



これを_rootでアングルが変わる毎にあらかじめ計算しておく.
今までのように,_rootのXsin,Xcos,Ysin,Ycos
使って軸回転移動させるのではなく,これからは
_rootのxx,xy,xz,yx,yy,yz,zx,zy,zzを使って直線移動する感じ.


すると,各座標の変換は
//最終的にこんな感じの式を各スプライトに持たせる (新)
xx = _root.xx*(rx-_root.rx) + _root.yx*(ry-_root.ry) + _root.zx*(rz-_root.rz);
xy = _root.xy*(rx-_root.rx) + _root.yy*(ry-_root.ry) + _root.zy*(rz-_root.rz);
xz = _root.xz*(rx-_root.rx) + _root.yz*(ry-_root.ry) + _root.zz*(rz-_root.rz);
zz = _root.p/(_root.p+xz); //遠近感
_x = -xx*zz/2;
_y = -xy*zz/2;

こんだけ短くなります.

やったー∩( ・ω・)∩ばんじゃーい

って思ったんですがイマイチ早くなった気がしない.
↑上のテスト用のフラッシュでも新旧の方式を並べてますが
殆ど処理の重さが変わってません.
なんでじゃー


で,まず当然として緑色の部分の,0だからかける必要の無かったり
分かり切っているところを整理していたら分かってきました.

緑色の部分はこんな感じになります.
xx = Ycos;       //xが1増えるたびにxがいかに増えるか
xy = Ysin*Xsin;   //xが1増えるたびにyがいかに増えるか
xz = Ysin*Xcos;   //xが1増えるたびにzがいかに増えるか
yx = 0;         //yが1増えるたびにxがいかに増えるか
yy = Xcos;      //yが1増えるたびにyがいかに増えるか
yz =-Xsin ;      //yが1増えるたびにzがいかに増えるか
zx =-Ysin;      //zが1増えるたびにxがいかに増えるか
zy = Ycos*Xsin;   //zが1増えるたびにyがいかに増えるか
zz = Ycos*Xcos;  //zが1増えるたびにzがいかに増えるか


んで,これを見ててなんとなく分かりました.
これを使って(新)を移動させるのは
結局,最初の2回回転の式を短くまとめたくらいのことと同じなのだと.
考えてみりゃ当たり前なんだけどなぜか軽くなる気がしたのでした.

あえて言うならば何度もやってたYsin*Xsin/Ysin*Xcos/Ycos*Xsin/Ycos*Xcos
_rootでまとめて一回でやってる分,くらいは軽くなるって感じでしょうか.


でもまぁソースは短くなったからいっかー.
あとはこれを関数にしたりとか.




関連記事
[ 2009/11/25 13:28 ] ニートメソッド | TB(0) | CM(0)
コメントの投稿












管理者にだけ表示を許可する
トラックバック
この記事のトラックバックURL

月別カレンダー
05 ≪│2017/06│≫ 07
- - - - 1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 -