立方体の絵を描く

立方体の絵を描く

絵を描くキャンバス用のフレームの準備もでき、試しに線を書きました。次は線だけではつまらないので、立方体を描いてみます。
立方体の頂点データを扱うCubeVert()という以下のクラスファイルを作りました。
8つの立方体の頂点データを配列に格納します。頂点データのxyzはVertex()というクラスファイルにセットし、そのVertex()を8つの配列に格納しています。


public class CubeVert {
	
	public static Vertex vt[];	
	static int vt_num=8;

	  // 初期化されないコンストラクタ
	  private CubeVert(){
	  }
	
	public static int getVt_num() {
		return vt_num;
	}

	
	  public static  void setModelData() {
	        vt  = new Vertex[vt_num];

	        vt[0]=new Vertex( 0, 0, 1);
	        vt[1]=new Vertex( 0, 1, 1);
	        vt[2]=new Vertex( 1, 1, 1);
	        vt[3]=new Vertex( 1, 0, 1);
	        vt[4]=new Vertex( 0, 0, 0);
	        vt[5]=new Vertex( 0, 1, 0);
	        vt[6]=new Vertex( 1, 1, 0);
	        vt[7]=new Vertex( 1, 0, 0); 
	  }
	
}
//==================
// Vertex クラス
//==================
  class Vertex
  {
      public double x,y,z;
  
      public Vertex(double x,double y,double z)
      {
          this.x = x;
          this.y = y;
          this.z = z;
      }
  }

次は、 DrawGraphi()の修正です。
initial()の中の、CubeVert.setModelData();で頂点データを配列に格納しています。
Draw()で絵を描きます。キャンバスの大きさは600と固定しています。
for文で各頂点に●文字を描いています。立方体の中心がキャンバスの中心となるように0.5補正しています。Scaleは拡大率です。


import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;

public class DrawGraphi {
	DrawGraphi(){
		initial();
	}

	void initial(){
		CubeVert.setModelData();
	}

	public void Draw(Graphics g){
		Graphics2D g2 = (Graphics2D)g;

		g2.setBackground(backColor);
		g2.clearRect(0,0,600,600);
		g2.setColor(dc);
	    
		vtt=CubeVert.getVt_num();
		int Canvas_w = 600;
		int Canvas_h = 600;
		int Center_x= Canvas_w/2;
		int Center_y= Canvas_h/2;
		int x0,y0;
		int g_Scale=200;

		g2.drawLine(200,300,400,300);
		g2.drawLine(300,200,300,400);
    	
		for(int i=0;i<vtt;i++){
			x0=(int)((CubeVert.vt[i].x-0.5) * g_Scale + Center_x) ;
			y0=(int)((CubeVert.vt[i].y-0.5) * g_Scale + Center_y) ;
			g2.drawString(targs,x0,y0);
		}
	}

		int vtt=0;
		private Color dc =new Color(255,0,255);	//pink
		private Color backColor = new Color(0,0,80);//dark blue
		private String targs="●";
}



hello

実行すると、右図のようになります。
平面なので立方体に見えません。そこで少し斜めから見たような感じにするために回転してみます。
回転角度は固定で、15°30°くらいにしました。回転はx軸とy軸を回転しています。
コンピュータのための数学といった本などで紹介されている回転行列を参考にしました。
x1y1が回転した後で、x0y0がモニタ画面に映す場合の座標の差分です。モニタ画面のy軸は、上が0ですので、キャンバスの中心から減じて計算しています。
xyz軸の線も描いてみました。


import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;

public class DrawGraphi {
	DrawGraphi(){
		initial();
	}

	void initial(){
		CubeVert.setModelData();
	}

	public void Draw(Graphics g){
		Graphics2D g2 = (Graphics2D)g;

		g2.setBackground(backColor);
		g2.clearRect(0,0,600,600);
		g2.setColor(dc);

		vtt=CubeVert.getVt_num();
		int Canvas_w = 600;
		int Canvas_h = 600;
		int Center_x= Canvas_w/2;
		int Center_y= Canvas_h/2;
		int x0,y0;
		int g_Scale=200;
		double cosx=0.96,sinx=0.3,cosy=0.88,siny=-0.48;
		double x1,y1,z1;
		int line[][]=new int[8][2];
    
		for(int i=0;i<vtt;i++){
			// xy回転行列  111から回転するときに原点をずらす
			x1=(CubeVert.vt[i].x-0.5)*cosy+(CubeVert.vt[i].z-0.5)*siny;
			z1=-(CubeVert.vt[i].x-0.5)*siny+(CubeVert.vt[i].z-0.5)*cosy;
			y1=(CubeVert.vt[i].y-0.5)*cosx-z1*sinx;
	    	
			x0=(int)(x1 * g_Scale) ;
			y0=(int)(y1 * g_Scale) ;
			g2.drawString(targs,Center_x+x0,Center_y-y0);
			line[i][0]=x0;line[i][1]=y0;
		}
		
		//xyz line
		g2.setColor(new Color(100,255,255));	//シアン
		x1=cosy;
		z1=-siny;
		y1=-z1*sinx;
		x0=(int)(x1 * g_Scale) ;
		y0=(int)(y1 * g_Scale) ;
		g2.drawLine(Center_x,Center_y,Center_x+x0,Center_y-y0);
		//y line
		g2.setColor(new Color(0,255,0));	//green
		x1=0;
		z1=0;
		y1=cosx;
		x0=(int)(x1 * g_Scale) ;
		y0=(int)(y1 * g_Scale) ;
		g2.drawLine(Center_x,Center_y,Center_x+x0,Center_y-y0); 	
		//z line
		g2.setColor(new Color(0,0,255));	//blue
		x1=siny;
		z1=cosy;
		y1=-z1*sinx;
		x0=(int)(x1 * g_Scale) ;
		y0=(int)(y1 * g_Scale) ;
		g2.drawLine(Center_x,Center_y,Center_x+x0,Center_y-y0);
	  }
		int vtt=0;
		private Color dc =new Color(255,0,255);	//pink
		private Color backColor = new Color(0,0,80);//dark blue
		private String targs="●";
}



hello

実行すると右図のようになります。
何となく回転しているように見えますが、点だけではわかりにくいです。
そこで点と点の間に線を描く処理を追加したのが以下のとおりです。
先ほどの画面用頂点配列を使って線を描いています。きっともっとスマートな処理があると思うのですが、分からなかったので、素人処理となっています。


import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;

public class DrawGraphi {
	DrawGraphi(){
		initial();
	}

	void initial(){
		CubeVert.setModelData();
	}

	public void Draw(Graphics g){
		Graphics2D g2 = (Graphics2D)g;

		g2.setBackground(backColor);
		g2.clearRect(0,0,600,600);
		g2.setColor(dc);

		vtt=CubeVert.getVt_num();
		int Canvas_w = 600;
		int Canvas_h = 600;
		int Center_x= Canvas_w/2;
		int Center_y= Canvas_h/2;
		int x0,y0;
		int g_Scale=200;
		double cosx=0.96,sinx=0.3,cosy=0.88,siny=-0.48;
		double x1,y1,z1;
		int line[][]=new int[8][2];
    
		for(int i=0;i<vtt;i++){
			x1=(CubeVert.vt[i].x-0.5)*cosy+(CubeVert.vt[i].z-0.5)*siny;
			z1=-(CubeVert.vt[i].x-0.5)*siny+(CubeVert.vt[i].z-0.5)*cosy;
			y1=(CubeVert.vt[i].y-0.5)*cosx-z1*sinx;
	    	
			x0=(int)(x1 * g_Scale) ;
			y0=(int)(y1 * g_Scale) ;
			g2.drawString(targs,Center_x+x0,Center_y-y0);
			line[i][0]=x0;line[i][1]=y0;
		}

		g2.setColor(new Color(255,255,255));	//white
		for(int j=0;j<vtt;j++){
			if(j==3){
				g2.drawLine(Center_x+line[j][0],Center_y-line[j][1],Center_x+line[j-3][0],Center_y-line[j-3][1]);				
				
			}else if(j==7){	//うまくor処理ができないので分離した
				g2.drawLine(Center_x+line[j][0],Center_y-line[j][1],Center_x+line[j-3][0],Center_y-line[j-3][1]);				
			}else{
				g2.drawLine(Center_x+line[j][0],Center_y-line[j][1],Center_x+line[j+1][0],Center_y-line[j+1][1]);				
			}
		}
		for(int i=0;i<vtt/2;i++){
			g2.drawLine(Center_x+line[i][0],Center_y-line[i][1],Center_x+line[i+4][0],Center_y-line[i+4][1]);				
		}			
		
		//xyz line
		g2.setColor(new Color(100,255,255));	//シアン
		x1=cosy;
		z1=-siny;
		y1=-z1*sinx;
		x0=(int)(x1 * g_Scale) ;
		y0=(int)(y1 * g_Scale) ;
		g2.drawLine(Center_x,Center_y,Center_x+x0,Center_y-y0);
		//y line
		g2.setColor(new Color(0,255,0));	//green
		x1=0;
		z1=0;
		y1=cosx;
		x0=(int)(x1 * g_Scale) ;
		y0=(int)(y1 * g_Scale) ;
		g2.drawLine(Center_x,Center_y,Center_x+x0,Center_y-y0); 	
		//z line
		g2.setColor(new Color(0,0,255));	//blue
		x1=siny;
		z1=cosy;
		y1=-z1*sinx;
		x0=(int)(x1 * g_Scale) ;
		y0=(int)(y1 * g_Scale) ;
		g2.drawLine(Center_x,Center_y,Center_x+x0,Center_y-y0); 		
	  }
		int vtt=0;
		private Color dc =new Color(255,0,255);	//pink
		private Color backColor = new Color(0,0,80);//dark blue
		private String targs="●";
}



hello

 実行すると右図のようになります。立方体とxyz軸線がなんとなく立体的に見えています。ただ●文字と線の交点が一致していません。これは●文字の座標が●の中心ではないからです。