计算机图形学 考试实验代码分析2 两点透视法


两点透视法

代码一

数据(复制粘贴到记事本即可)

0 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 1 1 0 1 0 1 1 0 1 0 1
0.0 0.0 0.0	0.0 0.0 20.0 40.0 0.0 20.0
40.0 5.0 20.0 0.0 5.0 20.0 0.0 0.0 20.0
0.0 5.0 20.0 0.0 5.0 12.0
0.0 12.0 12.0 0.0 12.0 0.0 20.0 12.0 0.0
20.0 20.0 0.0 40.0 20.0 0.0 40.0 20.0 12.0
20.0 20.0 12.0 20.0 20.0 0.0 20.0 20.0 12.0
20.0 12.0 12.0 20.0 12.0 0.0
20.0 12.0 12.0 0.0 12.0 12.0 0.0 5.0 12.0
40.0 5.0 12.0 40.0 20.0 12.0 40.0 5.0 12.0
40.0 5.0 20.0 0.0 12.0 0.0 0.0 0.0 0.0
20 -0.1 -0.45 0 -1.4 0.0

code

void CMyView::OnDraw(CDC* pDC)
{
	CMyDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
	int i,j,l,ip[28];
	float g[28][4],T[4][4],B[28][4];
	//g储存变换后的坐标,T是变换矩阵,B是变换前的坐标
	float x0,y0,th,r,tx,ty,tz,p;
	FILE *fp;
	CPen mypen;
	mypen.CreatePen(PS_SOLID,1,RGB(255,255,255));
	//定义画笔
	fp = fopen("d:\\liti1.txt","r");
	if (fp!=NULL){
		for(i=0;i<28;i++)
		{
			fscanf(fp,"%d",&ip[i]);
		}
		//读取ip
		for(i=0;i<28;i++)
			for(j=0;j<3;j++)
			{
				fscanf(fp,"%f",&B[i][j]);
			}
			//读取点的x,y,z坐标
		fscanf(fp,"%f%f%f",&th,&p,&r);
		fscanf(fp,"%f%f%f",&tx,&ty,&tz);
		//读取变换矩阵中的变量
	}
	for(i=0;i<28;i++)
		B[i][3]=20;
		//给B中的第四列全部赋值为20
	x0=250;
	y0=50;
	th=th/57.2958;
	//C++中角度要使用弧度的方式进行使用
	for(i=0;i<4;i++)
		for(j=0;j<4;j++)
		T[i][j]=0;
	T[0][0]=cos(th);
	T[2][0]=sin(th);
	T[3][0]=tx*cos(th)+tz*sin(th);
	T[1][1]=1.0;
	T[3][1]=ty;
	T[0][3]=p*cos(th)-r*sin(th);
	T[2][3]=p*sin(th)+r*cos(th);
	T[3][3]=p*(tx*cos(th)+tz*sin(th))+r*(tz*cos(th)-tx*sin(th))+1;
	//设置变换矩阵
	for(i=0;i<28;i++)
		for(j=0;j<4;j++)
		{
			g[i][j]=0;
			for(l=0;l<4;l++)
			g[i][j]=g[i][j]+B[i][l]*T[l][j];

		}
		//坐标变换
	for(i=0;i<28;i++)
	{
		g[i][0]=g[i][0]/g[i][3]*60+x0;
		g[i][1]=-g[i][1]/g[i][3]*60+y0;
		g[i][3]=g[i][3]/g[i][3];
	}
	//记住就好
	for(i=0;i<28;i++)
	{
		if(ip[i]==0)
			pDC->MoveTo(g[i][0],g[i][1]);
		else
			pDC->LineTo(g[i][0],g[i][1]);
	}
	//绘图
}

结果

代码二

数据

 0.0   0.0    0.0   0
 0.0   0.0   20.0   1
40.0   0.0   20.0   1
40.0   5.0   20.0   1
 0.0   5.0   20.0   1
 0.0   0.0   20.0   1
 0.0   5.0   20.0   0 
 0.0   5.0   12.0   1
 0.0  12.0   12.0   1
 0.0  12.0    0.0   1
20.0  12.0    0.0   1
20.0  20.0    0.0   1
40.0  20.0    0.0   1
40.0  20.0   12.0   1
20.0  20.0   12.0   1
20.0  20.0    0.0   1
20.0  20.0   12.0   0
20.0  12.0   12.0   1
20.0  12.0    0.0   1
20.0  12.0   12.0   0
 0.0  12.0   12.0   1
 0.0   5.0   12.0   0
40.0   5.0   12.0   1
40.0  20.0   12.0   1
40.0   5.0   12.0   0
40.0   5.0   20.0   1
 0.0  12.0    0.0   0
 0.0   0.0    0.0   1

code

void CMy2View::OnDraw(CDC* pDC)
{
	CMy2Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
	FILE *fp=NULL;
	float a=20/57.2958,p=-0.1,r=-0.45,l=0,n=0,m=-1.4;
	//定义变换矩阵的变量
	float x[28],y[28],z[28],h[28],x1[28],y1[28],z1[28],h1[28],x2[28],y2[28],z2[28],t[4][4]={cos(a),0,0,p*cos(a)-r*sin(a),0,1,0,0,sin(a),0,0,p*sin(a)+r*cos(a),l*cos(a)+n*sin(a),m,0,p*(l*cos(a)+n*sin(a))+r*(n*cos(a)-l*sin(a)+1)};
	//定义变换矩阵
	int ip[28],i=0;
	int x0=250,y0=50;
	//处值可以随意设置
	fp=fopen("d:\\ces1.txt","r");
	for(i=0;i<28;i++)
	{
		fscanf(fp,"%f%f%f%d",&x[i],&y[i],&z[i],&ip[i]);
		h[i]=20;
		x1[i]=0;
		y1[i]=0;
		z1[i]=0;
	}
	//给x1[i],y1[i],z1[i],h[i]赋值很重要!!!
	CPen mypen;
	mypen.CreatePen(PS_SOLID,1,RGB(255,255,255));
	for(i=0;i<28;i++)
	{	
		x1[i]=(x[i]*t[0][0]+y[i]*t[1][0]+z[i]*t[2][0]+h[i]*t[3][0])/1.5;
		y1[i]=(y[i]*t[0][1]+y[i]*t[1][1]+z[i]*t[2][1]+h[i]*t[3][1])/1.5;
		z1[i]=z[i]*t[0][2]+y[i]*t[1][2]+z[i]*t[2][2]+h[i]*t[3][2];
		h1[i]=h[i]+(x[i]*t[0][3]+y[i]*t[1][3]+z[i]*t[2][3]+h[i]*t[3][3])/1.5;
	}
	//坐标变换与斜二测的做法类似,比较好记。
	//除以1.5是为了使图形不至于太大
	for(i=0;i<28;i++)
	{
		x2[i]=x1[i]/h1[i]*60+x0;
		y2[i]=-y1[i]/h1[i]*60+y0;
	}
	for(i=0;i<28;i++)
	{
		if(ip[i]==0)
		{
			pDC->MoveTo(x2[i],y2[i]);
		}
		else
		{
			pDC->LineTo(x2[i],y2[i]);
		}
	}
}

结果