图形学实验报告2分解.docx
《图形学实验报告2分解.docx》由会员分享,可在线阅读,更多相关《图形学实验报告2分解.docx(24页珍藏版)》请在冰豆网上搜索。
图形学实验报告2分解
实验二图形变换与裁减
一、实验目的:
1、通过本次实验掌握二维图形和三维图形的基本变换算法,及变换矩阵的求法。
2、掌握三维图形的投影方法。
3、使用Cohen-Sutherland算法裁减二维线段或使用Sutherland-Hodgman算法对多边形进行裁减,验证算法的正确性。
二、实验内容:
(必做)1、编写一个通用的子程序(如:
类或多个函数),其功能可以完成基本二维图形变换(平移、旋转、变比、反射)。
通过调用此子程序,实现下列变换:
(1)将一平行四边形做平移变换;
(2)将平行四边形以原点为中心,以10o为间隔做360o旋转;(3)将一三角形在x和y方向均缩小为原来一半。
绘制各种基本图形可以使用系统函数。
(必做)2、绘制立方体的平行投影效果图和一点透视效果图。
在程序中给出立方体的顶点坐标。
视点方向为从z轴正方向看原点,视线平行于z轴。
投影面为XOY平面,投影中心位于z轴负轴某点,当改变投影中心位置时,查看一点透视效果的变化。
绘制各种基本图形可以使用系统函数。
(选做)3、用Cohen-Sutherland算法裁剪二维线段或用Sutherland-Hodgman算法裁剪多边形。
要求:
输入裁减窗口的四条边坐标,对于Cohen-Sutherland算法裁剪二维线段要输入线段的起点与终点x,y坐标,对于Sutherland-Hodgman算法裁剪多边形要输入多边形的顶点数及各顶点x,y坐标。
禁止使用裁减的系统函数。
三、实验要求:
实验前须规划程序界面和按钮的相关事件的编写代码。
实验时进行代码的调试。
四、实验代码
1,图形的变换
//TransformView.cpp:
implementationoftheCTransformViewclass
//
#include"stdafx.h"
#include"Transform.h"
#include"TransformDoc.h"
#include"TransformView.h"
#include
#ifdef_DEBUG
#definenewDEBUG_NEW
#undefTHIS_FILE
staticcharTHIS_FILE[]=__FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
//CTransformView
IMPLEMENT_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,OnMenuTransformScale)
ON_COMMAND(ID_MENU_TRANSFORM_ROTATE,OnMenuTransformRotate)
ON_WM_KEYDOWN()
//}}AFX_MSG_MAP
//Standardprintingcommands
ON_COMMAND(ID_FILE_PRINT,CView:
:
OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT,CView:
:
OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW,CView:
:
OnFilePrintPreview)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
//CTransformViewconstruction/destruction
CTransformView:
:
CTransformView()
{
//TODO:
addconstructioncodehere
Pt[0].x=200;Pt[0].y=220;
Pt[1].x=260;Pt[1].y=300;
Pt[2].x=360;Pt[2].y=180;
dAngle=0.0;
}
CTransformView:
:
~CTransformView()
{
}
BOOLCTransformView:
:
PreCreateWindow(CREATESTRUCT&cs)
{
//TODO:
ModifytheWindowclassorstylesherebymodifying
//theCREATESTRUCTcs
returnCView:
:
PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
//CTransformViewdrawing
voidCTransformView:
:
OnDraw(CDC*pDC)
{
CTransformDoc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
//TODO:
adddrawcodefornativedatahere
DrawTriangle(pDC);
}
/////////////////////////////////////////////////////////////////////////////
//CTransformViewprinting
BOOLCTransformView:
:
OnPreparePrinting(CPrintInfo*pInfo)
{
//defaultpreparation
returnDoPreparePrinting(pInfo);
}
voidCTransformView:
:
OnBeginPrinting(CDC*/*pDC*/,CPrintInfo*/*pInfo*/)
{
//TODO:
addextrainitializationbeforeprinting
}
voidCTransformView:
:
OnEndPrinting(CDC*/*pDC*/,CPrintInfo*/*pInfo*/)
{
//TODO:
addcleanupafterprinting
}
/////////////////////////////////////////////////////////////////////////////
//CTransformViewdiagnostics
#ifdef_DEBUG
voidCTransformView:
:
AssertValid()const
{
CView:
:
AssertValid();
}
voidCTransformView:
:
Dump(CDumpContext&dc)const
{
CView:
:
Dump(dc);
}
CTransformDoc*CTransformView:
:
GetDocument()//non-debugversionisinline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CTransformDoc)));
return(CTransformDoc*)m_pDocument;
}
#endif//_DEBUG
/////////////////////////////////////////////////////////////////////////////
//CTransformViewmessagehandlers
voidCTransformView:
:
DrawTriangle(CDC*pDC)
{
pDC->MoveTo(Pt[0]);
pDC->LineTo(Pt[1]);
pDC->LineTo(Pt[2]);
pDC->LineTo(Pt[0]);
}
voidCTransformView:
:
OnMenuTransformTranslate()
{
//TODO:
Addyourcommandhandlercodehere
intnX=50;
intnY=80;//平移的X坐标和Y坐标
for(inti=0;i<3;i++)
{
Pt[i].x+=nX;
Pt[i].y+=nY;
}
RedrawWindow();
}
voidCTransformView:
:
OnMenuTransformScale()
{
//TODO:
Addyourcommandhandlercodehere
floatdScaleX=2.0;
floatdScaleY=0.5;
for(inti=0;i<3;i++)
{
Pt[i].x*=dScaleX;
Pt[i].y*=dScaleY;
}
RedrawWindow();
}
#definePI3.1415926
voidCTransformView:
:
OnMenuTransformRotate()
{
//TODO:
Addyourcommandhandlercodehere
floatdRadiusAngle=30.0*PI/180.0;
for(inti=0;i<3;i++)
{
Pt[i].x=Pt[i].x*cos(dRadiusAngle)-Pt[i].y*sin(dRadiusAngle);
Pt[i].y=Pt[i].x*sin(dRadiusAngle)+Pt[i].y*cos(dRadiusAngle);
}
RedrawWindow();
}
voidCTransformView:
:
OnKeyDown(UINTnChar,UINTnRepCnt,UINTnFlags)
{
//TODO:
Addyourmessagehandlercodehereand/orcalldefault
inti=0;
CPointTmpPt=Pt[0];
switch(nChar){
caseVK_UP:
//上
for(i=0;i<3;i++)
{
Pt[i].y-=5;
}
break;
caseVK_DOWN:
//下
for(i=0;i<3;i++)
{
Pt[i].y+=5;
}
break;
caseVK_LEFT:
//左
for(i=0;i<3;i++)
{
Pt[i].x-=5;
}
break;
caseVK_RIGHT:
//右
for(i=0;i<3;i++)
{
Pt[i].x+=5;
}
break;
case0X5A:
//Z的ASCII码
Pt[1]=Pt[1]-Pt[0];
Pt[2]=Pt[2]-Pt[0];
Pt[0].x=Pt[0].y=0;
for(i=1;i<3;i++)
{
Pt[i].x*=0.5;
Pt[i].y*=0.5;
}
Pt[0]=TmpPt;
Pt[1]=Pt[1]+Pt[0];
Pt[2]=Pt[2]+Pt[0];
break;
case0X58:
//X的ASCII码
Pt[1]=Pt[1]-Pt[0];
Pt[2]=Pt[2]-Pt[0];
Pt[0].x=Pt[0].y=0;
for(i=1;i<3;i++)
{
Pt[i].x*=2.0;
Pt[i].y*=2.0;
}
Pt[0]=TmpPt;
Pt[1]=Pt[1]+Pt[0];
Pt[2]=Pt[2]+Pt[0];
break;
case0X52:
//R的ASCII码
dAngle=-1.0;
floatdRadiusAngle=dAngle*PI/180.0;
Pt[1]=Pt[1]-Pt[0];
Pt[2]=Pt[2]-Pt[0];
Pt[0].x=Pt[0].y=0;
for(inti=1;i<3;i++)//由于CPoint的x和y坐标值都为正值,所以如果计算出是负值来时,就直接赋0
{
Pt[i].x=(float)Pt[i].x*cos(dRadiusAngle)-(float)Pt[i].y*sin(dRadiusAngle);
Pt[i].y=(float)Pt[i].x*sin(dRadiusAngle)+(float)Pt[i].y*cos(dRadiusAngle);
}
Pt[0]=TmpPt;
Pt[1]=Pt[1]+Pt[0];
Pt[2]=Pt[2]+Pt[0];
break;
}
RedrawWindow();
CView:
:
OnKeyDown(nChar,nRepCnt,nFlags);
}
2、中心投影
#include"stdafx.h"
#include"中心投影.h"
#include"中心投影Doc.h"
#include"中心投影View.h"
#ifdef_DEBUG
#definenewDEBUG_NEW
#undefTHIS_FILE
staticcharTHIS_FILE[]=__FILE__;
#endif
#include"math.h"
#include"dlg.h"
#include"dlgangl.h"
#include"point.h"
#include//时间处理函数原型及数据结构
pointp[10],tp[10];
intxx;
/////////////////////////////////////////////////////////////////////////////
//CMyView
IMPLEMENT_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_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
//CMyViewconstruction/destruction
CMyView:
:
CMyView()
{
//TODO:
addconstructioncodehere
}
CMyView:
:
~CMyView()
{
}
BOOLCMyView:
:
PreCreateWindow(CREATESTRUCT&cs)
{
//TODO:
ModifytheWindowclassorstylesherebymodifying
//theCREATESTRUCTcs
returnCView:
:
PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
//CMyViewdrawing
voidCMyView:
:
OnDraw(CDC*pDC)
{
CMyDoc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
//TODO:
adddrawcodefornativedatahere
/*edgeEd[12];
facefc[6];
inta=200;
volumv;
v.num=12;
v.en[0]=0;v.en[1]=1;v.en[2]=2;
v.en[3]=3;v.en[4]=4;v.en[5]=5;
v.en[6]=6;v.en[7]=7;v.en[8]=8;
v.en[9]=9;v.en[10]=10;v.en[11]=11;
//pDC->LineTo(100,100);
p[0].x=a;p[0].y=a;p[0].z=a;
p[1].x=100+a;p[1].y=a;p[1].z=a;
p[2].x=100+a;p[2].y=100+a;p[2].z=a;
p[3].x=a;p[3].y=100+a;p[3].z=a;
p[4].x=a;p[4].y=a;p[4].z=100+a;
p[5].x=100+a;p[5].y=a;p[5].z=100+a;
p[6].x=100+a;p[6].y=100+a;p[6].z=100+a;
p[7].x=a;p[7].y=100+a;p[7].z=100+a;
//pDC->LineTo(p[6].x+100,p[6].y);
Ed[0].sn=0;Ed[0].en=1;
Ed[1].sn=1;Ed[1].en=2;
Ed[2].sn=2;Ed[2].en=3;
Ed[3].sn=3;Ed[3].en=0;
Ed[4].sn=4;Ed[4].en=5;
Ed[5].sn=5;Ed[5].en=6;
Ed[6].sn=6;Ed[6].en=7;
Ed[7].sn=7;Ed[7].en=4;
Ed[8].sn=0;Ed[8].en=4;
Ed[9].sn=1;Ed[9].en=5;
Ed[10].sn=2;Ed[10].en=6;
Ed[11].sn=3;Ed[11].en=7;
doubleseta=-3.14/6,fai=-3.14/8;
doublesseta,cseta,sfai,cfai;
CStrings;
sseta=sin(seta);cseta=cos(seta);
sfai=sin(fai);cfai=cos(fai);
s.Format("%.2f%.2f%.2f%.2f",sseta,cseta,sfai,cfai);
pDC->TextOut(100,100,s);
floatxe,ye,ze,x,y,z;
inti,j,k,D=600,d=200;
longtx,ty;
for(i=0;i<8;i++)
{xe=p[i].x*cseta-p[i].y*sseta;
ye=p[i].x*sseta*cfai+p[i].y*cseta*cfai-p[i].z*sfai;
ze=D-(p[i].x*sseta*sfai+p[i].y*cseta*sfai+p[i].z*cfai);
tp[i].x=d*xe/ze;//p[i].x;
tp[i].y=d*ye/ze;//p[i].y;
}
intesn,een,ent;
for(i=0;i<12;i++)//v.num;i++)
{
esn=Ed[v.en[i]].sn;
een=Ed[v.en[i]].en;
tx=tp[esn].x;
ty=tp[esn].y;
s.Format("**%d%d%d%d",esn,een,tx,ty);
pDC->TextOut(200+j*30,200+j*20,s);
pDC->MoveTo(tx,ty);//要求int
tx=tp[een].x;
ty=tp[een].y;
pDC->LineTo(tx,ty);
}
*/
}
/////////////////////////////////////////////////////////////////////////////
//CMyViewdiagnostics
#ifdef_DEBUG
voidCMyView:
:
AssertValid()const
{
CView:
:
AssertValid();
}
voidCMyView:
:
Dump(CDumpContext&dc)const
{
CView:
:
Dump(dc);
}
CMyDoc*CMyView:
:
GetDocument()//non-debugversionisinline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMyDoc)));
return(CMyDoc*)m_pDocument;
}
#endif//_DEBUG
/////////////////////////////////////////////////////////////////////////////
//CMyViewmessagehandlers
//操作步骤:
1.改变d的大小:
可见z轴向外,
//2。
改变y的大小,确定y或x方向
//3。
旋转seita=30,确定绕z轴转
//4。
旋转fai=90,确定绕x轴转
//5.一起转,看结果
voidCMyView:
:
MatrixM(array3Ao,array3A1,array3A2)
{inti,j;
//Ao[1][1]=A1[1][1]*A2[1][1]+A1[1]