计算机图形学 第四章图形变换.doc_第1页
计算机图形学 第四章图形变换.doc_第2页
计算机图形学 第四章图形变换.doc_第3页
计算机图形学 第四章图形变换.doc_第4页
计算机图形学 第四章图形变换.doc_第5页
已阅读5页,还剩36页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第四章 图形变换图形变换是计算机图形学的基础内容之一。图形在计算机上的显示可以比喻为用假想的照相机对物体进行拍照,并将产生的照片贴在显示屏上的指定位置进行观察的过程。三维物体要在屏幕上显示首先要做的就是投影变换。此外,还要求能够对物体进行旋转、缩放、平移变换。绘图过程还要用窗口规定显示物体的哪个部分,用视区来规定将窗口中的内容显示在屏幕上的什么位置。图形显示的过程见下图。本体坐标系子物体1本体坐标系子物体1用户坐标系观察坐标系规范化设备坐标系设备坐标系图4.1 图形显示的坐标变换过程在本章中,我们将实现二维图形的几何变换、三维图形的投影变换,以及对图形进行裁剪的算法。 4.1变换的数学基础在计算机图形学的图形变换过程中要大量的用到向量、矩阵以及它们之间的运算。本小节对这些知识做简要介绍。一、 向量及向量运算一个物理量,如果我们只关心其数值的大小(例如物体的质量、体积、密度),则这样的量统称为标量,如果我们既关心其数值大小,还关心其方向(如速度),则这样的两统称为向量。标量一般用普通字体的英文字母显示,而向量一般用黑体英文字母显示。设向量,有关的向量运算有:(1) 两个向量的和、差运算(2) 两个向量的点乘运算(3) 两个向量的叉乘运算(4) 向量的长度二、 矩阵及矩阵运算由个数排成矩形表:或简记成或,称为一个行列的矩阵,简称矩阵,叫做第行第列元素。当时,叫做阶方针,此时元素称为主对角线元素。只有一行的矩阵称为行向量,只有一列的矩阵称为列向量。有关矩阵的运算有(1) 数乘矩阵用标量乘的每一个元素而得的矩阵称为与的乘积,记为:(2) 矩阵的加法运算设有两个矩阵,将它们对应元素相加而得到的矩阵称为与的和,记为+(3) 矩阵的乘法运算设有矩阵,则此二矩阵相乘的积为矩阵:可见,只有的列数等于的行数的时候,才有意义。矩阵运算有如下基本性质(1) 数乘矩阵适合分配律和结合律(2) 矩阵加法适合结合律(3) 矩阵乘法对加法适合分配律(4) 矩阵乘法不适合交换律,因为当两个矩阵,能够相乘时,与却未必能够相乘,即使,都是方阵,与也未必相等。在图形变换中还有用到如下的概念:(1) 零矩阵及其运算矩阵的所有元素均为零的矩阵称为零矩阵。一个行列的零矩阵记为,对于任意的矩阵都与下式成立:(2) 单位矩阵在一个方阵中,如果其主对角线元素全是1,而其余元素都是0,则称这样的矩阵为单位矩阵,记为。对任意矩阵,有下式成立:(3) 逆矩阵对于方阵,若存在矩阵,使得,则称是可逆的,称为的逆,记为(4) 转置矩阵将的行、列互换而得到的矩阵,称为的转置矩阵,记为。矩阵的转置有如下的性质:三、 齐次坐标齐次坐标表示法就是用维的向量表示一个维向量。维空间中的点具有个坐标分量,并且是唯一的,用齐次坐标表示为,是不唯一的。使用齐次坐标还可以表示无穷远点,规定当时为无穷远点。 4.2 二维图形的几何变换本节将讲解如何对二维图形进行几何变换,包括平移变换、比例变换、旋转变换、对称变换和错切变换。1、 平移变换平移变换是将平面上的一点沿平行于轴的方向平移,沿平行于轴的方向平移后变成点,则有,OTxTyXy图4.2 平移变换程序的功能如下。首先,在屏幕上显示一个默认的矩形,然后根据用户选择的不同操作对此矩形进行平移,平移操作是随着鼠标的移动而移动的。程序步骤:1) 首先,建立一个MFC单文档工程,起名为“Ch4_2DTrans_2DTrans”。单击Workspace中的ClassView标签,双击CCh4_2DTrans_2DTransView,在CCh4_2DTrans_2DTransView类的定义之前定义一个枚举类型,代码如下:2) 在CCh4_2DTransView类的定义中添加如下成员变量:3) 右键单击CCh4_2DTransView,选择Add Member Function,在弹出的对话框中,Function Type设为void,Function Declaration设为ClearScreen(),单击确定。4) 单击CCh4_2DTransView左侧的+号,双击ClearScreen函数,在ClearScreen函数中添加如下代码:5) 右键单击CCh4_2DTransView,选择Add Member Function,在弹出的对话框中,Function Type设为void,Function Declaration设为DrawRect(),单击确定。6) 单击CCh4_2DTransView左侧的+号,双击DrawRect函数,在DrawRect函数中添加如下代码:7) 双击构造函数CCh4_2DTransView(),在其中添加如下代码:8) 单击Workspace中的ResourceViewView标签中的Menu左边的“+”号,双击其子项:IDR_MAINFRAME。9) 建立名称为【二维图形变换】的菜单,并建立【平移】子菜单。ID号设为:IDT_TRANSLATE。如图10) 右键单击【平移】子菜单,选择ClassWizzard选项。在弹出的对话框中选择:Object IDs:IDT_TRANSLATE, Class name:CCh4_2DTransView,Messages:COMMAND,单击Add Function按钮,在弹出的为函数命名的对话框中单击OK,单击Edit Code按钮。11) 在函数OnTranslate()中添加代码:12) 按组合键Ctrl+W,调出ClassWizzard对话框,选择Object IDs:CCh4_2DTransView,Class name:CCh4_2DTransView,在Messages列表中双击WM_LBUTTONDOWN,WM_LBUTTONUP,WM_MOUSEMOVE, WM_RBUTTONDOWN, WM_RBUTTONUP, 单击Edit Code按钮。13) 分别在OnLButtonDown(UINT nFlags, CPoint point)、OnLButtonUp(UINT nFlags, CPoint point)、OnMouseMove(UINT nFlags, CPoint point)、OnRButtonDown(UINT nFlags, CPoint point)、OnRButtonUp(UINT nFlags, CPoint point)函数中添加如下代码(黑体部分是添加的代码):void CCh4_2DTrans_TranslateView:OnLButtonUp(UINT nFlags, CPoint point) / TODO: Add your message handler code here and/or call defaultm_bLBDown = FALSE;m_prevPoint = point;CView:OnLButtonUp(nFlags, point);void CCh4_2DTrans_TranslateView:OnRButtonDown(UINT nFlags, CPoint point) / TODO: Add your message handler code here and/or call defaultm_bRBDown = TRUE;m_prevPoint = point;CView:OnRButtonDown(nFlags, point);void CCh4_2DTrans_TranslateView:OnRButtonUp(UINT nFlags, CPoint point) / TODO: Add your message handler code here and/or call defaultm_bRBDown = FALSE;m_prevPoint = point;CView:OnRButtonUp(nFlags, point);void CCh4_2DTrans_TranslateView:OnMouseMove(UINT nFlags, CPoint point) / TODO: Add your message handler code here and/or call defaultInt delta;switch(m_type_transform) case TRF_TRANSLATE:if(m_bLBDown)ClearScreen();delta = point.x - m_prevPoint.x;m_prevPoint = point;m_LT += CPoint(delta * (int)m_xStep,0);m_LB += CPoint(delta * (int)m_xStep,0);m_RT += CPoint(delta * (int)m_xStep,0);m_RB += CPoint(delta * (int)m_xStep,0);DrawRect();if(m_bRBDown)ClearScreen();delta = point.y - m_prevPoint.y;m_prevPoint = point;m_LT += CPoint(0,delta * (int)m_yStep);m_LB += CPoint(0,delta * (int)m_yStep);m_RT += CPoint(0,delta * (int)m_yStep);m_RB += CPoint(0,delta * (int)m_yStep);DrawRect();break;case TRF_NONE:break;CView:OnMouseMove(nFlags, point);至此,代码部分结束。编译,运行,点击菜单项中的【平移】命令,出现如图所示矩形。图4.3 平移代码运行结果图中的矩形可以用鼠标进行平移,具体来说,鼠标的左键控制矩形左右平移,用鼠标右键控制矩形上下平移。2、比例变换比例变换是相对于原点,将平面上一点沿轴方向乘以常数,沿轴方向乘以常数后,变成点,则有,可见,如果,则为恒等变换,图形不变,如果,则图形被放大了,如果则图形被缩小了。如果,则图形在轴和轴方向被缩放的倍数不一样。为了实现上述的功能,我们在前面代码的基础上继续添加代码。要求,可以令矩形根据用户输入的参数而放大和缩小。程序步骤:1) 在枚举类型Type_Transform添加TRF_SCALE2) 单击Workspace中的ResourceView标签中的Menu左边的“+”号,双击其子项:IDR_MAINFRAME。3) 在【二维图形变换】菜单的子菜单【平移】之下建立一个新的菜单【比例】,ID号设为:IDT_SCALE,如图所示4) 右键单击【比例】,选择Classwizzard,在弹出的对话框中选择Object IDs为IDT_SCALE,Class name选为CCh4_2DTransView,Messages选为Command,单击Add Functions,单击确定。5) 打开Workspace中的ResourceView,右键单击Dialog,选择Insert Dialog,则出现了一个新的对话框资源,其ID号是IDD_DIALOG1,右键单击其ID,选择Properties,将其ID号改为IDD_SCALE.6) 将两个静态文本框和两个编辑框加入到对话框中,编辑框的ID分别设为IDC_SCALE_SX,IDC_SCALE_SY,如图所示7) 右键单击对话框,选择Classward,点击确定。在弹出的New对话框中的Name栏中键入Dlg_Scale。8) 单击Member Variables标签,双击其中的IDC_SCALE_SX,在弹出的对话框中键入变量名:m_Sx,Variable type栏选择int,单击确定,同样,双击IDC_SCALE_SY,输入变量名:m_Sy。9) 点击Workspace中的ClassView标签,双击Dlg_scale,将m_Sx和m_Sy的类型改为double。10) 为了在CCh4_2DTransView类中能够调用对话框累Dlg_Scale需在CCh4_2DTransView类的开头部分加入头文件:#include “Dlg_Scale.h”11) 在OnScale()函数中添加如下代码:ClearScreen();m_type_transform = TRF_SCALE;m_LT = CPoint(100,300);m_LB = CPoint(100,100);m_RT = CPoint(300,300);m_RB = CPoint(300,100);DrawRect();CClientDC dc(this);CPen* oldPen;CPen newPen(PS_DASH,1,RGB(0,0,0);oldPen = dc.SelectObject(&newPen);dc.MoveTo(0,0);dc.LineTo(m_LT);dc.MoveTo(0,0);dc.LineTo(m_RB);dc.SelectObject(oldPen);double Sx = 1;double Sy = 1;Dlg_Scale dlgScale;if(dlgScale.DoModal() = IDOK)Sx = dlgScale.m_Sx;Sy = dlgScale.m_Sy;m_LT.x *= Sx;m_LB.x *= Sx;m_RT.x *= Sx;m_RB.x *= Sx;m_LT.y *= Sy;m_LB.y *= Sy;m_RT.y *= Sy;m_RB.y *= Sy;ClearScreen();DrawRect();oldPen = dc.SelectObject(&newPen);dc.MoveTo(0,0);dc.LineTo(m_LT);dc.MoveTo(0,0);dc.LineTo(m_RB);dc.SelectObject(oldPen);至此,代码部分结束。编译运行,点击菜单项的【比例】,出现如图所示图形和对话框:在对话框中输入想要在x和y轴方向进行缩放的比例,点击确定,即可看到缩放之后的结果。3、旋转变换旋转变换是将图新绕某一旋转中心转动一个角度,通常约定以逆时针方向为正方向。最简单的旋转变换是以坐标原点(0,0)为旋转中心,这时,平面上一点旋转了之后,变成点,则有,xyO图4.4 旋转变换为了实现旋转变换的功能,在前面代码的基础上继续添加代码。在本小节的代码中,我们将前面代码实现的矩形按照用户输入的参数进行旋转。程序步骤:1) 单击Workspace中的ResourceView标签中的Menu左边的“+”号,双击其子项:IDR_MAINFRAME。2) 在【二维图形变换】菜单的子菜单【比例】之下建立一个新的菜单【旋转】,ID号设为:IDT_ROTATE 3) 右键单击【旋转】,选择Classwizzard,在弹出的对话框中选择Object IDs为IDT_ROTATE,Class name选为CCh4_2DTransView,Messages选为Command,单击Add Functions,单击确定。4) 打开Workspace中的ResourceView,右键单击Dialog,选择Insert Dialog,则出现了一个新的对话框资源,将其ID号改为IDD_ROTATE.5) 将一个静态文本框和一个编辑框加入到对话框中,编辑框的ID设为IDC_ROTATE_ANGLE。6) 右键单击对话框,选择Classward,点击确定。在弹出的New对话框中的Name栏中键入Dlg_Rotate。7) 单击Member Variables标签,双击其中的IDC_ROTATE_ANGLE,在弹出的对话框中键入变量名:m_RotateAngle,Variable type栏选择int,单击确定。8) 点击Workspace中的ClassView标签,双击Dlg_Rotate,将m_RotateAngle的类型改为double。9) 在CCh4_2DTransView类的开头部分加入头文件:#include “Dlg_Rotate.h”和#include “math.h”10) 在OnRotate()函数中添加如下代码:ClearScreen();m_type_transform = TRF_ROTATE;m_LT = CPoint(100,300);m_LB = CPoint(100,100);m_RT = CPoint(300,300);m_RB = CPoint(300,100);DrawRect();CClientDC dc(this);CPen* oldPen;CPen newPen(PS_DASH,1,RGB(0,0,0);oldPen = dc.SelectObject(&newPen);dc.MoveTo(0,0);dc.LineTo(m_LT);dc.SelectObject(oldPen);double angle = 0;Dlg_Rotate dlgRotate;if(dlgRotate.DoModal() = IDOK)angle = dlgRotate.m_RotateAngle / 180 * 3.1415926;double c = cos(angle);double s = sin(angle);m_LT.x = m_LT.x * c - m_LT.y * s;m_LT.y = m_LT.x * s + m_LT.y * c;m_LB.x = m_LB.x * c - m_LB.y * s;m_LB.y = m_LB.x * s + m_LB.y * c;m_RT.x = m_RT.x * c - m_RT.y * s;m_RT.y = m_RT.x * s + m_RT.y * c;m_RB.x = m_RB.x * c - m_RB.y * s;m_RB.y = m_RB.x * s + m_RB.y * c;ClearScreen();DrawRect();oldPen = dc.SelectObject(&newPen);dc.MoveTo(0,0);dc.LineTo(m_LT);dc.SelectObject(oldPen);至此,代码部分结束。编译运行,点击菜单项中的【旋转】,出现如图所示图形和对话框:输入图形旋转的角度,按确定即可看到旋转之后的图形。4、对称变换对称变换的公式如下:,当取不同值时,产生不同的对称变换。(1) 当时,产生相对于轴对称的反射图形。(2) 当时,产生相对于轴对称的反射图形。(3) 当时,产生相对于原点对称的反射图形。(4) 当时,产生相对于直线对称的反射图形。(5) 当时,产生相对于直线对称的反射图形。y轴对称x轴对称原点对称直线对称直线对称图4.5 对称变换为实现对称变换的目的,我们仍然在前面代码的基础上继续添加代码。本小节,我们添加菜单项命令来实现关于y轴、x轴、原点、直线y = x、直线y = -x的对称变换。程序步骤:1) 单击Workspace中的ResourceView标签中的Menu左边的“+”号,双击其子项:IDR_MAINFRAME。2) 在【二维图形变换】菜单的子菜单【旋转】之下建立一个新的菜单【对称】,勾选Pop-up选项。在【对称】菜单下新建菜单【关于y轴】,其ID号设为IDT_SYMMETRY_Y3) 右键单击【关于y轴】,选择Classwizzard,在弹出的对话框中选择Object IDs为IDT_SYMMETRY_Y,Class name选为CCh4_2DTransView,Messages选为Command,单击Add Functions,单击确定,点击Edit Code编辑函数OnSymmetryY4) 为CCh4_2DTransView类增加一个成员函数 void DrawTriangle(),其代码为:5) 在函数OnSymmetryY中添加如下代码:ClearScreen();m_type_transform = TRF_SYMMETRY_Y;CClientDC dc(this);dc.MoveTo(0,300);dc.LineTo(800,300);dc.MoveTo(400,0);dc.LineTo(400,600);m_LT = CPoint(100,150);m_LB = CPoint(100,100);m_RB = CPoint(150,100);DrawTriangle();double a = -1;double b = 0;double d = 0;double e = 1;int x = m_LT.x;int y = m_LT.y;m_LT.x = (x - 400) * a + (y - 300) * b + 400;m_LT.y = (x - 400) * d + (y - 300) * e + 300;x = m_LB.x;y = m_LB.y;m_LB.x = (x - 400) * a + (y - 300) * b + 400;m_LB.y = (x - 400) * d + (y - 300) * e + 300;x = m_RB.x;y = m_RB.y;m_RB.x = (x - 400) * a + (y - 300) * b + 400;m_RB.y = (x - 400) * d + (y - 300) * e + 300;DrawTriangle();至于其它的对称方式是类似的,只需改变函数中的a、b、d、e的值即可。5、错切错切变换的公式为:,(1) 当时,图形的坐标随初值及变换常数做线性变换,如果图形沿轴正方向移位,如果图形沿轴反方向移位。(2) 当时,图形的坐标随初值及变换常数做线性变换,如果图形沿轴正方向移位,如果图形沿轴反方向移位。(3) 当时,图形沿,两个方向移位。实现沿x方向、y方向以及x、y两个方向的错切变换,在刚才的Ch4_2Dtrans_2Dtrans 工程的基础上添加代码。程序步骤:1) 单击Workspace中的ResourceView标签中的Menu左边的“+”号,双击其子项:IDR_MAINFRAME。2) 在【二维图形变换】菜单的子菜单【对称】之下建立一个新的菜单【错切】,勾选Pop-up选项。在【错切】菜单下新建菜单【沿y方向】,其ID号设为IDT_SHEAR_Y3) 右键单击【沿y方向】,选择Classwizzard,在弹出的对话框中选择Object IDs为IDT_SHEAR_Y,Class name选为CCh4_2DTransView,Messages选为Command,单击Add Functions,单击确定,点击Edit Code编辑函数OnShearY4) 在函数OnShearY中添加如下代码:ClearScreen();m_type_transform = TRF_SHEAR_Y;CClientDC dc(this);dc.MoveTo(0,300);dc.LineTo(800,300);dc.MoveTo(400,0);dc.LineTo(400,600);/相当于坐标原点放在(400,300)CPoint Origin = CPoint(400,300);CPoint LT = CPoint(-50,100);CPoint LB = CPoint(-50,-100);CPoint RT = CPoint(50,100);CPoint RB = CPoint(50,-100);m_LT = LT +Origin;m_LB = LB +Origin;m_RT = RT +Origin;m_RB = RB +Origin;DrawRect();5) 在OnMouseMove()函数中添加如下一些新的局部变量:Int x;Int y;double b;double d;6) 在OnMouseMove的switch中添加如下代码:case TRF_SHEAR_X:if(m_bLBDown)/清屏ClearScreen();CClientDC dc(this);dc.MoveTo(0,300);dc.LineTo(800,300);dc.MoveTo(400,0);dc.LineTo(400,600);/更新矩形数据并画矩形delta = point.x - m_prevPoint.x;m_prevPoint = point;b = 0.01;d = 0;x = m_LT.x - 400;y = m_LT.y - 300;m_LT.x = x + y * b * delta + 400;m_LT.y = x * d * delta + y + 300;x = m_LB.x - 400;y = m_LB.y - 300;m_LB.x = x + y * b * delta + 400;m_LB.y = x * d * delta + y + 300;x = m_RT.x - 400;y = m_RT.y - 300;m_RT.x = x + y * b * delta + 400;m_RT.y = x * d * delta + y + 300;x = m_RB.x - 400;y = m_RB.y - 300;m_RB.x = x + y * b * delta + 400;m_RB.y = x * d * delta + y + 300;DrawRect();break;7) 沿x方向和沿x、y方向的错切变换是类似的。编译运行,点击菜单中的沿y轴错切命令,出现如图所示图形。按下鼠标左键,随着鼠标上下的移动,我们可以看到图中的图形在进行沿y轴方向的切变。 4.3 投影变换我们知道,现有的图形显示设备是平面的,因此如果要将三维物体显示出来,必须用到投影的方法。本节中我们将实现平行投影中的一种正交投影:等轴投影以及斜交投影中的斜二测投影和斜等轴投影,最后实现透视投影。1、 平行投影平行投影分为两种:正交投影和斜交投影。1)正交投影投影平面与投影方向垂直的投影称为正交投影。一种常见的正交投影是等轴投影,即投影平面与三个坐标轴的夹角都相等。为了显示等轴投影,我们构造空间中的一个正方体,它可以由它的八个顶点来表示。将这八个顶点分别利用投影矩阵投影到二维平面上,再将原来具有邻接关系的顶点连接起来就得到了三维图形投影之后的二维图形。程序步骤:1)建立一个新的MFC工程,工程名为CCh4_ProjAnd3DTransView,并在CCh4_ProjAnd3DTransView.h文件中CCh4_ProjAnd3DTransView类定义之前定义如下类类型:2)在CCh4_ProjAnd3DTransView类中添加如下成员变量:3)添加一个CCh4_ProjAnd3DTransView类的成员变量:double m_Proj_Matri444)添加一个CCh4_ProjAnd3DTransView类的成员函数void DrawRect(CPoint P1,CPoint P2,CPoint P3,CPoint P4),其代码如下:5)添加一个CCh4_ProjAnd3DTransView的成员函数void DrawCubic(),其代码如下:/Draw Left faceDrawRect(m_2dLbb,m_2dLbt,m_2dLft,m_2dLfb);/Draw Right faceDrawRect(m_2dRbb,m_2dRbt,m_2dRft,m_2dRfb);/Draw Back faceDrawRect(m_2dLbb,m_2dLbt,m_2dRbt,m_2dRbb);/Draw Front faceDrawRect(m_2dLfb,m_2dLft,m_2dRft,m_2dRfb);/Draw Bottom faceDrawRect(m_2dLbb,m_2dLfb,m_2dRfb,m_2dRbb);/Draw Top faceDrawRect(m_2dLbt,m_2dLft,m_2dRft,m_2dRbt);6)增加一个CCh4_ProjAnd3TransView的成员函数:void From3dTo2d(),其代码如下:m_2dLbb.x = m_LBB.x * m_Proj_Matri00 + m_LBB.y * m_Proj_Matri01 + m_LBB.z * m_Proj_Matri02 + m_Proj_Matri04;m_2dLbb.y = m_LBB.x * m_Proj_Matri10 + m_LBB.y * m_Proj_Matri11 + m_LBB.z * m_Proj_Matri12 + m_Proj_Matri14;m_2dLbt.x = m_LBT.x * m_Proj_Matri00 + m_LBT.y * m_Proj_Matri01 + m_LBT.z * m_Proj_Matri02 + m_Proj_Matri04;m_2dLbt.y = m_LBT.x * m_Proj_Matri10 + m_LBT.y * m_Proj_Matri11 + m_LBT.z * m_Proj_Matri12 + m_Proj_Matri14;m_2dLfb.x = m_LFB.x * m_Proj_Matri00 + m_LFB.y * m_Proj_Matri01 + m_LFB.z * m_Proj_Matri02 + m_Proj_Matri04;m_2dLfb.y = m_LFB.x * m_Proj_Matri10 + m_LFB.y * m_Proj_Matri11 + m_LFB.z * m_Proj_Matri12 + m_Proj_Matri14;m_2dLft.x = m_LFT.x * m_Proj_Matri00 + m_LFT.y * m_Proj_Matri01 + m_LFT.z * m_Proj_Matri02 + m_Proj_Matri04;m_2dLft.y = m_LFT.x * m_Proj_Matri10 + m_LFT.y * m_Proj_Matri11 + m_LFT.z * m_Proj_Matri12 + m_Proj_Matri14;m_2dRbb.x = m_RBB.x * m_Proj_Matri00 + m_RBB.y * m_Proj_Matri01 + m_RBB.z * m_Proj_Matri02 + m_Proj_Matri04;m_2dRbb.y = m_RBB.x * m_Proj_Matri10 + m_RBB.y * m_Proj_Matri11 + m_RBB.z * m_Proj_Matri12 + m_Proj_Matri14;m_2dRbt.x = m_RBT.x * m_Proj_Matri00 + m_RBT.y * m_Proj_Matri01 + m_RBT.z * m_Proj_Matri02 + m_Proj_Matri04;m_2dRbt.y = m_RBT.x * m_Proj_Matri10 + m_RBT.y * m_Proj_Matri11 + m_RBT.z * m_Proj_Matri12 + m_Proj_Matri14;m_2dRfb.x = m_RFB.x * m_Proj_Matri00 + m_RFB.y * m_Proj_Matri01 + m_RFB.z * m_Proj_Matri02 + m_Proj_Matri04;m_2dRfb.y = m_RFB.x * m_Proj_Matri10 + m_RFB.y * m_Proj_Matri11 + m_RFB.z * m_Proj_Matri12 + m_Proj_Matri14;m_2dRft.x = m_RFT.x * m_Proj_Matri00 + m_RFT.y * m_Proj_Matri01 + m_RFT.z * m_Proj_Matri02 + m_Proj_Matri04;m_2dRft.y = m_RFT.x * m_Proj_Matri10 + m_RFT.y * m_Proj_Matri11 + m_RFT.z * m_Proj_Matri12 + m_Proj_Matri14;7)增加ClearScreen函数,代码与二维图形变换中的ClearScreen函数相同。8)打开Resource标签,双击Menu,增加一个新的菜单【投影变换】,在其下建立菜单项【正交投影】,将其设置为Pop-Up类型。在【正交投影】中建立子菜单项【等轴投影】其ID号设为IDP_ISOMETRIC,右键单击【等轴投影】,选择ClassWizzard,在弹出的对话框中选择Class name为CCh4_ProjAnd3DtransView,选择Messages 为COMMAND,单击确定。9)编辑OnIsometric函数,在其中添加如下代码:ClearScreen();m_Proj_Matri00=0.70710678118655;m_Proj_Matri01=0.70710678118655;m_Proj_Matri02=0;m_Proj_Matri03 = 0; m_Proj_Matri10=-0.40824829046386;m_Proj_Matri11=0.40824829046386;m_Proj_Matri12=0.81649658092773;m_Proj_Matri13 = 0; m_Proj_Matri20=0;m_Proj_Matri21=0;m_Proj_Matri22=0;m_Proj_Matri23 = 0; m_Proj_Matri30 = 0;m_Proj_Matri31 = 0;m_Proj_Matri32 = 0;m_Proj_Matri33 = 1;From3dTo2d();DrawCubic();10)在CCh4_ProjAnd3DtransView的构造函数中添加如下代码:2)斜交投影斜交投影,指投影方向与投影平面不垂直的投影方式,常用的有斜二测投影、斜等轴投影。本小节即来实现这两种投影。在前面代码基础之上添加代码。程序步骤:1)打开Resource标签,双击Menu,在菜单【投影变换】中【正交投影】下面添加【斜交投影】,并为【斜交投影】建立两个子菜单,【斜二测投影】,【斜等轴投影】,其ID号分别设为IDP_CABINET和IDP_CAVALIER,右键单击【斜二测投影】,选择ClassWizzard,在弹出的对话框中选择Class name为CCh4_ProjAnd3DtransView,选择Messages 为COMMAND,单击确定。2)编辑OnCabinet函数,在其中添加如下代码:3)编辑OnCavalier()函数,代码如下:4)为了使上面代码能够顺利运行,在CCh4_ProjAnd3DtransView.h中添加如下头文件#include “math.h”2、 透视投影在平行投影中,对三维物体上的任意一组平行直线投影后所得的直线,或者仍然平行,或者重合。但在透视投影中,物体上的平行直线如果不是平行与投影平面,那么,投影之后的图形将不再互相平行。本节,我们就来实现一种最简单的透视投影,仍然在前面CCh4_ProjAnd3Dtrans工程基础上添加代码。程序步骤:1) 打开Resource标签,双击Menu,在菜单【投影变换】【斜交投影】下面新建的【透视投影】菜单,其ID号设为IDP_PERSPECTIVE,右键单击【透视投影】,选择ClassWizzard,在弹出的对话框中选择Class name为CCh4_ProjAnd3DtransView,选择Messages 为COMMAND,单击确定。2) 编辑OnPerspective函数,在其中添加如下代码:4.4 三维图形变换类似与二维图形,三维图形也可以进行平移、旋转、比例等几何变换。本节即来实现这一部分。在本节所实现的三维图形的平移、比例、旋转变换,所采用投影方式都是斜二测投影,并且仍然在CCh4_ProjAnd3Dtrans工程的基础上添加代码。程序步骤:1) 在CCh4_ProjAnd3DtransView之前再定义一种枚举型变量类型:2) 为CCh4_ProjAnd3DtransView类添加新的成员变量:3) 建立五个消息响应函数:WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MOUSEMOVE, WM_RBUTTONDOWN, WM_RBUTTONUP。4) 在函数OnLButtonDown,OnLButtonUp,OnRButtonDown,OnRButtonUp,OnMouseMove函数中分别添加如下代码(黑体部分是后添加的代码):void CCh4_ProjAnd3DTransView:OnLButtonDown(UINT nFlags, CPoint point) m_bLBDown = TRUE;m_prevPoint = point;CView:OnLButtonDown(nFlags, point);void CCh4_ProjAnd3DTransView:OnLButtonUp(UINT nFlags, CPoint point) m_bLBDown = FALSE;m_prevPoint = point;CView:OnLButtonUp(nFlags, point);void CCh4_ProjAnd3DTransView:OnRButtonDown(UINT nFlags, CPoint point) m_bRBDown = TRUE;m_prevPoint = point;CView:OnRButtonDown(nFlags, point);void CCh4_ProjAnd3DTransView:OnRButtonUp(UINT nFlags, CPoint point) m_bRBDown = FALSE;m_prevPoint = point;CView:OnRButtonUp(nFlags, point);void CCh4_ProjAnd3

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论