Visual C++6.0画三维立体图形

在画三维立体图之前,主要是先要找到二维和三维的对应关系,这是转化的关键。
关键代码如下:

			S[i].x=P[i][1]+sqrt(2)/3.0*(-P[i][0]);
			S[i].y=P[i][2]+sqrt(2)/3.0*(-P[i][0]);

一、建立边表结构,在同一屏幕上完成三视图和正等轴测投影图

//消隐之前
//编译环境:Visual C++ 6.0,EasyX_20190219(beta)
#include<graphics.h>
#include<conio.h>
#include<math.h>
#define max 50
#include<iostream>
#include<math.h>
using namespace std;

#define pi 3.14159
using namespace std;
double ja=35.3;//54.7
double rad=(double)ja*pi/(double)180.0;
double Dpoint[][4]={
	{0,0,84,1},{110,0,84,1},{110,0,20,1},{140,0,20,1},
	{140,0,0,1},{140,80,0,1},{0,80,0,1},{0,80,54,1},
	{0,60,54,1},{0,60,84,1},{20,60,84,1},{20,20,84,1},
	{110,20,84,1},{110,20,20,1},{60,20,20,1},{60,80,20,1},
	{40,80,54,1},{40,60,54,1},{140,80,20,1},{0,0,0,1}
};

//下标从0开始
int ring[]={
	0,1,12,11,10,9,//0-5
	2,3,18,15,14,13,//6-11
	8,17,16,17,//12-15
	1,2,13,12,//16-19
	3,4,5,18,//20-23
	11,14,15,16,17,10,//24-29
	11,12,13,14,//30-33
	15,18,5,6,7,16,//34-39
	9,10,17,8,//40-43
	0,9,8,7,6,19,//44-49
	0,19,4,3,2,1,//50-55
	4,19,6,5//56-59
};
//构成面的顶点
int surface[12][2]={
	{0,5},{6,11},{12,15},{16,19},{20,23},{24,29},
	{30,33},{34,39},{40,43},{44,49},{50,55},{56,59}
};
//主视图
int XOZ_ring[]={
	1,2,14,10,
	0,7,16,10,
	3,15,17,7,6,4
};
int XOZ_surface[3][2]={
	{0,3},{4,7},{8,13}
};
//侧视图
int YOZ_ring[]={
	0,2,13,12,
	11,10,8,7,15,13,
	3,4,5,15
};
int YOZ_surface[3][2]={
	{0,3},{4,9},{10,13}
};
//俯视图
int XOY_ring[]={
	2,0,9,10,11,12,
	3,5,15,14,12,2,
	14,15,16,17,10,11,
	16,7,9,17
};
int XOY_surface[4][2]={
	{0,5},{6,11},{12,17},{18,21}
};

//正等轴投影
int XYZ_ring[]={
	3,4,5,18,
	5,6,7,16,15,18,
	2,3,18,15,14,13,
	1,2,13,12,
	11,12,13,14,
	10,11,14,15,16,17,
	7,8,17,16,
	8,9,10,17,
	0,1,12,11,10,9
};
int XYZ_surface[9][2]={
	{0,3},{4,9},{10,15},{16,19},{20,23},{24,29},{30,33},{34,37},{38,43}
};

//三维坐标转换为右手坐标系的二维坐标
void transfer(double P[max][4], int n, POINT S[])
{
	int i,j;
	for(i=0;i<n;i++)
	{
		for(j=0;j<3;j++)
		{
			S[i].x=P[i][1]+sqrt(2)/3.0*(-P[i][0]);
			S[i].y=P[i][2]+sqrt(2)/3.0*(-P[i][0]);
		}		
	}
}
//主视图:XOZ面的投影变换,将Z的值给二维坐标的y
void XOZ_Projection(double P[max][4], int n, POINT S[])
{
	double T[max][4];//新生成的投影面上的点
	int i,j,k;
	int TV[4][4]={ {1,0,0,0},{0,0,0,0},{0,0,1,0},{0,0,0,1} };
	for(i=0;i<n;i++)
	{		
		for(j=0;j<4;j++)
		{   T[i][j]=0;
			for(k=0;k<4;k++)
			{T[i][j]+=P[i][k]*TV[k][j];}
		} 
	}
	for(i=0;i<n;i++)
	{
		S[i].x=T[i][0];
		S[i].y=T[i][2];
	}
}

//侧视图:YOZ面的投影变换,将y的值给二维坐标的x, z的值给二维坐标的y
void YOZ_Projection(double P[max][4], int n, POINT S[])
{
	double T[max][4];//新生成的投影面上的点
	int i,j,k;
	int TW[4][4]={ {0,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1} };
	for(i=0;i<n;i++)
	{		
		for(j=0;j<4;j++)
		{   T[i][j]=0;
			for(k=0;k<4;k++)
			{T[i][j]+=P[i][k]*TW[k][j];}
		}
	}
	for(i=0;i<n;i++)
	{
		S[i].x=T[i][1];
		S[i].y=T[i][2];
	}
}

//俯视图:XOY面的投影变换,将y的值给二维坐标的y, x的值给二维坐标的x
void XOY_Projection(double P[max][4], int n, POINT S[])
{
	double T[max][4];//新生成的投影面上的点
	int i,j,k;
	int TH[4][4]={ {1,0,0,0},{0,1,0,0},{0,0,0,0},{0,0,0,1} };
	for(i=0;i<n;i++)
	{		
		for(j=0;j<4;j++)
		{   T[i][j]=0;
			for(k=0;k<4;k++)
			{T[i][j]+=P[i][k]*TH[k][j];}
		}
	}
	for(i=0;i<n;i++)
	{
		S[i].x=T[i][0];
		S[i].y=T[i][1];
	}
}

//正等轴投影图:绕Z轴正向旋转α角 ,再绕X轴反向旋转β角,将三维形体向XOZ平面作正投影得到正轴测投影的投影变换矩阵 
//三维形体向XOZ平面作正投影,将Z的值给二维坐标的y
void XYZ_Projection(double P[max][4], int n, POINT S[])
{
	double T[max][4];//新生成的投影面上的点
	int i,j,k;
	double TT[4][4]={
		{cos(rad),0,-sin(rad)*sin(rad),0},
		{-sin(rad),0,-cos(rad)*sin(rad),0},
		{0,0,cos(rad),0},
		{0,0,0,1}
	};
	for(i=0;i<n;i++)
	{	
		for(j=0;j<4;j++)
		{   T[i][j]=0;
			for(k=0;k<4;k++)
			{T[i][j]+=P[i][k]*TT[k][j];}
		}
	}
	for(i=0;i<n;i++)
	{
		S[i].x=T[i][0];
		S[i].y=T[i][2];
	}
}


int main()
{
	initgraph(800,550);
	setorigin(220,350);
	setaspectratio(1,-1);
	
	line(0,0,180,0);
	line(0,0,0,120);
	line(0,0,-95,-95);
	int i,j,index,k;
	POINT points[20];
	POINT points1[10];
	setcolor(RED);
	transfer(Dpoint,20,points);
//画三维立体图
for(i=0;i<12;i++){
    k=0;
	for(j=surface[i][0];j<=surface[i][1];j++)
	{
		index=ring[j];
		points1[k].x=points[index].x;
		points1[k].y=points[index].y;
		k++;
	}
	polygon(points1,k);
}
setcolor(YELLOW);
//画主视图
XOZ_Projection(Dpoint,20,points);	
for(i=0;i<3;i++){//3个面
    k=0;
	for(j=XOZ_surface[i][0];j<=XOZ_surface[i][1];j++)
	{
		index=XOZ_ring[j];
		points1[k].x=-points[index].x;
		points1[k].y=points[index].y+230;
		k++;
	}
	polygon(points1,k);
}

//侧视图
YOZ_Projection(Dpoint,20,points);	
for(i=0;i<3;i++){//3个面
    k=0;
	for(j=YOZ_surface[i][0];j<=YOZ_surface[i][1];j++)
	{
		index=YOZ_ring[j];
		points1[k].x=points[index].x+20;
		points1[k].y=points[index].y+230;
		k++;
	}
	polygon(points1,k);
}

//俯视图
XOY_Projection(Dpoint,20,points);	
for(i=0;i<4;i++){//4个面
    k=0;
	for(j=XOY_surface[i][0];j<=XOY_surface[i][1];j++)
	{
		index=XOY_ring[j];
		points1[k].x=-points[index].x;
		points1[k].y=-points[index].y+210;
		k++;
	}
	polygon(points1,k);
}
//正等轴投影图
XYZ_Projection(Dpoint,20,points);	
for(i=0;i<12;i++){
    k=0;
	for(j=surface[i][0];j<=surface[i][1];j++)
	{
		index=ring[j];
		points1[k].x=-points[index].x+250;
		points1[k].y=-(-points[index].y+100)+200;
		k++;
	}
	polygon(points1,k);
}
	_getch();
	closegraph();
	return 0;
}

效果演示:
在这里插入图片描述
二、给定点的三维坐标值,建立面表、环表、顶点表三表结构,画出三维物体的消隐图

//消隐之后 
//编译环境:Visual C++ 6.0,EasyX_20190219(beta)
#include<graphics.h>
#include<conio.h>
#include<math.h>
#define max 50
#include<iostream>
#include<math.h>
using namespace std;
#define pi 3.14159
using namespace std;
double ja=35.3;//54.7
double rad=(double)ja*pi/(double)180.0;
double Dpoint[][4]={
	{0,0,84,1},{110,0,84,1},{110,0,20,1},{140,0,20,1},
	{140,0,0,1},{140,80,0,1},{0,80,0,1},{0,80,54,1},
	{0,60,54,1},{0,60,84,1},{20,60,84,1},{20,20,84,1},
	{110,20,84,1},{110,20,20,1},{60,20,20,1},{60,80,20,1},
	{40,80,54,1},{40,60,54,1},{140,80,20,1},{0,0,0,1}
};

//下标从0开始
int ring[]={
	0,1,12,11,10,9,//0-5
	2,3,18,15,14,13,//6-11
	8,17,16,17,//12-15
	1,2,13,12,//16-19
	3,4,5,18,//20-23
	11,14,15,16,17,10,//24-29
	11,12,13,14,//30-33
	15,18,5,6,7,16,//34-39
	9,10,17,8,//40-43
	0,9,8,7,6,19,//44-49
	0,19,4,3,2,1,//50-55
	4,19,6,5//56-59
};
//构成面的顶点
int surface[12][2]={
	{0,5},{6,11},{12,15},{16,19},{20,23},{24,29},
	{30,33},{34,39},{40,43},{44,49},{50,55},{56,59}
};

//消影
int ring1[]={
	3,4,5,18,
	5,6,7,16,15,18,
	2,3,18,15,14,13,
	1,2,13,12,
	11,12,13,14,
	10,11,14,15,16,17,
	7,8,17,16,
	8,9,10,17,
	0,1,12,11,10,9
};
int surface1[9][2]={
	{0,3},{4,9},{10,15},{16,19},{20,23},{24,29},{30,33},{34,37},{38,43}
};

//三维坐标转换为右手坐标系的二维坐标
void transfer(double P[max][4], int n, POINT S[]){
	int i,j;
	for(i=0;i<n;i++){
		for(j=0;j<3;j++){
			S[i].x=P[i][1]+sqrt(2)/3.0*(-P[i][0]);
			S[i].y=P[i][2]+sqrt(2)/3.0*(-P[i][0]);
		}		
	}
}

//正等轴投影图
void XYZ_Projection(double P[max][4], int n, POINT S[]){
	double T[max][4];//新生成的投影面上的点
	int i,j,k;
	double TT[4][4]={
		{cos(rad),0,-sin(rad)*sin(rad),0},
		{-sin(rad),0,-cos(rad)*sin(rad),0},
		{0,0,cos(rad),0},
		{0,0,0,1}
	};
	for(i=0;i<n;i++){	
		for(j=0;j<4;j++){   
			T[i][j]=0;
			for(k=0;k<4;k++)
			{T[i][j]+=P[i][k]*TT[k][j];}
		}
	}
	for(i=0;i<n;i++){
		S[i].x=T[i][0];
		S[i].y=T[i][2];
	}
}

int main()
{
	initgraph(800,550);
	setorigin(220,350);
	setaspectratio(1,-1);
	line(0,0,180,0);
	line(0,0,0,120);
	line(0,0,-95,-95);

	int i,j,index,k;
	POINT points[20];
	POINT points1[10];
	setcolor(RED);
	transfer(Dpoint,20,points);
//未消影之前的三维立体图
for(i=0;i<12;i++){
    k=0;
	for(j=surface[i][0];j<=surface[i][1];j++){
		index=ring[j];
		points1[k].x=points[index].x;
		points1[k].y=points[index].y;
		k++;
	}
	polygon(points1,k);
}
//画三维立体消影图
setcolor(YELLOW);
for(i=0;i<9;i++){
    k=0;
	for(j=surface1[i][0];j<=surface1[i][1];j++){
		index=ring1[j];
		points1[k].x=points[index].x+250;
		points1[k].y=points[index].y;
		k++;
	}
	polygon(points1,k);
}
setcolor(BLUE);
//正等轴投影图
XYZ_Projection(Dpoint,20,points);	
for(i=0;i<9;i++){
    k=0;
	for(j=surface1[i][0];j<=surface1[i][1];j++){
		index=ring1[j];
		points1[k].x=-points[index].x+200;
		points1[k].y=-(-points[index].y+100)+300;
		k++;
	}
	polygon(points1,k);
}
	_getch();
	closegraph();
	return 0;
}

效果演示:
在这里插入图片描述
红色为原图,黄色为消影之后的三维立体图,蓝色为消影后的正等轴侧投影图。

  • 12
    点赞
  • 91
    收藏
    觉得还不错? 一键收藏
  • 14
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值