计算机图形学上机实验09Word文档格式.docx
《计算机图形学上机实验09Word文档格式.docx》由会员分享,可在线阅读,更多相关《计算机图形学上机实验09Word文档格式.docx(13页珍藏版)》请在冰点文库上搜索。
4.MFC图形编程框架
三、实验步骤
实验二基本2D图形填充算法和坐标变换
1.掌握扫描线多边形填充算法、种子填充算法等的基本原理和计算机实现填充功能。
2.掌握在齐次坐标系中进行二维基本线性变换(平移、比例、旋转、错切)的原理、性质、表示方法及应用。
多边形填充算法、种子填充算法
二维基本线性变换(平移、比例、旋转、错切等)
1、创建应用程序框架,本例以单文档框架为例。
2、编辑菜单资源
在工作区的【ResourceView】标签中,单击Menu项左边的“+”,然后双击其子项IDR_MAINFRAME,并根据下图和下图添加编辑菜单资源。
菜单标题
菜单项标题
标识符ID
区域填充
种子填充算法
ID_FLOODFILL
边界填充算法
ID_BOUNDARY
扫描线多边形填充算法
ID_SCANLINEFILL
3、添加菜单项消息处理函数
利用ClassWizard(建立类向导)为应用程序添加与菜单项相关的消息处理函数,ClassName栏中选择CmyView,根据下表建立如下的消息映射函数,ClassWizard会自动生成有关的函数声明。
菜单项ID
消息
消息处理函数
COMMAND
OnFloodfill
OnBoundary
OnScanlinefill
4、添加程序代码
Ø
在OnDraw()函数中添加如下蓝色字体部分代码。
voidCMyView:
:
OnDraw(CDC*pDC)
{
CMyDoc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
//TODO:
adddrawcodefornativedatahere
pDC->
TextOut(20,20,"
双击鼠标左键,出现需填充的多边形,点击相关功能菜单实现区域填充"
);
TextOut(20,50,"
进行种子填充,需用鼠标右键,单击多边形内一点,作为开始填充的种子点"
}
添加鼠标消息处理函数:
利用ClassWizard(建立类向导)为应用程序添加与鼠标相关的消息处理函数,ClassName栏中选择CmyView,根据下表建立如下的鼠标消息映射函数,ClassWizard会自动生成有关的函数声明。
ObjectIDs
CmyView
WM_LBUTTONDBLCLK
OnLButtonDblClk
WM_RBUTTONDOWN
OnRButtonDown
分别给鼠标消息映射函数添加如下代码:
OnLButtonDblClk(UINTnFlags,CPointpoint)
Addyourmessagehandlercodehereand/orcalldefault
RedrawWindow();
CDC*pDC=GetDC();
CPennewpen(PS_SOLID,1,RGB(255,0,0));
CPen*old=pDC->
SelectObject(&
newpen);
Rectangle(100,100,200,200);
SelectObject(old);
ReleaseDC(pDC);
CView:
OnLButtonDblClk(nFlags,point);
OnRButtonDown(UINTnFlags,CPointpoint)
a_point=point;
//a_point为点类对象,表示种子点,定义为CmyView类的数据成员。
OnRButtonDown(nFlags,point);
给CmyView类添加各种填充的函数成员:
voidboundary_fill_4(CDC*pDC,intx,inty,COLORREFboundary_Color,COLORREFnew_Color);
voidFlood_Fill_4(CDC*pDC,intx,inty,COLORREFold_Color,COLORREFnew_Color);
voidscanLineFill4(CDC*pDC,intxseed,intyseed,COLORREFoldColor,COLORREFfillColor);
boundary_fill_4(CDC*pDC,intx,inty,COLORREFboundary_Color,COLORREFnew_Color)
COLORREFcent=pDC->
GetPixel(CPoint(x,y));
staticDWORDdwCount=0;
if(cent!
=boundary_Color&
&
cent!
=new_Color)
pDC->
SetPixel(CPoint(x,y),new_Color);
boundary_fill_4(pDC,x,y+1,boundary_Color,new_Color);
boundary_fill_4(pDC,x,y-1,boundary_Color,new_Color);
boundary_fill_4(pDC,x-1,y,boundary_Color,new_Color);
boundary_fill_4(pDC,x+1,y,boundary_Color,new_Color);
boundary_fill_4(pDC,x-1,y+1,boundary_Color,new_Color);
boundary_fill_4(pDC,x+1,y-1,boundary_Color,new_Color);
boundary_fill_4(pDC,x+1,y+1,boundary_Color,new_Color);
boundary_fill_4(pDC,x-1,y-1,boundary_Color,new_Color);
dwCount++;
}
Flood_Fill_4(CDC*pDC,intx,inty,COLORREFold_Color,COLORREFnew_Color)
if(cent==old_Color&
Flood_Fill_4(pDC,x,y+1,old_Color,new_Color);
Flood_Fill_4(pDC,x,y-1,old_Color,new_Color);
Flood_Fill_4(pDC,x-1,y,old_Color,new_Color);
Flood_Fill_4(pDC,x+1,y,old_Color,new_Color);
Flood_Fill_4(pDC,x-1,y+1,old_Color,new_Color);
Flood_Fill_4(pDC,x+1,y+1,old_Color,new_Color);
Flood_Fill_4(pDC,x-1,y-1,old_Color,new_Color);
Flood_Fill_4(pDC,x+1,y-1,old_Color,new_Color);
scanLineFill4(CDC*pDC,intxseed,intyseed,COLORREFoldColor,COLORREFfillColor)
intx,y,xtemp,xleft,xright;
intspanfill;
SeqStackstack;
stack.Push(xseed);
stack.Push(yseed);
while(!
stack.StackEmpty())
{
y=stack.Peek();
stack.Pop();
x=stack.Peek();
stack.Pop();
pDC->
SetPixel(x,y,fillColor);
for(xtemp=x+1;
GetPixel(xtemp,y)==oldColor;
xtemp++)
pDC->
SetPixel(xtemp,y,fillColor);
xright=xtemp-1;
for(xtemp=x-1;
xtemp--)
xleft=xtemp+1;
xtemp=xleft;
y=y+1;
while(xtemp<
=xright)
{
spanfill=0;
COLORREFcr=pDC->
GetPixel(xtemp,y);
while(cr!
=oldColor&
cr!
=fillColor&
xtemp<
{
xtemp++;
cr=pDC->
}
while(cr==oldColor&
spanfill=1;
if(spanfill==1)
stack.Push(xtemp-1);
stack.Push(y);
cr=pDC->
if(cr!
continue;
while(cr==oldColor||cr==fillColor&
xtemp=xleft;
y=y-2;
while(xtemp<
{spanfill=0;
}
分别给菜单消息映射函数添加如下代码:
OnFloodfill()
Addyourcommandhandlercodehere
CDC*pDC=GetDC();
intnew_Color=RGB(0,255,0);
intold_Color=pDC->
GetPixel(a_point);
intx=a_point.x,y=a_point.y;
Flood_Fill_4(pDC,x,y,old_Color,new_Color);
OnBoundary()
CDC*pDC=GetDC();
intnew_Color=RGB(0,0,255);
intboundary_Color=pDC->
GetPixel(100,100);
boundary_fill_4(pDC,x,y,boundary_Color,new_Color);
OnScanlinefill()
intfill_Color=RGB(0,0,255);
GetPixel(150,150);
scanLineFill4(pDC,x,y,old_Color,fill_Color);
注:
扫描线多边形填充算法中要使用的栈代码如下():
typedefintDatatype;
classSeqStack
private:
Datatypedata[100];
//抽象类型Datatype的数组
inttop;
//栈顶位置指示器
public:
SeqStack(void)//构造函数
{top=0;
};
~SeqStack(void)//析构函数
{};
voidSeqStack:
Push(Datatypeitem);
//把元素item入栈
DatatypePop(void);
//出栈数据元素并返回
DatatypePeek(void);
//读栈顶数据元素并返回
intStackEmpty(void)//堆栈空返回1;
否则返回0
{return(top==0);
intGetSize(void)//读栈元素个数top
{returntop;
voidClearStack(void)//清空堆栈使之为初始化状态
voidSeqStack:
Push(Datatypeitem){
if(top==100){
//cout<
<
"
堆栈已满!
endl;
exit(0);
}
data[top]=item;
top++;
DatatypeSeqStack:
Pop()
if(top==0)
//cout<
堆栈已空!
exit(0);
top--;
//top先减1
returndata[top];
//然后取top位置上的元素返回
Peek(void)
堆栈空!
returndata[top-1];
//top指在栈顶的下一个位置,取top-1上的元素返回
实验三裁剪算法
掌握Cohen-Sutherland、Liang-Barsky等直线段裁剪算法以及多边形裁剪算法的基本原理
1.直线裁剪算法
2.多边形裁剪算法
实验四基本3D图形生成以及变换、曲线和曲面生成
1.知道曲线、曲面的常用表示方法,以及用参数法表示曲线、曲面的优点。
2.掌握基本3D图形生成以及变换。
3.掌握Bezier曲线的生成方法和性质。
4.了解一种完全过型值点的分段插值算法。
3D图形生成以及各种变换、Bezier曲线曲面的生成方法。