计算机图形学课程设计 透视投影图 三视图
- 格式:doc
- 大小:4.06 MB
- 文档页数:16
计算机图形学程序课程设计题目:分别在四个视区内显示空间四面体的三视图、透视投影图。
学院:信息科学与技术学院专业:计算机科学与技术姓名:oc学号:oc电话:oc邮箱:oc目录一、设计概述(1)设计题目。
2(2)设计要求。
2(3)设计原理。
2(4)算法设计。
5(5)程序运行结果。
9二、核心算法流程图。
10三、程序源代码。
12四、程序运行结果分析。
24五、设计总结分析。
25六、参考文献。
26 一.设计概述•设计题目计算机图形学基础(第二版)陆枫何云峰编著电子工业出版社P228-7、16:利用OpenGL中的多视区,分别在四个视区内显示图7-41所示空间四面体的主视图、俯视图、侧视图、透视投影图。
•设计要求设计内容:1、掌握主视图、俯视图、侧视图与透视投影变换矩阵;2、掌握透视投影图、三视图生成原理;功能要求:分别在四个视区内显示P228-图7-41所示空间四面体的主视图、俯视图、侧视图、透视投影图。
•设计原理正投影正投影根据投影面与坐标轴的夹角可分为三视图与正轴测图。
当投影面与某一坐标轴垂直时,得到的投影为三视图,这时投影方向与这个坐标轴的方向一致,否则,得到的投影为正轴测图。
1、主视图(V面投影)将三维物体向XOZ平面作垂直投影,得到主视图。
由投影变换前后三维物体上点到主视图上的点的关系,其变换矩阵为:Tv=Txoz= [1 0 0 0][0 0 0 0][0 0 1 0][0 0 0 1]Tv为主视图的投影变换矩阵。
简称主视图投影变换矩阵。
2、侧视图(W面投影)将三维物体向YOZ平面作垂直投影,得到侧视图。
为使侧视图与主视图在一个平面内,就要使W面绕Z轴正向旋转90°。
同时为了保证侧视图与主视图有一段距离,还要使W面再沿X方向平移一段距离x0,这样即得到侧视图。
变换矩阵为:Tv=Tyoz= [ 0 0 0 0 ][-1 0 0 0 ][ 0 0 1 0 ][-x0 0 0 1]Tv为主视图的投影变换矩阵。
简称主视图投影变换矩阵。
3、俯视图(H面投影)将三维物体向XOY平面作垂直投影,得到俯视图。
为使俯视图与主视图在一个平面内,就要使H面绕X轴负向旋转90°。
同时为了保证侧视图与主视图有一段距离,还要使H面再沿Z方向平移一段距离-z0,这样即得到侧视图。
变换矩阵为:Tv=Txoy= [ 1 0 0 0][0 0 -1 0][0 0 0 0 ][ 0 0–z0 1]Tv为主视图的投影变换矩阵。
简称主视图投影变换矩阵。
三视图常作为主要的工程施工图纸,因为在三视图上可以测量距离与角度。
但一种三视图只有物体在一面的投影,所以单独从某一个方面的三视图很难想象出物体的三维形状,只有将主视图、侧视图与俯视图放在一起,才有可能综合处物体的空间形状。
总的来说三视图中主视图、俯视图与侧视图都就是通过变换矩阵得来的。
透视投影-一点透视一点透视只有一个主灭点。
灭点可以瞧做就是无限远处的一个点在投影面上的点。
一点透视的一般步骤:•将三维物体平移到适当位置l,m,n、•令视点在z轴,进行透视变换。
•最后,向xoy面做正投影变换,将结果变换到xoy面上。
如此一点透视变换矩阵为:Tv=Txoy= [ 1 0 0 0 ][ 0 1 0 0 ][ 0 0 0 1/d ][ l m 0 1+n/d]•算法设计核心算法1、构造类表示三维坐标系下的点struct DefPoint{double x, y, z, tag;}2、为顶点建立顶点表:Point[MaxNum],TPoint[MaxNum],XOZPoint[MaxNum],XOYPoint[Ma xNum],YOZPoint[MaxNum],YOYPoint[MaxNum]3、定义各个视图的变换矩阵以及变换函数变换矩阵:double Matrix[4][4] = { { 1, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 1, 0 }, { 500, 300, 300, 1 } };//初始化为单位矩阵double XOZ[4][4] = { { 1, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 1 } };//主视图变换矩阵double XOY[4][4] = { { 1, 0, 0, 0 }, { 0, 0, -1, 0 }, { 0, 0, 0, 0 }, { 0, 0, -50, 1 } };//俯视图变换矩阵double YOZ[4][4] = { { 0, 0, 0, 0 }, { -1, 0, 0, 0 }, { 0, 0, 1, 0 }, { -150, 0, 0, 1 } };//侧视图变换矩阵double DD= -400, NN = -200, MM = -360, LL = -500;//DD视点,平移到适当距离NN、MM、LLdouble YOY[4][4] = { { 1, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 0, 1 / DD }, { LL, MM, 0, 1 + NN / DD } };//一点透视矩阵变换函数:void TransForm(DefPoint NewPoint[], DefPoint OldPoint[], double Tran[4][4])变换函数主要功能就是将三维图形顶点与变换矩阵相乘得到变换后的矩阵。
4、四个视图的显示算法。
void Display(){glClear(GL_COLOR_BUFFER_BIT);OnCoordinate();glColor3f(0、0f, 0、0f, 0、0f);glBegin(GL_LINES);glVertex2d(winWidth / 2, 0);glVertex2d(winWidth / 2, winHeight);glVertex2d(0, winHeight / 2);glVertex2d(winWidth, winHeight / 2);glEnd();glColor3f(1、0f, 0、0f, 0、0f);OnDraw(XOZPoint);glColor3f(0、0f, 1、0f, 0、0f);OnDraw(XOYPoint);glColor3f(0、0f, 0、0f, 1、0f);OnDraw(YOZPoint);glColor3f(1、0f, 0、0f, 0、0f);OnDraw_O(YOYPoint);glutS();}5、三视图的划线算法//绘制指定的图形void OnDraw(DefPoint TempPoint[]){glBegin(GL_LINES);for (int i = 0; i<FaceNum; i++){int size = Face[i]、size();for (int j = 0; j<size; j++){glVertex2d(TempPoint[Face[i][j]]、x,TempPoint[Face[i][j]]、z);glVertex2d(TempPoint[Face[i][(j + 1) % size]]、x,TempPoint[Face[i][(j + 1) % size]]、z);}}glEnd();}6.一点透视的划线算法//绘制指定的图形void OnDraw_O(DefPoint TempPoint[]){glColor3f(1、0f, 0、0f, 0、0f);glBegin(GL_LINES);glVertex2d(TempPoint[0]、x, TempPoint[0]、y);glVertex2d(TempPoint[1]、x, TempPoint[1]、y);glVertex2d(TempPoint[0]、x, TempPoint[0]、y);glVertex2d(TempPoint[2]、x, TempPoint[2]、y);glVertex2d(TempPoint[0]、x, TempPoint[0]、y);glVertex2d(TempPoint[3]、x, TempPoint[3]、y);glVertex2d(TempPoint[1]、x, TempPoint[1]、y);glVertex2d(TempPoint[2]、x, TempPoint[2]、y);glVertex2d(TempPoint[1]、x, TempPoint[1]、y);glVertex2d(TempPoint[3]、x, TempPoint[3]、y);glVertex2d(TempPoint[2]、x, TempPoint[2]、y);glVertex2d(TempPoint[3]、x, TempPoint[3]、y);glEnd();glColor3f(0、0f, 1、0f, 0、0f);glBegin(GL_LINES);glVertex2d(TempPoint[0]、x,TempPoint[0]、y); glVertex2d(0, 0); glVertex2d(TempPoint[1]、x,TempPoint[1]、y); glVertex2d(0, 0); glVertex2d(TempPoint[2]、x,TempPoint[2]、y); glVertex2d(0, 0); glVertex2d(TempPoint[3]、x,TempPoint[3]、y); glVertex2d(0, 0);glEnd();}(5)程序运行结果(1)矩阵变换函数流程图(2)三视图绘制算法流程图三.程序源代码#include"stdafx、h"#include<glut、h>#include<vector>#include<iostream>using namespace std;const int MaxNum = 200;vector<int>Face[10];//最大数,面数vectorint winWidth = 1000, winHeight = 600;//窗口宽高int PointNum = 4, FaceNum = 4; //用户图形的顶点,面数double Matrix[4][4] = { { 1, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 1, 0 }, { 500, 300, 300, 1 } };//初始化为单位矩阵double XOZ[4][4] = { { 1, 0, 0, 0 }, { 0, 0, 0, 0 },{ 0, 0, 1, 0 }, { 0, 0, 0, 1 } };//主视图变换矩阵double XOY[4][4] = { { 1, 0, 0, 0 }, { 0, 0, -1, 0 },{ 0, 0, 0, 0 }, { 0, 0, -50, 1 } };//俯视图变换矩阵double YOZ[4][4] = { { 0, 0, 0, 0 }, { -1, 0, 0, 0 },{ 0, 0, 1, 0 }, { -150, 0, 0, 1 } };//侧视图变换矩阵double DD= -400, NN = -200, MM = -360, LL = -500;//DD视点,平移到适当距离NN、MM、LLdouble YOY[4][4] = { { 1, 0, 0, 0 }, { 0, 1, 0, 0 },{ 0, 0, 0, 1 / DD }, { LL, MM, 0, 1 + NN / DD } };//一点透视矩阵//定义图形的顶点struct DefPoint{double x, y, z, tag;}Point[MaxNum], TPoint[MaxNum], XOZPoint[MaxNum],XOYPoint[MaxNum],YOZPoint[MaxNum],YOYPoint[MaxNum];//初始化自定义三维图形void ThPmidInit(){PointNum = 4;Point[0]、x = 400, Point[0]、y = 0, Point[0]、z = 0, Point[0]、tag = 1;Point[1]、x = 400, Point[1]、y = 200, Point[1]、z = 0, Point[1]、tag = 1;Point[2]、x = 0, Point[2]、y = 200, Point[2]、z = 0, Point[2]、tag = 1;Point[3]、x = 200, Point[3]、y = 200, Point[3]、z = 200, Point[3]、tag = 1;FaceNum = 4;Face[0]、push_back(0); Face[0]、push_back(1); Face[0]、push_back(2);Face[1]、push_back(0); Face[1]、push_back(1); Face[1]、push_back(3);Face[2]、push_back(0); Face[2]、push_back(2); Face[2]、push_back(3);Face[3]、push_back(1); Face[3]、push_back(2); Face[3]、push_back(3);}//获得变换后的用户图形的顶点void TransForm(DefPoint NewPoint[], DefPoint OldPoint[], double Tran[4][4]){for (int i = 0; i<PointNum; i++){double tx = OldPoint[i]、x, ty = OldPoint[i]、y,tz = OldPoint[i]、z, ttag = OldPoint[i]、tag;NewPoint[i]、x = tx*Tran[0][0] + ty*Tran[1][0] +tz*Tran[2][0] + ttag*Tran[3][0];NewPoint[i]、y = tx*Tran[0][1] + ty*Tran[1][1] +tz*Tran[2][1] + ttag*Tran[3][1];NewPoint[i]、z = tx*Tran[0][2] + ty*Tran[1][2] +tz*Tran[2][2] + ttag*Tran[3][2];NewPoint[i]、tag = tx*Tran[0][3] + ty*Tran[1][3] +tz*Tran[2][3] + ttag*Tran[3][3];if (NewPoint[i]、tag != 0 && NewPoint[i]、tag != 1){NewPoint[i]、x /= NewPoint[i]、tag,NewPoint[i]、y /= NewPoint[i]、tag,NewPoint[i]、z /= NewPoint[i]、tag,NewPoint[i]、tag = 1;}}}//重新指定窗口的宽高void ReShape(int w, int h){winWidth = w; winHeight = h;glViewport(0, 0, w, h);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D(0、0, winWidth, 0、0, winHeight);}//绘制指定的图形void OnDraw(DefPoint TempPoint[]){glBegin(GL_LINES);for (int i = 0; i<FaceNum; i++){int size = Face[i]、size();for (int j = 0; j<size; j++){glVertex2d(TempPoint[Face[i][j]]、x,TempPoint[Face[i][j]]、z);glVertex2d(TempPoint[Face[i][(j + 1) % size]]、x,TempPoint[Face[i][(j + 1) % size]]、z);}}glEnd();}//绘制指定的图形void OnDraw_O(DefPoint TempPoint[]){glColor3f(1、0f, 0、0f, 0、0f);glBegin(GL_LINES);glVertex2d(TempPoint[0]、x, TempPoint[0]、y);glVertex2d(TempPoint[1]、x, TempPoint[1]、y);glVertex2d(TempPoint[0]、x, TempPoint[0]、y);glVertex2d(TempPoint[2]、x, TempPoint[2]、y);glVertex2d(TempPoint[0]、x, TempPoint[0]、y);glVertex2d(TempPoint[3]、x, TempPoint[3]、y);glVertex2d(TempPoint[1]、x, TempPoint[1]、y);glVertex2d(TempPoint[2]、x, TempPoint[2]、y);glVertex2d(TempPoint[1]、x, TempPoint[1]、y);glVertex2d(TempPoint[3]、x, TempPoint[3]、y);glVertex2d(TempPoint[2]、x, TempPoint[2]、y);glVertex2d(TempPoint[3]、x, TempPoint[3]、y);glEnd();glColor3f(0、0f, 1、0f, 0、0f);glBegin(GL_LINES);glVertex2d(TempPoint[0]、x, TempPoint[0]、y); glVertex2d(0, 0);glVertex2d(TempPoint[1]、x, TempPoint[1]、y); glVertex2d(0, 0);glVertex2d(TempPoint[2]、x, TempPoint[2]、y); glVertex2d(0, 0);glVertex2d(TempPoint[3]、x, TempPoint[3]、y); glVertex2d(0, 0);glEnd();}//绘制坐标系void OnCoordinate(){glColor3f(0、0f, 0、0f, 0、0f);glBegin(GL_LINES);glVertex2d(winWidth / 2, 0);glVertex2d(winWidth / 2, winHeight);glVertex2d(0, winHeight / 2);glVertex2d(winWidth, winHeight / 2);//标记Z轴glVertex2d(winWidth / 2 + 5, winHeight - 15);glVertex2d(winWidth / 2 + 5, winHeight - 25); glVertex2d(winWidth / 2 + 15, winHeight - 15); glVertex2d(winWidth / 2 + 5, winHeight - 25); glVertex2d(winWidth / 2 + 15, winHeight - 25); glVertex2d(winWidth / 2 - 5, winHeight - 5); glVertex2d(winWidth / 2, winHeight);glVertex2d(winWidth / 2 + 5, winHeight - 5); glVertex2d(winWidth / 2, winHeight);//标记Y轴glVertex2d(winWidth / 2 + 25, 0 + 15); glVertex2d(winWidth / 2 + 20, 0 + 10);glVertex2d(winWidth / 2 + 15, 0 + 15); glVertex2d(winWidth / 2 + 20, 0 + 10);glVertex2d(winWidth / 2 + 20, 0 + 10); glVertex2d(winWidth / 2 + 20, 0 + 5);glVertex2d(winWidth / 2 - 5, 0 + 5);glVertex2d(winWidth / 2, 0);glVertex2d(winWidth / 2 + 5, 0 + 5);glVertex2d(winWidth / 2, 0);//标记Y轴glVertex2d(0 + 25, winHeight / 2 + 15); glVertex2d(0 + 20, winHeight / 2 + 10); glVertex2d(0 + 15, winHeight / 2 + 15); glVertex2d(0 + 20, winHeight / 2 + 10); glVertex2d(0 + 20, winHeight / 2 + 10); glVertex2d(0 + 20, winHeight / 2 + 5);glVertex2d(0 + 5, winHeight / 2 + 5);glVertex2d(0, winHeight / 2);glVertex2d(0 + 5, winHeight / 2 - 5); glVertex2d(0, winHeight / 2);//标记X轴glVertex2d(winWidth - 25, winHeight / 2 + 15); glVertex2d(winWidth - 15, winHeight / 2 + 5); glVertex2d(winWidth - 25, winHeight / 2 + 5);glVertex2d(winWidth - 5, winHeight / 2 - 5);glVertex2d(winWidth, winHeight / 2);glVertex2d(winWidth - 5, winHeight / 2 + 5);glVertex2d(winWidth, winHeight / 2);glEnd();}//绘制图形void Display(){glClear(GL_COLOR_BUFFER_BIT);OnCoordinate();glColor3f(0、0f, 0、0f, 0、0f);glBegin(GL_LINES);glVertex2d(winWidth / 2, 0);glVertex2d(winWidth / 2, winHeight);glVertex2d(0, winHeight / 2);glVertex2d(winWidth, winHeight / 2);glEnd();glColor3f(1、0f, 0、0f, 0、0f);OnDraw(XOZPoint);glColor3f(0、0f, 1、0f, 0、0f);OnDraw(XOYPoint);glColor3f(0、0f, 0、0f, 1、0f);OnDraw(YOZPoint);glColor3f(1、0f, 0、0f, 0、0f);OnDraw_O(YOYPoint);glutS();}//三维图形变换主函数void GetThPmidView(){TransForm(XOZPoint, Point, XOZ);TransForm(XOYPoint, Point, XOY);TransForm(YOZPoint, Point, YOZ);TransForm(YOYPoint, Point, YOY);TransForm(XOZPoint, XOZPoint, Matrix);TransForm(XOYPoint, XOYPoint, Matrix);TransForm(YOZPoint, YOZPoint, Matrix);TransForm(YOYPoint, YOYPoint, Matrix);}//初始化void Initial(){for (int i = 0; i<10; i++)Face[i]、clear();glClearColor(1、0f,1、0f, 1、0f, 1、0f);ThPmidInit();GetThPmidView();}int main(int argc, char* argv[]){glutInit(&argc, argv);glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);glutInitWindowSize(1000, 600);glutInitWindowPosition(150, 100);glutCreateWindow("三维图形透视投影图&三视图演示程序");glutDisplayFunc(Display);glutReshapeFunc(ReShape);Initial();glutMainLoop();return 0;}四.程序运行结果分析在程序中预先输入要实现的三维物体的顶点与面的信息,然后经过矩阵变换函数,得到变换后的函数。