このアプレットは、主に以下の3つの処理で成り立っています。
1. 回転の処理
2. 奥行きの処理
3. 隠れている面の処理
1) 回転の処理
x軸の回りにα度回転するとし、最初の位置を(x0, y0, z0)とすると回転後の位置(x1, y1, z1)は
x1 = x0
y1 = y0 * cosα - z0 * sinα
z1 = y0 * sinα + z0 * cosα
で計算できます。
y軸の回りにβ度回転するとし、最初の位置を(x0, y0, z0)とすると回転後の位置(x1, y1, z1)は
x1 = x0 * cosβ + z0 * sinβ
y1 = y0
z1 = -x0 * sinβ + z0 * cosβ
で計算できます。
同様にz軸の回りにγ度回転するとし、最初の位置を(x0, y0, z0)とすると回転後の位置(x1, y1, z1)は
x1 = x0 * cosγ - y0 * sinγ
y1 = x0 * sinγ + y0 * cosγ
z1 = z0
で計算できます。
2) 奥行きの処理
私たちが住むこの3次元の世界は、同じ大きさのものでも、近くのものは大きく、遠くのものは小さく見えるようになっています。
ここに針金でできている箱があるとします。
この箱を真正面から見ると、このようになります。
しかし実際には私たちの目にはこのようには見えず、下図のように見えます。
わかりやすくするため、真正面からでなく、少し角度を変えてみるとこのように見えます。
後ろの平面と前の平面は実際には同じ長さの辺からできている平面ですが、私たちの目には後ろの平面の方が小さく見えます。
これをモニタ上で再現しなければなりません。そのために使われる方法はいくつかありますが、このアプレットでは、透視投影という方法を使っています。元の位置を(x0, y0, z0)として、実際画面に表示される位置を(x1, y1)とすると、y1は
y1 = (a / (b - z0)) * y0
で計算できます。(aは投影平面から視点までの距離、bはy軸から視点までの距離。詳細は下図参照)
同様にx1も
x1 = (a / (b - z0)) * x0
で計算できます。
3) 隠れている面の処理
これで回転と表示はできましたが、後一つ、重要な処理が残っています。後ろに隠れている面を表示しないようにすることです。このアプレットではベクトルを使った方法でその処理をしています。
立方体は面の集まりでできています。面であることの最低条件は点が3つあることです。この3つの点を使って各面の法線ベクトルを求め、その値がプラスの場合はその面を表示し、0かそれ以下の場合は表示しないというようにすると、隠れている面を表示しないようにすることができます。
ここに3つの点、(x1 y1, z1), (x2, y2, z2), (x3, y3, z3)があるとします。この3つの点でできている面の法線ベクトルの値は、
x1(y2 - y3) + x2(y3 - y1) + x3(y1 -y2)
で計算できます。
リファレンス:
Javaによる図形処理入門/山元芳人著/工学図書