二维图形几何变换实验报告.docx
- 文档编号:4366993
- 上传时间:2022-11-30
- 格式:DOCX
- 页数:16
- 大小:213.46KB
二维图形几何变换实验报告.docx
《二维图形几何变换实验报告.docx》由会员分享,可在线阅读,更多相关《二维图形几何变换实验报告.docx(16页珍藏版)》请在冰豆网上搜索。
二维图形几何变换实验报告
计算机图形学实验报告
实验4二维图形几何变换
一实验目的
1)掌握3*3矩阵乘法运算的编程实现:
2)掌握平移、比例、旋转三种基本二维几何变换矩阵生成:
3)掌握相对于任意参考点的二维复合变换矩阵生成。
二实验要求
1)设计实现二维图形变换类,具有平移、比例、旋转二维几何变换功能,以及相对于任意参考点的二维复合变换功能;
2)将2.2节直线类所绘制的如图2-3所示的菱形线框,绕最上端A点匀速旋转,并要求相对于A点来回缩放。
3)使用双缓冲机制进行图形绘制,避免运动闪烁,所有图形先绘制到用户自定的DC,绘制完成后再统一拷贝到屏幕DC。
三实验步骤
第1步:
打开2.2节(实验2)工程文件
直接使用2.2节(实验2)的MFC项目工程,及其中的直线类CLine.
第2步:
二维点类CP2添加齐次坐标
在“Line.h/cpp”文件中的二维点类CP2的相关代码中添加齐次坐标,修改后的CP2类代码如下(带底纹部分为添加的代码)。
“Line.h”中相关代码
classCP2
{
public:
CP2();
virtual~CP2();
CP2(double,double);
public:
doublex;
doubley;
doublew;
};
classCLine
{
public:
CLine();
virtual~CLine();
voidSetLineColor(COLORREF);
voidMoveTo(CP2);
voidMoveTo(double,double);
voidLineTo(CP2,CDC*);
voidLineTo(double,double,CDC*);
public:
CP2P0;
CP2P1;
COLORREFclr;
};
=====================================================================
Line.cpp
#include"stdafx.h"
#include"Line.h"
#include"math.h"
#defineRound(d)int(floor(d+0.5))
CP2:
:
CP2()
{
x=0.0;
y=0.0;
w=1.0;
}
CP2:
:
~CP2()
{}
CP2:
:
CP2(doublex,doubley)
{
this->x=x;
this->y=y;
this->w=1;
}
CLine:
:
CLine()
{}
CLine:
:
~CLine()
{}
voidCLine:
:
SetLineColor(COLORREFcolor)
{
clr=color;
}
voidCLine:
:
MoveTo(CP2p0)
{
P0=p0;
}
voidCLine:
:
MoveTo(doublex,doubley)
{
P0.x=x;
P0.y=y;
}
voidCLine:
:
LineTo(doublex,doubley,CDC*pDC)
{
CP2p;
p.x=x;
p.y=y;
LineTo(p,pDC);
}
voidCLine:
:
LineTo(CP2p1,CDC*pDC)
{
P1=p1;
CP2p,t;
if(fabs(P0.x-P1.x)<1e-6)
{
if(P0.y>P1.y)
{
t=P0;P0=P1;P1=t;
}
for(p=P0;p.y { pDC->SetPixelV(Round(p.x),Round(p.y),clr); } } else { doublek,d; k=(P1.y-P0.y)/(P1.x-P0.x); if(k>1.0) { if(P0.y>P1.y) { t=P0;P0=P1;P1=t; } d=1-0.5*k; for(p=P0;p.y { pDC->SetPixelV(Round(p.x),Round(p.y),clr); if(d>=0) { p.x++; d+=1-k; } else d+=1; } } if(0.0<=k&&k<=1.0) { if(P0.x>P1.x) { t=P0;P0=P1;P1=t; } d=0.5-k; for(p=P0;p.x { pDC->SetPixelV(Round(p.x),Round(p.y),clr); if(d<0) { p.y++; d+=1-k; } else d-=k; } } if(k>=-1.0&&k<0.0) { if(P0.x>P1.x) { t=P0;P0=P1;P1=t; } d=-0.5-k; for(p=P0;p.x { pDC->SetPixelV(Round(p.x),Round(p.y),clr); if(d>0) { p.y--; d-=1+k; } else d-=k; } } if(k<-1.0) { if(P0.y { t=P0;P0=P1;P1=t; } d=-1-0.5*k; for(p=P0;p.y>P1.y;p.y--) { pDC->SetPixelV(Round(p.x),Round(p.y),clr); if(d<0) { p.x++; d-=1+k; } else d-=1; } } } P0=p1; } 第3步 (1)二维图形几何变换矩阵 ➢平移变换矩阵: T1= ➢旋转变换矩阵 Tr= ➢比例变换矩阵 Ts= ➢相对于任意参考点的旋转变换矩阵 T(fr)= * * ➢相对于任意参考点的比例变换矩阵 T(fs)= * * (2)新建二维图形几何变换类CTrans2D头文件 ➢在"FieView (解决方案资源管理器》”视图中,选中”HeaderFiles”文件夹。 ➢选择菜单Fie>New",弹出图所示对话框,默认在Files选项卡中。 左侧类型框里选中”C/C++ Headr File";, 右边确定"Addaproject”然后填写”File”下的文件名称“CTrans2D”。 ➢设置完成后, 点击“OK”即可自动新建“CTrans2D.h"空头文件。 成员变量应包括记录图形变换顶点的二维顶点数组和记录顶点个数的整数,成员函数应包括3*3矩阵乘法运算函数,变换矩阵重置函数,平移、比例、旋转二维变换函数,以及相对于任意参考点的二维复合变换函数。 “CTrans2D.h”头文件中具体类型声明代码如下: CTrans2D.h #pragmaonce #include"Line.h" classCTrans2D { public: CTrans2D(); virtual~CTrans2D(); voidSetPoints(CP2*,int); voidIdentity(); voidTranslate(double,double); voidRotate(double); voidScale(double,double); voidRotatePoint(double,CP2); voidScalePoint(double,double,CP2); protected: voidMultiMatrix(); public: doublem_aT[3][3]; CP2*m_pPoints; intm_iNum; }; (3)新建二维图形几何变换类CTrans2D源文件 ➢在"FileView(解决方案资源管理器)”视图中,选中“Source Files”文件夹。 ➢选择菜单"File->New”, 弹出图所示对话框,默认在“Files”选项卡。 左侧类型 框里选中“C/C++ Source File";右边确定“Add to project”被勾选,然后填写"File"下的文件名称“CTrans2D”(需与头文件一致)。 ➢设置完成后,点击“OK"即可自动新建“CTrans2D.cpp”空源文件。 CTransD.cpp”源文件中具体实现代码如下: CTrans2D.cpp #include"stdafx.h" #include"CTrans2D.h" #include"math.h" #defineIP3.14159 CTrans2D: : CTrans2D() {} CTrans2D: : ~CTrans2D() {} voidCTrans2D: : SetPoints(CP2*p,intn) { m_pPoints=p; m_iNum=n; } voidCTrans2D: : Identity() { m_aT[0][0]=1.0;m_aT[0][1]=0.0;m_aT[0][2]=0.0; m_aT[1][0]=0.0;m_aT[1][1]=1.0;m_aT[1][2]=0.0; m_aT[2][0]=0.0;m_aT[2][1]=0.0;m_aT[2][2]=1.0; } voidCTrans2D: : Translate(doubletx,doublety) { Identity(); m_aT[2][0]=tx; m_aT[2][1]=ty; MultiMatrix(); } voidCTrans2D: : Rotate(doublebeta) { Identity(); doublerad=beta*IP/180; m_aT[0][0]=cos(rad);m_aT[0][1]=sin(rad); m_aT[1][0]=sin(rad);m_aT[1][1]=cos(rad); MultiMatrix(); } voidCTrans2D: : Scale(doublesx,doublesy) { Identity(); m_aT[0][0]=sx; m_aT[1][1]=sy; MultiMatrix(); } voidCTrans2D: : RotatePoint(doublebeta,CP2p) { Translate(-p.x,-p.y); Rotate(beta); Translate(p.x,p.y); } voidCTrans2D: : ScalePoint(doublesx,doublesy,CP2p) { Translate(-p.x,-p.y); Scale(sx,sy); Translate(p.x,p.y); } voidCTrans2D: : MultiMatrix() { CP2*PNew=newCP2[m_iNum]; for(inti=0;i { PNew[i]=m_pPoints[i]; } for(intj=0;j { m_pPoints[j].x=PNew[j].x*m_aT[0][0]+PNew[j].y*m_aT[1][0]+PNew[j].w*m_aT[2][0]; m_pPoints[j].y=PNew[j].x*m_aT[0][1]+PNew[j].y*m_aT[1][1]+PNew[j].w*m_aT[2][1]; m_pPoints[j].w=PNew[j].x*m_aT[0][2]+PNew[j].y*m_aT[1][2]+PNew[j].w*m_aT[2][2]; } delete[]PNew; } 第3步: 调用二维图形几何变换类转动、缩放菱形线框图 直接在CTestView: : OnDraw ()函数中进行菱形线框图的填充,只需新建CFillPoly类对象,设置顶点序列为菱形的ABCD顶点,并设置合适的填充色给顶点数据,按照有效边表填充算法实现步骤依次调用成员函数即可。 具体实现代码如下(带底纹部分为修改添加的代码): #include"CTrans2D.h" voidCTestsView: : OnDraw(CDC*pDC) { CTestsDoc*pDoc=GetDocument(); ASSERT_VALID(pDoc); //TODO: adddrawcodefornativedatahere CRectrect; GetClientRect(&rect); pDC->SetMapMode(MM_ANISOTROPIC); pDC->SetWindowExt(rect.Width(),rect.Height()); pDC->SetViewportExt(rect.Width(),-rect.Height()); pDC->SetViewportOrg(rect.Width()/2,rect.Height()/2); CDCMemDC; CBitmapNewBitmap,*pOldBitmap; MemDC.CreateCompatibleDC(pDC); NewBitmap.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height()); pOldBitmap=MemDC.SelectObject(&NewBitmap); MemDC.FillSolidRect(rect,pDC->GetBkColor()); MemDC.SetMapMode(MM_ANISOTROPIC); MemDC.SetWindowExt(rect.Width(),rect.Height()); MemDC.SetViewportExt(rect.Width(),-rect.Height()); MemDC.SetViewportOrg(rect.Width()/2,rect.Height()/2); CLine*line=newCLine; line->SetLineColor(RGB(0,0,0)); line->MoveTo(CP2(-rect.Width()/2,0)); line->LineTo(CP2(rect.Width()/2,0),&MemDC); line->MoveTo(CP2(0,-rect.Width()/2,0)); line->LineTo(CP2(0,rect.Width()/2),&MemDC); inta=200; CP2points[4]; points[0].x=0,points[0].y=a; points[1].x=a,points[1].y=0; points[2].x=0,points[2].y=-a; points[3].x=-a,points[3].y=0; CP2A(0,a) CTrans2Dtans; tans.SetPoints(points,4); staticfloats=1.0; staticfloatstep=0.01; if(s>=2.0||s<=0.5) step=-step; tans.ScalePoint(s,s,A); staticfloattheta=0.0; theta+=1.0; if(theta>=360.0) theta=0.0; tans.RotatePoint(theta,A); line->SetLineColor(RGB(0,55,199)); line->MoveTo(points[0]); line->LineTo(points[1],&MemDC); line->SetLineColor(RGB(90,55,0)); line->LineTo(points[2],&MemDC); line->SetLineColor(RGB(10,0,0)); line->LineTo(points[3],&MemDC); line->SetLineColor(RGB(50,200,0)); line->LineTo(points[0],&MemDC); deleteline; pDC->BitBlt(-rect.Width()/2,-rect.Height()/2,rect.Width(),rect.Height(),&MemDC,-rect.Width()/2,-rect.Height()/2,SRCCOPY); MemDC.SelectObject(pOldBitmap); NewBitmap.DeleteObject(); Invalidate(FALSE); s+=step;. tans.ScalePoint(s,s,A); staticfloattheta=0.0; theta+=1.0; if(theta>=360.0) theta=0.0; tans.RotatePoint(theta,A); line->SetLineColor(RGB(255,0,0)); line->MoveTo(points[0]); line->LineTo(points[1],&MemDC); line->SetLineColor(RGB(0,255,0)); line->LineTo(points[2],&MemDC); line->SetLineColor(RGB(0,255,0)); line->LineTo(points[3],&MemDC); line->SetLineColor(RGB(0,255,0)); line->LineTo(points[0],&MemDC); deleteline; //将内存位图拷贝到屏幕 pDC->BitBlt(-rect.Width()/2,-rect.Height()/2,rect.Width(),rect.Height(),&MemDC,-rect.Width()/2,-rect.Height()/2,SRCCOPY); MemDC.SelectObject(pOldBitmap); NewBitmap.DeleteObject(); Invalidate(FALSE); 四实验结果 五总结与讨论 二维图形几何变换实验中需要用到第二次试验直线扫描算法,是在这次实验的基础上进行的,二维图形几何变换十分神奇,在试验期间,又让我认识到矩阵在各方面的强大作用和神奇之处。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 二维 图形 几何 变换 实验 报告
![提示](https://static.bdocx.com/images/bang_tan.gif)