两点透视法
代码一
数据(复制粘贴到记事本即可)
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]);
}
}
}
结果