素晴らしい質問です。
あなたが持っていたように次のコードを実行しましたが、それは白い立方体の等角図のように見えました.
1: size(300,300,P3D);
2: camera(30, 30, 30, 0, 0, 0, 1, 1, 0);
3: ortho(-100, 100, -100, 100, -500, 500);
4: PGraphics3D p3d = (PGraphics3D)g;
5: p3d.camera.set(1, 0, -0.433f, 0, 0, 1, 0.25f, 0, 0, 0, 0, 0, 0, 0, 0, 1);
6: box(20);
何が起こっているかは次のとおりです。
- 2 行目:カメラとモデルビューの両方の行列を設定します
- 3 行目:射影行列を設定します
- 4 行目:カメラマトリックスのみを設定しますが、これは実際には何もしませんでした。(読む)
変換は、モデル ビューと射影行列を使用してのみ実行されます。カメラマトリックスは、モデル ビューが通常初期化される ものを便利に分離したものにすぎません。
draw() 関数を使用した場合、モデルビュー マトリックスは、呼び出されるたびにカメラマトリックスに実際に初期化されます。draw() 関数を使用しなかったため、カメラ マトリックスはカメラ マトリックスの斜め変換で更新されませんでした。
斜め投影の作成方法
免責事項として、行列を使用して座標を変換する方法を完全に理解する必要があります。順序は非常に重要です。これはそれを学ぶための良いリソースです:
http://glprogramming.com/red/chapter03.html
私ができる最も簡単な説明は、モデルビューマトリックスがオブジェクト座標を相対的な目の座標に変換し、次に射影マトリックスがそれらの目の座標を取り、それらをスクリーン座標に変換するということです。したがって、スクリーン座標に変換する前に斜め投影を適用する必要があります。
いくつかの立方体を表示するキャビネット プロジェクションを作成するための実行可能な例を次に示します。
void setup()
{
strokeWeight(2);
smooth();
noLoop();
size(600,600,P3D);
oblique(radians(60),0.5);
}
void draw()
{
background(100);
// size of the box
float w = 100;
// draw box in the middle
translate(width/2,height/2);
fill(random(255),random(255),random(255),100);
box(w);
// draw box behind
translate(0,0,-w*4);
fill(random(255),random(255),random(255),100);
box(w);
// draw box in front
translate(0,0,w*8);
fill(random(255),random(255),random(255),100);
box(w);
}
void oblique(float angle, float zscale)
{
PGraphics3D p3d = (PGraphics3D)g;
// set orthographic projection
ortho(-width/2,width/2,-height/2,height/2,-5000,5000);
// get camera's z translation
// ... so we can transform from the original z=0
float z = p3d.camera.m23;
// apply z translation
p3d.projection.translate(0,0,z);
// apply oblique projection
p3d.projection.apply(
1,0,-zscale*cos(angle),0,
0,1,zscale*sin(angle),0,
0,0,1,0,
0,0,0,1);
// remove z translation
p3d.projection.translate(0,0,-z);
}
