ワイヤーフレームによる
立体表現

ってことで、前回、線を引けるようになったので、次はワイヤーフレームやります。
前回は二次元の座標の頂点を線で結びましたが、 今回は頂点の座標が三次元になります。
でも、最終的にはディスプレイに表示する場合は二次元にしなくてはならないので、どうするかというと 座標変換を行います。
変換について詳しく知りたい人は、このページを読むのがオススメ
ここもね

座標系の遷移は、

ローカル座標系→ワールド座標系→視野座標系→スクリーン座標系

というようになります。
一応、座標系についてはこちらで簡単に説明しています。
ちなみに今回はカメラ固定なので視野座標への変換は省きました。
頂点の座標変換ができれば、その二次元座標の頂点をブレゼンハムアルゴリズムで結ぶだけです。

↑マウスでドラッグすると、立方体が回転します。
public class Matrix {
    float mat[][] = new float[4][4];

    //-----------------------------
    //  単位行列で初期化
    //-----------------------------
    public void Init(){
        mat[0][0]=1; mat[0][1]=0; mat[0][2]=0; mat[0][3]=0;
        mat[1][0]=0; mat[1][1]=1; mat[1][2]=0; mat[1][3]=0;
        mat[2][0]=0; mat[2][1]=0; mat[2][2]=1; mat[2][3]=0;
        mat[3][0]=0; mat[3][1]=0; mat[3][2]=0; mat[3][3]=1;
    }

    //----------------------------
    //  行列を合成
    //-----------------------------
    public void Mul(Matrix m){
        float mat_00 = mat[0][0]*m.mat[0][0] + mat[0][1]*m.mat[1][0] + mat[0][2]*m.mat[2][0] + mat[0][3]*m.mat[3][0];
	float mat_01 = mat[0][0]*m.mat[0][1] + mat[0][1]*m.mat[1][1] + mat[0][2]*m.mat[2][1] + mat[0][3]*m.mat[3][1];
	float mat_02 = mat[0][0]*m.mat[0][2] + mat[0][1]*m.mat[1][2] + mat[0][2]*m.mat[2][2] + mat[0][3]*m.mat[3][2];
	float mat_03 = mat[0][0]*m.mat[0][3] + mat[0][1]*m.mat[1][3] + mat[0][2]*m.mat[2][3] + mat[0][3]*m.mat[3][3];
	float mat_10 = mat[1][0]*m.mat[0][0] + mat[1][1]*m.mat[1][0] + mat[1][2]*m.mat[2][0] + mat[1][3]*m.mat[3][0];
	float mat_11 = mat[1][0]*m.mat[0][1] + mat[1][1]*m.mat[1][1] + mat[1][2]*m.mat[2][1] + mat[1][3]*m.mat[3][1];
	float mat_12 = mat[1][0]*m.mat[0][2] + mat[1][1]*m.mat[1][2] + mat[1][2]*m.mat[2][2] + mat[1][3]*m.mat[3][2];
	float mat_13 = mat[1][0]*m.mat[0][3] + mat[1][1]*m.mat[1][3] + mat[1][2]*m.mat[2][3] + mat[1][3]*m.mat[3][3];
	float mat_20 = mat[2][0]*m.mat[0][0] + mat[2][1]*m.mat[1][0] + mat[2][2]*m.mat[2][0] + mat[2][3]*m.mat[3][0];
	float mat_21 = mat[2][0]*m.mat[0][1] + mat[2][1]*m.mat[1][1] + mat[2][2]*m.mat[2][1] + mat[2][3]*m.mat[3][1];
	float mat_22 = mat[2][0]*m.mat[0][2] + mat[2][1]*m.mat[1][2] + mat[2][2]*m.mat[2][2] + mat[2][3]*m.mat[3][2];
	float mat_23 = mat[2][0]*m.mat[0][3] + mat[2][1]*m.mat[1][3] + mat[2][2]*m.mat[2][3] + mat[2][3]*m.mat[3][3];
	float mat_30 = mat[3][0]*m.mat[0][0] + mat[3][1]*m.mat[1][0] + mat[3][2]*m.mat[2][0] + mat[3][3]*m.mat[3][0];
	float mat_31 = mat[3][0]*m.mat[0][1] + mat[3][1]*m.mat[1][1] + mat[3][2]*m.mat[2][1] + mat[3][3]*m.mat[3][1];
	float mat_32 = mat[3][0]*m.mat[0][2] + mat[3][1]*m.mat[1][2] + mat[3][2]*m.mat[2][2] + mat[3][3]*m.mat[3][2];
	float mat_33 = mat[3][0]*m.mat[0][3] + mat[3][1]*m.mat[1][3] + mat[3][2]*m.mat[2][3] + mat[3][3]*m.mat[3][3];

	mat[0][0] = mat_00; mat[0][1] = mat_01;mat[0][2] = mat_02;mat[0][3] = mat_03;
	mat[1][0] = mat_10; mat[1][1] = mat_11;mat[1][2] = mat_12;mat[1][3] = mat_13;
	mat[2][0] = mat_20; mat[2][1] = mat_21;mat[2][2] = mat_22;mat[2][3] = mat_23;
	mat[3][0] = mat_30; mat[3][1] = mat_31;mat[3][2] = mat_32;mat[3][3] = mat_33;
    }
    //------------------------------
    //  スケーリング
    //------------------------------
    void Scale(float sx,float sy,float sz){
	Matrix m = new Matrix();
	m.mat[0][0] = sx;m.mat[0][1] =  0;m.mat[0][2] =  0;m.mat[0][3] = 0;
	m.mat[1][0] =  0;m.mat[1][1] = sy;m.mat[1][2] =  0;m.mat[1][3] = 0;
	m.mat[2][0] =  0;m.mat[2][1] =  0;m.mat[2][2] = sz;m.mat[2][3] = 0;
	m.mat[3][0] =  0;m.mat[3][1] =  0;m.mat[3][2] =  0;m.mat[3][3] = 1;

	this.Mul(m);
    }

    //-----------------------------
    //     回転
    //-----------------------------
    void Rotate(float rx,float ry,float rz){

        //X軸回転
	float sinx = (float)Math.sin(rx);
	float cosx = (float)Math.cos(rx);

	Matrix m = new Matrix();

	m.mat[0][0] = 1;m.mat[0][1] =    0;m.mat[0][2] =    0;m.mat[0][3] = 0;
	m.mat[1][0] = 0;m.mat[1][1] = cosx;m.mat[1][2] = sinx;m.mat[1][3] = 0;
	m.mat[2][0] = 0;m.mat[2][1] =-sinx;m.mat[2][2] = cosx;m.mat[2][3] = 0;
	m.mat[3][0] = 0;m.mat[3][1] =    0;m.mat[3][2] =    0;m.mat[3][3] = 1;

	this.Mul(m);

        //Y軸回転
        float siny = (float)Math.sin(ry);
	float cosy = (float)Math.cos(ry);

	m.mat[0][0] = cosy;m.mat[0][1] = 0;m.mat[0][2] =-siny;m.mat[0][3] = 0;
	m.mat[1][0] =    0;m.mat[1][1] = 1;m.mat[1][2] =    0;m.mat[1][3] = 0;
	m.mat[2][0] = siny;m.mat[2][1] = 0;m.mat[2][2] = cosy;m.mat[2][3] = 0;
	m.mat[3][0] =    0;m.mat[3][1] = 0;m.mat[3][2] =    0;m.mat[3][3] = 1;

        this.Mul(m);

        //Z軸回転
        float sinz = (float)Math.sin(rz);
	float cosz = (float)Math.cos(rz);

        m.mat[0][0] = cosz;m.mat[0][1] = sinz;m.mat[0][2] = 0;m.mat[0][3] = 0;
	m.mat[1][0] =-sinz;m.mat[1][1] = cosz;m.mat[1][2] = 0;m.mat[1][3] = 0;
	m.mat[2][0] =    0;m.mat[2][1] =    0;m.mat[2][2] = 1;m.mat[2][3] = 0;
	m.mat[3][0] =    0;m.mat[3][1] =    0;m.mat[3][2] = 0;m.mat[3][3] = 1;

	this.Mul(m);
     }

    //-----------------------------------
    //            平行移動
    //-----------------------------------
    void Translate(float dx,float dy,float dz){
        Matrix m = new Matrix();

	m.mat[0][0] =  1;m.mat[0][1] =  0;m.mat[0][2] =  0;m.mat[0][3] = 0;
	m.mat[1][0] =  0;m.mat[1][1] =  1;m.mat[1][2] =  0;m.mat[1][3] = 0;
	m.mat[2][0] =  0;m.mat[2][1] =  0;m.mat[2][2] =  1;m.mat[2][3] = 0;
	m.mat[3][0] = dx;m.mat[3][1] = dy;m.mat[3][2] = dz;m.mat[3][3] = 1;

        this.Mul(m);
    }

    //-----------------------
    //   アフィン変換
    //----------------------
    vectorC Transform(vectorC a){
	vectorC v = new vectorC(0.f,0.f,0.f);

	v.x = mat[0][0] * a.x + mat[1][0] * a.y + mat[2][0] * a.z + mat[3][0];
	v.y = mat[0][1] * a.x + mat[1][1] * a.y + mat[2][1] * a.z + mat[3][1];
	v.z = mat[0][2] * a.x + mat[1][2] * a.y + mat[2][2] * a.z + mat[3][2];

	return v;
    }
}