仮fig0
Basic 3D #0
* 目的地。
*
* 3Dってのは確かにめんどくさい処理がたくさんある。なかなかとっつきにくいとは思う。
* でも、動いたときの気持ちよさは格別だ。単純な図形が回転するだけでも、一人ニヤニヤと見続けてしまう。
* だからまずは、ごく基本のみに限定して作って、その気持ちよさを実感してもらえたらと思う。
* 処理の流れ自体はとっても簡単だってのはわかるはずだ。
* 完全な理解、ディティールの追求はその後でも十分だろう。
*
* まず先に目的地を示したい。
* この20面体のワイヤーフレームが今回の学習の到達点だ。
* 面の塗りがない。テクスチャーもない。陰面消去もない。zソートもない。
* 人に見せても、今どき驚く人はいないよね。
* でも、まーいいじゃん。作れるようになると気持ち良いよ。
*
*
/**
* Copyright umhr ( http://wonderfl.net/user/umhr )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/5rDE
*/
/*
* Basic 3D #0
* 目的地。
*
* 3Dってのは確かにめんどくさい処理がたくさんある。なかなかとっつきにくいとは思う。
* でも、動いたときの気持ちよさは格別だ。単純な図形が回転するだけでも、一人ニヤニヤと見続けてしまう。
* だからまずは、ごく基本のみに限定して作って、その気持ちよさを実感してもらえたらと思う。
* 処理の流れ自体はとっても簡単だってのはわかるはずだ。
* 完全な理解、ディティールの追求はその後でも十分だろう。
*
* まず先に目的地を示したい。
* この20面体のワイヤーフレームが今回の学習の到達点だ。
* 面の塗りがない。テクスチャーもない。陰面消去もない。zソートもない。
* 人に見せても、今どき驚く人はいないよね。
* でも、まーいいじゃん。作れるようになると気持ち良いよ。
*
*
*/
package {
import flash.display.Sprite;
import flash.events.Event;
[SWF(backgroundColor="0x000000")]
public class Main extends Sprite {
//20面体の頂点座標。
private var phi:Number = 100 * ((Math.sqrt(5) + 1) / 2);
private var model_a_array:Array = new Array(0, phi, 100);//頂点a
private var model_b_array:Array = new Array(0, -phi, 100);
private var model_c_array:Array = new Array(0, -phi, -100);
private var model_d_array:Array = new Array(0, phi, -100);
private var model_e_array:Array = new Array(100, 0, phi);
private var model_f_array:Array = new Array(100, 0, -phi);
private var model_g_array:Array = new Array( -100, 0, -phi);
private var model_h_array:Array = new Array( -100, 0, phi);
private var model_i_array:Array = new Array(phi, 100, 0);
private var model_j_array:Array = new Array( -phi, 100, 0);
private var model_k_array:Array = new Array( -phi, -100, 0);
private var model_l_array:Array = new Array(phi, -100, 0);
//回転処理をするために、処理回数をカウントする。
private var count:int;
//この関数がまず実行される。
public function Main() {
//ENTER_FRAME関数を実行し続ける。
addEventListener(Event.ENTER_FRAME,ENTER_FRAME);
}
private function ENTER_FRAME(e:Event):void {
//処理回数のカウント。
count ++;
//移動量を設定[x,y,z,x軸回転,y軸回転,z軸回転]
var idou_array:Array = new Array(0, 0, 0, count / 100, count / 50, 0);
//行列(Matrix)を使ってモデルを動かします。
var a_array:Array = Mztm3D.matrix(model_a_array, idou_array);//頂点aを移動させる。
var b_array:Array = Mztm3D.matrix(model_b_array, idou_array);
var c_array:Array = Mztm3D.matrix(model_c_array, idou_array);
var d_array:Array = Mztm3D.matrix(model_d_array, idou_array);
var e_array:Array = Mztm3D.matrix(model_e_array, idou_array);
var f_array:Array = Mztm3D.matrix(model_f_array, idou_array);
var g_array:Array = Mztm3D.matrix(model_g_array, idou_array);
var h_array:Array = Mztm3D.matrix(model_h_array, idou_array);
var i_array:Array = Mztm3D.matrix(model_i_array, idou_array);
var j_array:Array = Mztm3D.matrix(model_j_array, idou_array);
var k_array:Array = Mztm3D.matrix(model_k_array, idou_array);
var l_array:Array = Mztm3D.matrix(model_l_array, idou_array);
//遠近感をつける処理。
//透視投影、プロジェクション変換。
a_array = Mztm3D.project(a_array);//頂点aに遠近感をつける。
b_array = Mztm3D.project(b_array);
c_array = Mztm3D.project(c_array);
d_array = Mztm3D.project(d_array);
e_array = Mztm3D.project(e_array);
f_array = Mztm3D.project(f_array);
g_array = Mztm3D.project(g_array);
h_array = Mztm3D.project(h_array);
i_array = Mztm3D.project(i_array);
j_array = Mztm3D.project(j_array);
k_array = Mztm3D.project(k_array);
l_array = Mztm3D.project(l_array);
//線を描く処理。
//まず、まっさらにする。
this.graphics.clear();
//線を描く。
Mztm3D.drawLine(this, a_array, d_array);//頂点aとdを結ぶ線。
Mztm3D.drawLine(this, a_array, i_array);
Mztm3D.drawLine(this, a_array, e_array);
Mztm3D.drawLine(this, a_array, h_array);
Mztm3D.drawLine(this, a_array, j_array);
Mztm3D.drawLine(this, c_array, f_array);
Mztm3D.drawLine(this, c_array, l_array);
Mztm3D.drawLine(this, c_array, b_array);
Mztm3D.drawLine(this, c_array, k_array);
Mztm3D.drawLine(this, c_array, g_array);
Mztm3D.drawLine(this, d_array, i_array);
Mztm3D.drawLine(this, i_array, e_array);
Mztm3D.drawLine(this, e_array, h_array);
Mztm3D.drawLine(this, h_array, j_array);
Mztm3D.drawLine(this, j_array, d_array);
Mztm3D.drawLine(this, f_array, l_array);
Mztm3D.drawLine(this, l_array, b_array);
Mztm3D.drawLine(this, b_array, k_array);
Mztm3D.drawLine(this, k_array, g_array);
Mztm3D.drawLine(this, g_array, f_array);
Mztm3D.drawLine(this, d_array, f_array);
Mztm3D.drawLine(this, i_array, l_array);
Mztm3D.drawLine(this, e_array, b_array);
Mztm3D.drawLine(this, h_array, k_array);
Mztm3D.drawLine(this, j_array, g_array);
Mztm3D.drawLine(this, d_array, g_array);
Mztm3D.drawLine(this, i_array, f_array);
Mztm3D.drawLine(this, e_array, l_array);
Mztm3D.drawLine(this, h_array, b_array);
Mztm3D.drawLine(this, j_array, k_array);
}
}
}
//処理をわかりやすくするためにクラス化。
import flash.display.Sprite;
import flash.display.Graphics;
class Mztm3D {
//行列(Matrix)を使ってモデルを動かします。
//引数_pozは頂点のx,y,zの座標。
//引数_viewは移動量のx,y,z,x軸回転,y軸回転,z軸回転。
public static function matrix(_poz:Array, idou_array:Array):Array {
var result_array:Array = new Array();
var n_cx:Number = Math.cos(idou_array[3]);
var n_sx:Number = Math.sin(idou_array[3]);
var n_cy:Number = Math.cos(idou_array[4]);
var n_sy:Number = Math.sin(idou_array[4]);
var n_cz:Number = Math.cos(idou_array[5]);
var n_sz:Number = Math.sin(idou_array[5]);
var af_xx:Number = n_cz*n_cy+n_sx*n_sy*n_sz;
var af_xy:Number = n_sx*n_sy*n_cz-n_sz*n_cy;
var af_xz:Number = n_sy*n_cx;
var af_yx:Number = n_cx*n_sz;
var af_yy:Number = n_cx*n_cz;
var af_yz:Number = -n_sx;
var af_zx:Number = n_cy*n_sx*n_sz-n_sy*n_cz;
var af_zy:Number = n_sy*n_sz+n_cy*n_sx*n_cz;
var af_zz:Number = n_cx*n_cy;
var af_x:Number = _poz[0];
var af_y:Number = _poz[1];
var af_z:Number = _poz[2];
result_array[0] = af_x * af_xx + af_y * af_xy + af_z * af_xz + idou_array[0];
result_array[1] = af_x * af_yx + af_y * af_yy + af_z * af_yz + idou_array[1];
result_array[2] = af_x * af_zx + af_y * af_zy + af_z * af_zz + idou_array[2];
return result_array;
}
//透視投影、プロジェクション変換。遠近感をつける。引数は、頂点のx,y,zの座標。
public static function project(_array:Array):Array {
_array[2] = 500/(500+_array[2]);
_array[0] = _array[0] * _array[2];
_array[1] = _array[1] * _array[2];
return _array;
}
//線を描く。引数は描くべき場所、線の開始点、線の終点。
public static function drawLine(_stage:Sprite,start_array:Array,end_array:Array):Sprite {
var g:Graphics = _stage.graphics;
g.lineStyle (1, 0xFF0000, 1.0);
//画面の中央に移動するため、xとyに465 / 2を足している。
g.moveTo (start_array[0]+465 / 2, start_array[1]+465 / 2);
g.lineTo (end_array[0]+465 / 2, end_array[1]+465 / 2);
return _stage;
}
}