图形学实验报告2_第1页
图形学实验报告2_第2页
图形学实验报告2_第3页
图形学实验报告2_第4页
图形学实验报告2_第5页
已阅读5页,还剩14页未读 继续免费阅读

下载本文档

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

文档简介

1、实验二 图形变换与裁减一、实验目的:1、通过本次实验掌握二维图形和三维图形的基本变换算法,及变换矩阵的求法。2、掌握三维图形的投影方法。3、使用Cohen-Sutherland算法裁减二维线段或使用Sutherland-Hodgman算法对多边形进行裁减,验证算法的正确性。二、实验内容:(必做)1、编写一个通用的子程序(如:类或多个函数),其功能可以完成基本二维图形变换(平移、旋转、变比、反射)。通过调用此子程序,实现下列变换:(1)将一平行四边形做平移变换;(2)将平行四边形以原点为中心,以10o为间隔做360o旋转;(3)将一三角形在x和y方向均缩小为原来一半。绘制各种基本图形可以使用系统

2、函数。(必做)2、绘制立方体的平行投影效果图和一点透视效果图。在程序中给出立方体的顶点坐标。视点方向为从z轴正方向看原点,视线平行于z轴。投影面为XOY平面,投影中心位于z轴负轴某点,当改变投影中心位置时,查看一点透视效果的变化。绘制各种基本图形可以使用系统函数。(选做)3、用Cohen-Sutherland算法裁剪二维线段或用Sutherland-Hodgman算法裁剪多边形。要求:输入裁减窗口的四条边坐标,对于Cohen-Sutherland算法裁剪二维线段要输入线段的起点与终点x,y坐标,对于Sutherland-Hodgman算法裁剪多边形要输入多边形的顶点数及各顶点x,y坐标。禁止使

3、用裁减的系统函数。三、实验要求:实验前须规划程序界面和按钮的相关事件的编写代码。实验时进行代码的调试。四、实验代码1,图形的变换/ TransformView.cpp : implementation of the CTransformView class/#include "stdafx.h"#include "Transform.h"#include "TransformDoc.h"#include "TransformView.h"#include <math.h>#ifdef _DEBUG#de

4、fine new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE = _FILE_;#endif/ CTransformViewIMPLEMENT_DYNCREATE(CTransformView, CView)BEGIN_MESSAGE_MAP(CTransformView, CView)/AFX_MSG_MAP(CTransformView)ON_COMMAND(ID_MENU_TRANSFORM_TRANSLATE, OnMenuTransformTranslate)ON_COMMAND(ID_MENU_TRANSFORM_SCALE, On

5、MenuTransformScale)ON_COMMAND(ID_MENU_TRANSFORM_ROTATE, OnMenuTransformRotate)ON_WM_KEYDOWN()/AFX_MSG_MAP/ Standard printing commandsON_COMMAND(ID_FILE_PRINT, CView:OnFilePrint)ON_COMMAND(ID_FILE_PRINT_DIRECT, CView:OnFilePrint)ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView:OnFilePrintPreview)END_MESSAGE_M

6、AP()/ CTransformView construction/destructionCTransformView:CTransformView()/ TODO: add construction code herePt0.x = 200; Pt0.y = 220;Pt1.x = 260; Pt1.y = 300;Pt2.x = 360; Pt2.y = 180;dAngle = 0.0;CTransformView:CTransformView()BOOL CTransformView:PreCreateWindow(CREATESTRUCT& cs)/ TODO: Modify

7、 the Window class or styles here by modifying/ the CREATESTRUCT csreturn CView:PreCreateWindow(cs);/ CTransformView drawingvoid CTransformView:OnDraw(CDC* pDC)CTransformDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);/ TODO: add draw code for native data hereDrawTriangle(pDC);/ CTransformView printingB

8、OOL CTransformView:OnPreparePrinting(CPrintInfo* pInfo)/ default preparationreturn DoPreparePrinting(pInfo);void CTransformView:OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)/ TODO: add extra initialization before printingvoid CTransformView:OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)/

9、TODO: add cleanup after printing/ CTransformView diagnostics#ifdef _DEBUGvoid CTransformView:AssertValid() constCView:AssertValid();void CTransformView:Dump(CDumpContext& dc) constCView:Dump(dc);CTransformDoc* CTransformView:GetDocument() / non-debug version is inlineASSERT(m_pDocument->IsKin

10、dOf(RUNTIME_CLASS(CTransformDoc);return (CTransformDoc*)m_pDocument;#endif /_DEBUG/ CTransformView message handlersvoid CTransformView:DrawTriangle(CDC *pDC)pDC->MoveTo(Pt0);pDC->LineTo(Pt1);pDC->LineTo(Pt2);pDC->LineTo(Pt0);void CTransformView:OnMenuTransformTranslate() / TODO: Add your

11、 command handler code hereint nX = 50; int nY = 80; /平移的X坐标和Y坐标for(int i=0; i<3; i+)Pti.x += nX;Pti.y += nY;RedrawWindow();void CTransformView:OnMenuTransformScale() / TODO: Add your command handler code herefloat dScaleX = 2.0; float dScaleY = 0.5;for(int i=0; i<3; i+)Pti.x *= dScaleX;Pti.y *

12、= dScaleY;RedrawWindow();#define PI 3.1415926void CTransformView:OnMenuTransformRotate() / TODO: Add your command handler code herefloat dRadiusAngle = 30.0 * PI /180.0;for(int i=0; i<3; i+)Pti.x = Pti.x * cos(dRadiusAngle) - Pti.y * sin(dRadiusAngle);Pti.y = Pti.x * sin(dRadiusAngle) + Pti.y * c

13、os(dRadiusAngle);RedrawWindow();void CTransformView:OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) / TODO: Add your message handler code here and/or call defaultint i=0;CPoint TmpPt = Pt0;switch (nChar)case VK_UP:/上for(i=0; i<3; i+)Pti.y -= 5;break;case VK_DOWN:/下for(i=0; i<3; i+)Pti.y += 5;

14、break;case VK_LEFT:/左for(i=0; i<3; i+)Pti.x -= 5;break;case VK_RIGHT:/右for(i=0; i<3; i+)Pti.x += 5;break;case 0X5A:/Z的ASCII码Pt1 = Pt1 - Pt0;Pt2 = Pt2 - Pt0;Pt0.x = Pt0.y = 0;for(i=1; i<3; i+)Pti.x *= 0.5;Pti.y *= 0.5;Pt0 = TmpPt;Pt1 = Pt1 + Pt0;Pt2 = Pt2 + Pt0;break;case 0X58:/X的ASCII码Pt1 =

15、 Pt1 - Pt0;Pt2 = Pt2 - Pt0;Pt0.x = Pt0.y = 0;for(i=1; i<3; i+)Pti.x *= 2.0;Pti.y *= 2.0;Pt0 = TmpPt;Pt1 = Pt1 + Pt0;Pt2 = Pt2 + Pt0;break;case 0X52 : /R的ASCII码dAngle = -1.0;float dRadiusAngle = dAngle * PI /180.0;Pt1 = Pt1 - Pt0;Pt2 = Pt2 - Pt0;Pt0.x = Pt0.y = 0;for(int i=1; i<3; i+)/由于CPoint的

16、x和y坐标值都为正值,所以如果计算出是负值来时,就直接赋0Pti.x = (float)Pti.x * cos(dRadiusAngle) - (float)Pti.y * sin(dRadiusAngle);Pti.y = (float)Pti.x * sin(dRadiusAngle) + (float)Pti.y * cos(dRadiusAngle);Pt0 = TmpPt;Pt1 = Pt1 + Pt0;Pt2 = Pt2 + Pt0;break;RedrawWindow();CView:OnKeyDown(nChar, nRepCnt, nFlags);2、中心投影#include

17、 "stdafx.h"#include "中心投影.h"#include "中心投影Doc.h"#include "中心投影View.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE = _FILE_;#endif#include "math.h"#include "dlg.h"#include "dlgangl.h"#include "point.

18、h"# include < time.h > /时间处理函数原型及数据结构point p10, tp10;int xx;/ CMyViewIMPLEMENT_DYNCREATE(CMyView, CView)BEGIN_MESSAGE_MAP(CMyView, CView)/AFX_MSG_MAP(CMyView)ON_COMMAND(IDC_dai, Ondai)ON_COMMAND(IDD_anypoint, Onanypoint)ON_COMMAND(IDD_any2, Onany2)ON_COMMAND(IDD_anyPmap, OnanyPmap)/AFX_MS

19、G_MAPEND_MESSAGE_MAP()/ CMyView construction/destructionCMyView:CMyView()/ TODO: add construction code hereCMyView:CMyView()BOOL CMyView:PreCreateWindow(CREATESTRUCT& cs)/ TODO: Modify the Window class or styles here by modifying/ the CREATESTRUCT csreturn CView:PreCreateWindow(cs);/ CMyView dra

20、wingvoid CMyView:OnDraw(CDC* pDC)CMyDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);/ TODO: add draw code for native data here/*edge Ed12;face fc6;int a=200;volum v;v.num=12; v.en0=0; v.en1=1; v.en2=2;v.en3=3; v.en4=4; v.en5=5;v.en6=6; v.en7=7; v.en8=8;v.en9=9; v.en10=10; v.en11=11; / pDC->LineTo(10

21、0,100); p0.x=a; p0.y=a; p0.z=a; p1.x=100+a; p1.y=a; p1.z=a; p2.x=100+a; p2.y=100+a; p2.z=a; p3.x=a; p3.y=100+a; p3.z=a; p4.x=a; p4.y=a; p4.z=100+a; p5.x=100+a; p5.y=a; p5.z=100+a; p6.x=100+a; p6.y=100+a; p6.z=100+a; p7.x=a; p7.y=100+a; p7.z=100+a;/ pDC->LineTo(p6.x+100,p6.y); Ed0.sn=0;Ed0.en=1; E

22、d1.sn=1;Ed1.en=2; Ed2.sn=2;Ed2.en=3; Ed3.sn=3;Ed3.en=0; Ed4.sn=4;Ed4.en=5; Ed5.sn=5;Ed5.en=6; Ed6.sn=6;Ed6.en=7; Ed7.sn=7;Ed7.en=4; Ed8.sn=0;Ed8.en=4; Ed9.sn=1;Ed9.en=5; Ed10.sn=2;Ed10.en=6; Ed11.sn=3;Ed11.en=7; double seta=-3.14/6,fai=-3.14/8;double sseta,cseta,sfai,cfai; CString s; sseta=sin(seta)

23、; cseta=cos(seta); sfai=sin(fai); cfai=cos(fai); s.Format("%.2f %.2f %.2f %.2f ",sseta,cseta,sfai,cfai); pDC->TextOut(100,100,s);float xe,ye,ze,x,y,z;int i,j,k,D=600, d=200;long tx,ty; for(i=0;i<8;i+) xe=pi.x*cseta-pi.y*sseta; ye=pi.x*sseta*cfai+ pi.y*cseta*cfai -pi.z*sfai; ze=D-(pi.

24、x*sseta*sfai+ pi.y*cseta*sfai +pi.z*cfai); tpi.x=d*xe/ze;/pi.x; tpi.y=d*ye/ze; /pi.y; int esn,een,ent; for(i=0;i<12;i+) /v.num; i+) esn=Edv.eni.sn; een=Edv.eni.en; tx=tpesn.x; ty=tpesn.y; s.Format("*%d %d %d %d ",esn,een, tx,ty); pDC->TextOut(200+j*30,200+j*20,s); pDC->MoveTo(tx,t

25、y); /要求int tx=tpeen.x; ty=tpeen.y; pDC->LineTo(tx,ty); */ / CMyView diagnostics#ifdef _DEBUGvoid CMyView:AssertValid() constCView:AssertValid();void CMyView:Dump(CDumpContext& dc) constCView:Dump(dc);CMyDoc* CMyView:GetDocument() / non-debug version is inlineASSERT(m_pDocument->IsKindOf(RU

26、NTIME_CLASS(CMyDoc);return (CMyDoc*)m_pDocument;#endif /_DEBUG/ CMyView message handlers/操作步骤: 1. 改变d的大小: 可见z轴向外, / 2。 改变y的大小 ,确定y或x方向/ 3。旋转seita=30, 确定绕z轴转/ 4。旋转fai=90, 确定绕x轴转/ 5. 一起转,看结果void CMyView:MatrixM(array3 Ao,array3 A1,array3 A2) int i,j; / Ao11=A111*A211+A112*A221+ A113*A231+A114*A241; /

27、Ao12=A111*A212+A112*A222+ A113*A232+A114*A242; for(i=1;i<5;i+) for( j=1;j<5;j+) Aoij=A1i1*A21j+A1i2*A22j+ A1i3*A23j+A1i4*A24j;void CMyView:printa(array3 A,int w) int i,j;CString s; CDC *pDC=GetDC(); for(i=1;i<5;i+) s.Format("i:%d, %.3lf ,%.3lf, %.3lf ,%.3lf n",i, Ai1,Ai2,Ai3,Ai4);

28、 pDC->TextOut(50,i*30+w,s); void CMyView:readp() /物心在原点double a=0; p0.x=a-50; p0.y=a-50; p0.z=a-50; p1.x=50+a; p1.y=a-50; p1.z=a-50; p2.x=50+a; p2.y=100+a; p2.z=a-50; p3.x=a-50; p3.y=100+a; p3.z=a-50; p4.x=a-50; p4.y=a-50; p4.z=50+a; p5.x=50+a; p5.y=a-50; p5.z=50+a; p6.x=50+a; p6.y=100+a; p6.z=50

29、+a; p7.x=a-50; p7.y=100+a; p7.z=50+a; void CMyView:Ondai() / TODO: Add your command handler code heredlg dd;dd.DoModal(); /启动对话框CDC *pDC=GetDC();edge Ed12;/face fc6;int a=0;int b=0,yy=0;pDC->SetViewportOrg(200,200);volum v;v.num=12; /体用线来构成,下面是初始化v.en0=0; v.en1=1; v.en2=2;v.en3=3; v.en4=4; v.en5=

30、5;v.en6=6; v.en7=7; v.en8=8;v.en9=9; v.en10=10; v.en11=11; readp();/ pDC->LineTo(p6.x+100,p6.y); /线的初始化 Ed0.sn=0;Ed0.en=1; Ed1.sn=1;Ed1.en=2; Ed2.sn=2;Ed2.en=3; Ed3.sn=3;Ed3.en=0; Ed4.sn=4;Ed4.en=5; Ed5.sn=5;Ed5.en=6; Ed6.sn=6;Ed6.en=7; Ed7.sn=7;Ed7.en=4; Ed8.sn=0;Ed8.en=4; Ed9.sn=1;Ed9.en=5; Ed1

31、0.sn=2;Ed10.en=6; Ed11.sn=3;Ed11.en=7; int e=50; /画坐标 pDC->MoveTo(0+e,0+e); pDC->LineTo(300+e,0+e); pDC->TextOut(300+e,0+e,'x'); pDC->MoveTo(0+e ,0+e); pDC->LineTo(0+e,299+e); pDC->TextOut(0+e,299+e,'y'); pDC->MoveTo(e-1 ,e-1); pDC->LineTo(e+1,e+1); /0点 pDC-&g

32、t;TextOut(e+3,e+3,'0'); / pDC->TextOut(300,5,'x');/float seita=-3.14/6,fai=-3.14/8;float sita,fai; sita=(float)3.14*dd.m_seita/180; fai=(float)3.14*dd.m_fai/180;float ssita,csita,sfai,cfai; CString s; ssita=sin(sita); csita=cos(sita); sfai=sin(fai); cfai=cos(fai); s.Format("%

33、.2f %.2f %.2f %.2f ",ssita,csita,sfai,cfai); pDC->TextOut(100,100,s);float xe,ye,ze,xet,yet,zet,x,y,z;int i,j,k;/,D=400, d=200; /控制视点和投影平面long tx,ty; D=400, d=200; array3 Ao,A1,A2; A111=cfai ; A112=sfai ; A113=0; A114=0; A121=-sfai ; A122=cfai ; A123=0; A124=0; A131=0 ; A132=0 ; A133=1; A134

34、=0; A141=0 ; A142=0 ; A143=0; A144=1; /printa(A1,0); A211=1 ; A212=0 ; A213=0; A214=0; A221=0 ; A222=csita ; A223=ssita; A224=0; A231=0 ; A232=-ssita ; A233=csita; A234=0; A241=0 ; A242=0 ; A243=0; A244=1; /printa(A2,130); / sita for x fai for z /旋转公式:下面是两种旋转的合成 MatrixM(Ao,A1,A2); / printa(Ao,250);

35、AfxMessageBox("stop"); for(i=0;i<12;i+) / z(45)? /* if(sita>0.001 && fai>0.001) /s.Format("i=%d,%.3lf %.3lf",i,sita,fai); AfxMessageBox(s); xe= pi.x*Ao11+pi.y*Ao21+pi.z*Ao31; ye= pi.x*Ao12+pi.y*Ao22+pi.z*Ao32; ze= pi.x*Ao13+pi.y*Ao23+pi.z*Ao33-D; else */ if(fai&g

36、t;0.001) xet= pi.x*cfai -pi.y*sfai; /for z(fai) yet= pi.x*sfai+pi.y*cfai; zet=pi.z; else xet=pi.x; yet=pi.y;zet=pi.z; if( sita>0.001) xe=xet; /pi.x ; /ok for x(sita) ye=-yet* csita -zet*ssita ; ze=(yet*ssita+zet*csita); else xe=xet; ye=yet;ze=zet; ze=ze-D; /* if(sita>0.001) /换次序 xet= pi.x*csit

37、a -pi.y*ssita; /for z(sita) yet= pi.x*ssita+pi.y*csita; zet=pi.z; else xet=pi.x; yet=pi.y;zet=pi.z; if( fai>0.001) xe=xet; /pi.x ; /ok for x(fai) ye=-yet* cfai -zet*sfai ; ze=(yet*sfai+zet*cfai); else xe=xet; ye=yet;ze=zet; ze=ze-D; */ /* xe= pi.x*cfai -pi.y*csita*sfai +pi.z*sfai*ssita; ye= pi.x*

38、sfai+pi.y* csita*cfai+ pi.z* ssita*cfai; ze= pi.y*ssita+pi.z*csita-D; /ok */ /* xe=pi.x*csita-pi.y*ssita; ye=pi.x*ssita*cfai+ pi.y*csita*cfai -pi.z*sfai; ze=D-(pi.x*ssita*sfai+ pi.y*csita*sfai +pi.z*cfai); */ /* 88 /anyp xe=-pi.x*ssita+pi.y*csita; ye=-pi.x*csita*cfai- pi.y*ssita*cfai +pi.z*sfai; ze=

39、-pi.x*csita*sfai- pi.y*ssita*sfai -pi.z*cfai+D; */ tpi.x=d*xe/ze; /pi.x; /透视 tpi.y=d*ye/ze; /pi.y; int esn,een,ent; /e为了移动出来看得清楚 for(i=0;i<12;i+) /v.num; i+) esn=Edv.eni.sn; een=Edv.eni.en; tx=tpesn.x; ty=tpesn.y; / s.Format("i:%d,No:%d %d x:%d y:%d ",i,esn,esn, tx,ty);/ pDC->TextOut

40、(200+i*30,200+i*20,s); pDC->MoveTo(tx+e,ty+e); /要求int tx=tpeen.x; ty=tpeen.y;/ s.Format("i:%d,No:%d %d x:%d y:%d ",i,een,een, tx,ty);/ pDC->TextOut(300+i*30,300+i*20,s); pDC->LineTo(tx+e,ty+e); / AfxMessageBox("OK"); /* /饶annypoing rotolvoid print(CDC *pDC, CPoint p) pDC

41、->MoveTo(p0); for(int i=0;i<3;i+) pDC->LineTo(pi); pDC->LineTo(p0);void CMyView:Onanypoint() int tx=0,ty=20; dlgangl dg; /dg.DoModal(); float q=90*3.14159/180,y1,y2; /cosq=0;sinq=1; / q=dg.m_ang; /q=q*3.14159/180; CDC *pDC=GetDC(); pDC->SetWindowOrg(-200,-200);/pDC->SetViewportOrg(

42、+200,+200); CPoint p3= CPoint (100,100),CPoint(200,100),CPoint(150,150),pt3; pDC->MoveTo(0,0);pDC->LineTo(1,1); pDC->TextOut(2,2,"0") ; pDC->MoveTo(tx,ty);pDC->LineTo(tx+1,ty+1); pDC->TextOut(tx+2,ty+2,"T") ; print(pDC,p); for(int i=0;i<3;i+) y1=tx*(1-cos(q)+

43、ty*sin(q); y2=tx*sin(q)+ty*(1-cos(q); pti.x=pi.x*cos(q)-pi.y*sin(q)+y1 ; pti.y=pi.x*sin(q)+pi.y*cos(q)-y2 ; print(pDC,pt); void CMyView:Onany2() int tx=0,ty=20; dlgangl dg; /dg.DoModal(); float q=90*3.14159/180; /cosq=0;sinq=1; / q=dg.m_ang; /q=q*3.14159/180; CDC *pDC=GetDC(); pDC->SetWindowOrg(-

44、200,-200); CPoint p3= CPoint (100,100),CPoint(200,100),CPoint(150,150),pt3; pDC->MoveTo(0,0);pDC->LineTo(1,1); pDC->TextOut(2,2,"0") ; pDC->MoveTo(tx,ty);pDC->LineTo(tx+1,ty+1); pDC->TextOut(tx+2,ty+2,"T"); print(pDC,p); for(int i=0;i<3;i+) pti.x=pi.x*cos(q)-

45、pi.y*sin(q)+tx*(1-cos(q)-ty*sin(q) ; pti.y=pi.x*sin(q)+pi.y*cos(q)+tx*sin(q)+ty*(1-cos(q) ; print(pDC,pt); /* /任意点出发的正投影/void CMyView:OnanyPmap() CDC *pDC=GetDC();edge Ed12; point pt10;int yy=0;dlg dd;dd.DoModal(); /启动对话框int dx=dd.m_x,dy=dd.m_y,dz=dd.m_z;pDC->SetViewportOrg(200,200);volum V;V.num=12; /体用线来构成,下面是初始化V.en0=0; V.en1=1; V.en2=2;V.en3=3; V.en4=4; V.en5=5;V.en6=6; V.en7=7;

温馨提示

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

评论

0/150

提交评论