Project Board コメントComment
ログイン | ヘルプ | トップ

プロジェクト
親コメント:
[Ver0.05]立方体の表示が一つのオ... 2007-03-07 21:02 by ハイハー

三次元の多角形、立体表示

内容
Commented by: ごま太郎 at 2007-03-08 00:49:18

面や線の中心を座標で求め、そこから視点までのベクトルの大きさ(距離)を計算します。
そして、距離をzOrderに代入します。距離の大きい面ほどzOrderの値が大きくなるため、結果的に、手前にあるものが表示されます。
zo=(重心座標x-カメラ座標x)*(重心座標x-カメラ座標.x)+(重心座標y-カメラ座標.y)*(重心座標y-カメラ座標.y)+(重心座標z-カメラ座標z)*(重心座標z-カメラ座標z);
//zoがzOrderに代入される。
重心計算のために必要になる関数などは、私の3D迷路中のpointクラスで定義しています。
//大きさを求める
return sqrt( x*x + y*y + z*z );
}

function per(a,b) {
//aベクトルとbベクトルの法線ベクトルを求める
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;
}

function 内積(a) {
//aとの内積を求める
return x*a.x+y*a.y+z*a.z;
}

直接、これらの関数を利用しているのは、3D迷路のTestObjクラス内のwhile()ループです。

元ネタは旧アップ板にありますので、なんでしたら検索してみてください。

上下移動を考慮しない場合、面と視点との内角を計算することであきらかに視野にない面を描写せずに処理を軽量化することもできます。詳しい計算式などは長くなるのでネットで探してください。メジャーな方法なので、すぐに見つかります。
一般的な方法と少し変更して3D迷路で使っています。

hoge-氏の3Dサンプルでは、カメラ座標を中心に一定の距離を置いてカメラが円を描くようにして回転移動します。そのため、カメラの回転動作を行うと視点が壁にめり込んだりします。てか、視点が壁の中にめり込んだらめり込んだ部分の壁を描写しないようにするのが一般的です。
ゲームでも、キャラクターを見るのに邪魔になる壁などは非表示になったりするのと同じことです。
で、カメラの回転幅を調節するにはconvクラスを書き換えます。参考までに、私は
function cameraTo2D(cp) {
// カメラ視点から見た点 cp を 画面上の座標 x,y に変換
// 画面内におさまっていれば 1 、画面をとびだしたら 0を返す
p=cp;

z=(p.z+zadj-700)/zadj;
if (z<0.1) return 0;
x=p.x/z;
y=-(p.y+yadj)/z; //yの値、上方向を+にした
x+=$screenWidth/2;
y+=$screenHeight/2;
scale=1/z;
return 1;

}

function convCamera(pt) {
// pt をカメラ視点から見た座標に変換し、pに格納する
return p.set(pt).sub(v).rollZX(angleZX).rollYZ(angleYZ).rollXY(angleXY);//Y軸*X軸*Z軸
}

constructor Conv(x,y) {
super(x,y);
p=new Point(0,0,1000);// 作業用
v=new Point(0,0,0); // カメラの場所
zadj=1000; // 補正値 値を変えると、魚眼レンズかなんかのようになって面白いw
angleZX=0 ; // ZX平面(地面)の回転
angleYZ=0 ; // YZ平面の回転
angleXY=0 ; // XY平面の回転
}
としています。
まず、正規の3Dサンプルと異なっている部分を見て、それに関連する値を書き換えてみてください。そうやって、自分の求めてる計算値を探しましょう。私も、ここらへんの理屈はよく分からないので手探りで書き換えました。

まあ・・・とりあえず、上のような方法を試すなら私の3D迷路のプログラムを見てみてください。一通りやっているので、参考にはなると思います。

ttp://tonyu.jp/project/pages/viewProject.cgi?mainkey=92&にあります。

返信

おわっ! ありがとうございます!! 3D... 2007-03-08 15:47 by ハイハー