第05章-几何变换_第1页
第05章-几何变换_第2页
第05章-几何变换_第3页
第05章-几何变换_第4页
第05章-几何变换_第5页
已阅读5页,还剩73页未读 继续免费阅读

下载本文档

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

文档简介

计算机图形学第5章几何变换5.1二维变换计算机图形学经常用到基本的二维和三维几何变换,其中的平移变换、比例变换和旋转变换对很多图形应用程序来说极其重要。许多应用程序或图形子程序软件包需要用到各种变换,例如:一个城市规划程序,利用平移变换将表示建筑物和树木的图符移到合适的位置,利用旋转变换确定图符的朝向,以及利用比例变换确定图符的大小。一般来说,很多应用程序在绘图时都要用到几何变换来改变物体(也称为图符或模板)的位置、方向和大小5.1.1平移变换5.1.1平移变换变换前一座房子的平移变换.变换后5.1.2放缩变换

假设将点P(x,y)在x轴方向、y轴方向分别放缩sx和sy倍,得到点P'(x',y'),则有5.1.2放缩变换

矩阵表示

放缩变换是相对于坐标原点的,当它作用于物体时,不仅改变了物体的大小和形状,也改变了它离原点的距离。在图中,当sx=sy=1/2时,不仅线段P'0P'1的长度为P0P1的一半,而且它到原点的距离也为P0P1到原点距离的一半。在放缩变换中,两个方向上的放缩比例sx和sy可以不相等,也可以相等。当sx=sy时,该放缩变换成为象似中心在原点的象似变换。5.1.2放缩变换房子的比例变换。两个方向上的变换比例不同,并且房子改变了位置。比例变换前比例变换后5.1.3旋转变换

给定点P(x,y),其极坐标形式为:5.1.3旋转变换

将点P(x,y)绕坐标原点旋转角度

(逆时针为正,顺时针为负),得到P'(x',y'),则

矩阵表示5.1.3旋转变换旋转之前旋转之后房子的旋转变换,旋转的同时也改变了位置。5.2齐次坐标系和二维变换的矩阵表示平移、旋转和缩放的矩阵表示分别为

可是,平移的处理方法(矩阵加法)不同于缩放和旋转(矩阵乘法),这在进行复合变换时十分不方便5.2齐次坐标系和二维变换的矩阵表示在实际绘图时,常要对图形对象连续做多个变换,例如先平移,再旋转、放大等。这样对该图形上的每个点都要进行复杂的坐标计算,计算量较大。如果只对图形对象进行旋转和放缩两类变换,如先旋转,再放缩,则可以通过首先将两变换合成一个复合变换,将两次运算转换成一次性的矩阵与向量乘法,即

这样,对图形对象上每点做上述变换时,只要用A乘点的坐标就可以了。但如果在变换中再加入平移变换式。变换就不容易合并了。困难来自于平移变换和旋转、放缩变换的表示形式不一样;平移变换为一个矩阵的加法,而旋转和放缩变换为一个矩阵的乘法。为了使得各种变换的表示形式一致,从而使变换合成更容易,所以引入了齐次坐标的概念5.2齐次坐标系和二维变换的矩阵表示

所谓齐次坐标表示法就是由n+1维向量表示一个n维向量。n维空间中点的位置向量用非齐次坐标表示时,具有n个坐标分量(P1,P2,…,Pn),且是唯一的。若用齐次坐标表示时,此向量有n+1个坐标分量(hP1,hP2,…,hPn,h),且不唯一。普通的或“物理的”坐标与齐次坐标的关系为一对多的关系。点(x,y)的齐次坐标定义为(xh,yh,h),其中h0,xh=hx,yh=hy。从定义中不难看出,只要(xh1,yh1,h1)和(xh2,yh2,h2)对应的元素成比例,即5.2齐次坐标系和二维变换的矩阵表示则它们对应于二维空间中的同一点事实上,(x,y)点对应的齐次坐标为三维空间的一条直线:该直线上的每一点都对应同一个二维坐标点(x,y)。这种多对一的映射往往使运算更为复杂,所以通常取(x,y)的齐次坐标为(x,y,1),即取h=1。以后如不特别指出,齐次坐标指的都是这种意义上的齐次坐标。当h=0而xh和yh不都为0时,齐次坐标(xh,yh,0)对应二维空间的无穷远点。5.2.1平移变换在齐次坐标下,平移变换可表示为5.2.2比例变换在齐次坐标下,比例变换可表示为5.2.3旋转变换在齐次坐标下,旋转变换可表示为5.2.4刚体变换和仿射变换观察旋转变换矩阵,可以看到他们的左上角有个2×2的子矩阵,我们可以将其中的每一行看作是一个行向量。这两个行向量有以下几个特点:每个都是单位向量两个向量之间相互垂直(它们的点积为零)如果将每个向量所指的方向旋转R(θ),那么这些方向量便可位于正x轴、y轴方向前两个特点也适用于该2×2子矩阵的两个列向量,并且列向量所对应的两个方向量就是沿x轴和y轴正方向的向量(i,j)经矩阵R变换后而得到的。因此,当已知旋转变换的结果时,这些特点便为如何构造旋转变换矩阵提供了两种有效的方法。具有这些特性的矩阵称为特殊正交阵5.2.4刚体变换和仿射变换对于形如下面的变换矩阵,若其左上角的主子式是正交的,那么该矩阵变换保角保长。也就是说,一个单位的正方形经该矩阵变换后仍然是一个单位的正方形,这种变换称为刚体变换。因为进行变换的物体不会有任何变形,如任意次序的旋转、平移变换5.2.4刚体变换和仿射变换一系列任意的旋转、平移和比例变换的结果又是如何呢?这些变换称为仿射变换,它们能够保持直线平行性,但不保角和不保长。如图所示,其中先将一个单位正方体旋转45度,然后进行不均匀的比例变换。很明显,正方体的角度和长度都发生了变化,但那些原来平行的线仍保持平行,再继续进行旋转、比例和平移变换也不会改变线的平行性,R(θ)、S(sx,sy)和T(dx,dy)都是仿射变换。R(θ)、T(dx,dy)也是刚体变换保长保角。刚体变换一定也是仿射变换

单位正方体

旋转45度

在x轴方向拉伸5.2.4刚体变换和仿射变换单位正方体在x方向上错切在y方向上错切5.2.5对称变换对称变换可用来求一个图形关于某一镜面的反射图形(即镜像),在二维空间中,这个镜像即为一条直线,这条直线称为对称轴5.2.5对称变换(1)x坐标相同(2)y坐标互为负数5.2.5对称变换5.3二维变换的组合当我们需要对一个图形对象进行较为复杂的变换时,我们并不直接去计算这个变换,而是首先将其分解成多个基本变换,再依次用它们作用于图形。这种变换分解、再合成的方法看起来有些麻烦,但对用户来说却更直观、更易于想象。甚至在有些场合,它成了唯一可行方法5.3.1关于任意点P1旋转物体要实现绕任意一点P1的旋转,可分解为如下三次基本变换将P1点平移到原点;旋转;平移还原回P1点5.3.2关于任意点P1比例变换5.3.3综合变换5.3.3综合变换注意变换合成时,矩阵相乘的顺序。先作用的变换放在连乘式的右端,后作用的变换放在连乘式的左端。对于两个基本变换M1,M2,由于矩阵乘法不满足交换律,通常M1•M2

M2•M1Translate2D(1,0);Rotate2D(45);House();Rotate2D(45);Translate2D(1,0);House();5.3.3综合变换写出综合变换矩阵.12003456782345678112345678123456785.4窗口到视口的变换为了使被显示的图形对象数字化,用户需要在图形对象所在的空间定义一个坐标系。这个坐标系的长度单位和坐标轴方向要便于对显示对象的描述,这个坐标系称为世界坐标系(WorldCoordinate)。由于用户通常按自己熟悉的方式建立世界坐标系,所以世界坐标系有时也称用户坐标系(UserCoordinate)为了简化图形对象的描述,用户有时采用相对于物体的坐标系,这个坐标系称为局部坐标系(LocalCoordinate)。局部坐标系建立于物体之上,它和物体之间的相对位置保持不变5.4.1基本概念计算机对数字化的图形对象作了必要的处理之后,要将它在图形显示器或绘图纸上绘制出来,这就要在显示屏幕上或绘图纸上定义一个二维直角坐标系,这个坐标系称为屏幕坐标系或设备坐标系(Devicecoordinate)。该坐标系的坐标轴常取成平行于屏幕或绘图纸边缘,长度单位取成一个象素的长度或绘图机的步长,坐标取成整数,坐标系的原点和坐标轴的方向随显示设备的不同而不同。常见的微机显示器的屏幕坐标系如图所示5.4.1基本概念5.4.1基本概念空间坐标系中的输出图元被窗口剪切,保留的部分在视口中显示出来。5.4.2视窗变换实例WindowToView1.创建一个单文档MFC应用程序。由于不涉及文档的相关操作,所以在去掉“Document/ViewArchitectureSupport”,去掉MaximizeBox,选中“Maximized”,点击“完成”2.使用资源编辑器添加一个对话栏(注意不是对话框)IDD_DIALOGBAR,然后在对话栏中添加4个编辑控件(Edit)和4个微调控件(Spin)。注意为编辑控件设置Read-Only属性,为微调控件设置Alignment为Right,设置SetBuddyInteger和NoThousands风格3.为CMainFrame类添加一个CDialogBar类型的成员变量m_wndDialogBar,然后在CMainFrame::OnCreat()函数中添加代码if(!m_wndDialogBar.Create(this,IDD_DIALOGBAR,CBRS_TOP,AFX_IDW_CONTROLBAR_LAST-1)){ TRACE0("Failedtocreatedialogbar\n"); return-1;}5.4.2视窗变换实例WindowToView4.在CChildView.cpp文件中添加//Includeafxtempl.hforCArray<CRect,CRect>#include<afxtempl.h>5.为CChildView增加成员变量 CFontm_font;//显示文字所用字体 BOOLm_bIsInitialized;//是否初始化 BOOLm_bIsInWindowRect;//光标是否位于窗口内 intm_nMaxWinWidth;//窗口最大宽度 intm_nMaxWinHeight;//窗口最大高度 CPointm_ptWorldOrg;//世界坐标系原点 CPointm_ptScreenOrg;//屏幕坐标系原点 CPointm_ptOldPoint;//以前的点 CRectm_rcWorldRect;//世界坐标系 CRectm_rcWindowRect;//窗口 CRectm_rcScreenRect;//屏幕坐标系 CRectm_rcViewportRect;//视口 CArray<CRect,CRect>m_aWorldFigures;//世界坐标系中图形 CArray<CRect,CRect>m_aScreenFigures;//屏幕坐标系中图形5.4.2视窗变换实例WindowToView6.成员变量的初始化

在CChildView::CChildView()构造函数中初始化m_bIsInitialized和m_bIsInWindowRect为FALSE;7.在CChildView::OnPaint()中初始化有关窗口和视口的基本数据voidCChildView::OnPaint(){CPaintDCdc(this);//用于绘制的设备上下文CRectrcClient;//视图客户区矩形GetClientRect(&rcClient);//获取客户区矩形5.4.2视窗变换实例WindowToView//TODO:在此处添加消息处理程序代码if(!m_bIsInitialized){m_ptWorldOrg= CPoint(rcClient.right*11/40,rcClient.bottom*1/2);//记录世界坐标系原点m_ptScreenOrg= CPoint(rcClient.right*29/40,rcClient.bottom*1/2);//记录屏幕坐标系原点m_rcWorldRect= CRect(-rcClient.right*7/40,-rcClient.bottom*5/16, rcClient.right*7/40,rcClient.bottom*5/16);//记录世界坐标系矩形m_rcScreenRect=m_rcWorldRect;//屏幕坐标系矩形m_rcWindowRect=CRect(-(m_rcWorldRect.right-m_rcWorldRect.left)*3/8, -(m_rcWorldRect.right-m_rcWorldRect.left)*9/32, (m_rcWorldRect.right-m_rcWorldRect.left)*3/8, (m_rcWorldRect.right-m_rcWorldRect.left)*9/32);//窗口矩形m_rcViewportRect=m_rcWindowRect;//视口矩形5.4.2视窗变换实例WindowToView//初始化世界坐标系中的图形m_aWorldFigures.SetSize(4);m_aWorldFigures[0]=CRect(-m_rcWorldRect.Width()*9/20,-m_rcWorldRect.Height()/5, m_rcWorldRect.Width()*2/5,m_rcWorldRect.Height()/15);m_aWorldFigures[1]=CRect(-m_rcWorldRect.Width()/13,-m_rcWorldRect.Height()/10, m_rcWorldRect.Width()*4/13,m_rcWorldRect.Height()*2/7);m_aWorldFigures[2]=CRect(-m_rcWorldRect.Width()*2/5,m_rcWorldRect.Height()/6, m_rcWorldRect.Width()/6,m_rcWorldRect.Height()*2/5);m_aWorldFigures[3]=CRect(-m_rcWorldRect.Width()/5,-m_rcWorldRect.Height()*2/5, m_rcWorldRect.Width()/4,-m_rcWorldRect.Height()/8);5.4.2视窗变换实例WindowToView//初始化屏幕坐标系中的图形m_aScreenFigures.Copy(m_aWorldFigures);//确定窗口的最大宽度和高度m_nMaxWinWidth=m_rcWorldRect.Width()-6;m_nMaxWinHeight=m_rcWorldRect.Height()-6;//////////////////////////////////////////////////处理微调按钮和编辑框CSpinButtonCtrl*pSpinWW=GetSpinByID(IDC_SPINWW);CSpinButtonCtrl*pSpinWH=GetSpinByID(IDC_SPINWH);CSpinButtonCtrl*pSpinVW=GetSpinByID(IDC_SPINVW);CSpinButtonCtrl*pSpinVH=GetSpinByID(IDC_SPINVH);//将微调按钮和编辑框一一建立伙伴关系pSpinWW->SetBuddy(GetEditByID(IDC_EDITWW));pSpinWH->SetBuddy(GetEditByID(IDC_EDITWH));pSpinVW->SetBuddy(GetEditByID(IDC_EDITVW));pSpinVH->SetBuddy(GetEditByID(IDC_EDITVH));5.4.2视窗变换实例WindowToView//设置微调按钮的数值范围,最小值为2是为了防止产生除0错误pSpinWW->SetRange(2,m_nMaxWinWidth);pSpinWH->SetRange(2,m_nMaxWinHeight);pSpinVW->SetRange(2,m_nMaxWinWidth);pSpinVH->SetRange(2,m_nMaxWinHeight);pSpinWW->SetPos(m_rcWindowRect.Width());pSpinWH->SetPos(m_rcWindowRect.Height());pSpinVW->SetPos(m_rcWindowRect.Width());pSpinVH->SetPos(m_rcWindowRect.Height());//将初始化标志置为真m_bIsInitialized=TRUE;}5.4.2视窗变换实例WindowToView/////////////////////////////////显示标题dc.SelectObject(&m_font);dc.SetTextColor(RGB(255,0,0));//Settextcolordc.SetTextAlign(TA_CENTER+TA_BOTTOM);//Settextaligndc.TextOut(rcClient.right/2,30,_T("窗口到视口的变换"));//Showtitle//////////////////////////////////处理世界坐标系dc.SetViewportOrg(m_ptWorldOrg);//设置当前原点为“世界坐标系原点”dc.SetTextColor(RGB(0,0,255));dc.TextOut(0,m_rcWorldRect.top-20,_T("窗口"));dc.SetTextColor(RGB(0,150,0));dc.TextOut(0,m_rcWorldRect.bottom+30,_T("世界坐标系"));//绘制世界坐标系矩形DrawRect(&dc,m_ptWorldOrg,m_rcWorldRect,R2_COPYPEN,BS_NULL,RGB(0,150,0));5.4.2视窗变换实例WindowToView//绘制世界坐标系中的图形dc.Rectangle(m_aWorldFigures[0]);dc.Rectangle(m_aWorldFigures[1]);dc.Rectangle(m_aWorldFigures[2]);dc.Rectangle(m_aWorldFigures[3]);//绘制窗口矩形DrawRect(&dc,m_ptWorldOrg,m_rcWindowRect,R2_NOTXORPEN);//////////////////////////////////处理屏幕坐标系dc.SetViewportOrg(m_ptScreenOrg);//设置当前原点为“屏幕坐标系原点”dc.SetTextColor(RGB(0,0,255));dc.TextOut(0,m_rcScreenRect.top-20,_T("视口"));dc.SetTextColor(RGB(0,150,0));dc.TextOut(0,m_rcScreenRect.bottom+30,_T("屏幕坐标系"));//绘制屏幕坐标系矩形DrawRect(&dc,m_ptScreenOrg,m_rcScreenRect,R2_COPYPEN,BS_NULL,RGB(0,150,0));//绘制屏幕坐标系中的矩形DrawFigures(&dc);};5.4.2视窗变换实例WindowToView8.在CChildView.cpp文件中添加

#include"MainFrm.h"9.为类CChildView添加成员函数voidDrawRect(CDC*pDC,CPointorigin,CRectrect,int nDrawMode=R2_COPYPEN,UINT brushStyle=BS_NULL,COLORREFpenColor=RGB(0,0,255));绘矩形voidDrawFigures(CDC*pDC);//绘制视口中的图形voidOffsetFigures(CPointoffset);//移动视口中的图形CEdit*GetEditByID(intid);//获取编辑控件CSpinButtonCtrl*GetSpinByID(intid);//获取微调控件afx_msgBOOLOnSetCursor(CWnd*pWnd,UINTnHitTest,UINT message);afx_msgvoidOnLButtonDown(UINTnFlags,CPointpoint);afx_msgvoidOnMouseMove(UINTnFlags,CPointpoint);5.4.2视窗变换实例WindowToViewvoidCChildView::DrawRect(CDC*pDC,CPointorigin,CRectrect,intnDrawMode,unsignedintbrushStyle,COLORREFpenColor){intnOldMode=pDC->SetROP2(nDrawMode);//设置绘图模式CPenpen(PS_SOLID,2,penColor);//设置画笔颜色CPen*pOldPen=pDC->SelectObject(&pen);CBrushbrush,*pOldBrush;//LOGBRUSHlgbrush;lgbrush.lbStyle=brushStyle;lgbrush.lbColor=RGB(255,255,255);brush.CreateBrushIndirect(&lgbrush);//创建画刷pOldBrush=pDC->SelectObject(&brush);pDC->SetViewportOrg(origin);//设置原点pDC->Rectangle(rect);//绘制矩形//重置设备环境pDC->SelectObject(pOldPen);pDC->SelectObject(pOldBrush);pDC->SetROP2(nOldMode);}5.4.2视窗变换实例WindowToViewvoidCChildView::DrawFigures(CDC*pDC){CRectwr=m_rcWindowRect;wr.OffsetRect(-wr.CenterPoint());//视口中图形的移动和窗口的移动是相反的pDC->SetViewportOrg(m_ptScreenOrg);//以屏幕坐标系原点为当前原点pDC->Rectangle(m_rcViewportRect);//擦除视口中原来的图形pDC->SetMapMode(MM_ANISOTROPIC);//设置映射模式为各向异性pDC->SetWindowExt(m_rcWindowRect.Width(),m_rcWindowRect.Height());//设置窗口大小pDC->SetViewportExt(m_rcViewportRect.Width(),m_rcViewportRect.Height());//设置视口大小//绘制视口中的图形,通过“交”操作来代替裁剪pDC->Rectangle(m_aScreenFigures[0]&wr);pDC->Rectangle(m_aScreenFigures[1]&wr);pDC->Rectangle(m_aScreenFigures[2]&wr);pDC->Rectangle(m_aScreenFigures[3]&wr);pDC->SetMapMode(MM_TEXT);//重绘视口DrawRect(pDC,m_ptScreenOrg,m_rcViewportRect);}5.4.2视窗变换实例WindowToViewvoidCChildView::OffsetFigures(CPointoffset){for(inti=0;i<m_aScreenFigures.GetSize();i++)m_aScreenFigures[i].OffsetRect(offset);}CEdit*CChildView::GetEditByID(intid){CMainFrame*pMainFrame=(CMainFrame*)GetParentFrame();return(CEdit*)(pMainFrame->m_wndDialogBar.GetDlgItem(id));}CSpinButtonCtrl*CChildView::GetSpinByID(intid){CMainFrame*pMainFrame=(CMainFrame*)GetParentFrame();return(CSpinButtonCtrl*)(pMainFrame->m_wndDialogBar.GetDlgItem(id));}5.4.2视窗变换实例WindowToViewBOOLCChildView::OnSetCursor(CWnd*pWnd,UINTnHitTest,UINTmessage){//TODO:在此添加消息处理程序代码和/或调用默认值//当光标位于窗口矩形中时变成SIZEALL风格if(m_bIsInWindowRect)SetCursor(LoadCursor(NULL,IDC_SIZEALL));elseSetCursor(LoadCursor(NULL,IDC_ARROW));returnFALSE;}voidCChildView::OnLButtonDown(UINTnFlags,CPointpoint){//TODO:在此添加消息处理程序代码和/或调用默认值m_ptOldPoint=point;//记录左键按下时的位置,用于移动“窗口”CWnd::OnLButtonDown(nFlags,point);}5.4.2视窗变换实例WindowToViewvoidCChildView::OnMouseMove(UINTnFlags,CPointpoint){//TODO:在此添加消息处理程序代码和/或调用默认值CRectwr=m_rcWindowRect;//将wr置为窗口矩形的大小wr.OffsetRect(m_ptWorldOrg);//将wr移到世界坐标系原点,变成在屏幕上的实际位置m_bIsInWindowRect=wr.PtInRect(point);//检查光标是否位于窗口中//当用左键移动了窗口时if(m_bIsInWindowRect&&nFlags&MK_LBUTTON&&point!=m_ptOldPoint){CClientDCdc(this);dc.SetViewportOrg(m_ptWorldOrg);//设置当前原点为世界坐标系原点CRectwr=m_rcWindowRect;wr.InflateRect(2,2);wr.OffsetRect(point-m_ptOldPoint);//移动窗口//检查窗口是否位于世界坐标系中if(m_rcWorldRect.PtInRect(wr.BottomRight())&&m_rcWorldRect.PtInRect(wr.TopLeft())){DrawRect(&dc,m_ptWorldOrg,m_rcWindowRect,R2_NOTXORPEN);//擦除原来的窗口m_rcWindowRect.OffsetRect(point-m_ptOldPoint);//移动窗口DrawRect(&dc,m_ptWorldOrg,m_rcWindowRect,R2_NOTXORPEN);//重画窗口OffsetFigures(m_ptOldPoint-point);//移动屏幕坐标系中的图形DrawFigures(&dc);//重绘屏幕坐标系中的图形m_ptOldPoint=point;//oldpoint变为当前点}}CWnd::OnMouseMove(nFlags,point);}5.4.2视窗变换实例WindowToViewafx_msgvoidCChildView::OnChangeWinWidth(void){CClientDCdc(this);intww=GetSpinByID(IDC_SPINWW)->GetPos();//窗口宽度intwh=m_rcWindowRect.Height();//窗口高度DrawRect(&dc,m_ptWorldOrg,m_rcWindowRect,R2_NOTXORPEN);//擦除原来的窗口OffsetFigures(m_rcWindowRect.CenterPoint());//移动图形//改变窗口大小m_rcWindowRect.left=-ww/2;m_rcWindowRect.right=ww/2;m_rcWindowRect.top=-wh/2;m_rcWindowRect.bottom=wh/2;DrawRect(&dc,m_ptWorldOrg,m_rcWindowRect,R2_NOTXORPEN);//重绘窗口DrawFigures(&dc);//重绘图形}5.4.2视窗变换实例WindowToViewafx_msgvoidCChildView::OnChangeWinHeight(void){CClientDCdc(this);intwh=GetSpinByID(IDC_SPINWH)->GetPos();//窗口宽度intww=m_rcWindowRect.Width();//窗口高度DrawRect(&dc,m_ptWorldOrg,m_rcWindowRect,R2_NOTXORPEN);//擦除原来的窗口OffsetFigures(m_rcWindowRect.CenterPoint());//移动图形//改变窗口大小m_rcWindowRect.left=-ww/2;m_rcWindowRect.right=ww/2;m_rcWindowRect.top=-wh/2;m_rcWindowRect.bottom=wh/2;DrawRect(&dc,m_ptWorldOrg,m_rcWindowRect,R2_NOTXORPEN);//重绘窗口DrawFigures(&dc);//重绘图形}5.4.2视窗变换实例WindowToViewafx_msgvoidCChildView::OnChangeViewWidth(void){CClientDCdc(this);intvw=GetSpinByID(IDC_SPINVW)->GetPos();//视口宽度DrawRect(&dc,m_ptScreenOrg,m_rcViewportRect,R2_COPYPEN,BS_SOLID);//擦除视口中的图形DrawRect(&dc,m_ptScreenOrg,m_rcViewportRect,R2_NOTXORPEN);//重绘视口//改变视口大小m_rcViewportRect.left=-vw/2;m_rcViewportRect.right=vw/2;DrawFigures(&dc);//重绘视口中的图形}5.4.2视窗变换实例WindowToViewafx_msgvoidCChildView::OnChangeViewHeight(void){CClientDCdc(this);intvh=GetSpinByID(IDC_SPINVH)->GetPos();//视口高度DrawRect(&dc,m_ptScreenOrg,m_rcViewportRect,R2_COPYPEN,BS_SOLID);//擦除视口中的图形DrawRect(&dc,m_ptScreenOrg,m_rcViewportRect,R2_NOTXORPEN);//重绘视口//改变视口大小m_rcViewportRect.top=-vh/2;m_rcViewportRect.bottom=vh/2;DrawFigures(&dc);//重绘视口中的图形}5.4.2视窗变换实例WindowToView10.为编辑控件增添消息处理函数 afx_msgvoidOnChangeWinWidth(); afx_msgvoidOnChangeWin

温馨提示

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

评论

0/150

提交评论