实验三计算机图形学多边形填充算法汇总.docx
《实验三计算机图形学多边形填充算法汇总.docx》由会员分享,可在线阅读,更多相关《实验三计算机图形学多边形填充算法汇总.docx(27页珍藏版)》请在冰豆网上搜索。
实验三计算机图形学多边形填充算法汇总
洛阳理工学院实验报告
系别
计算机与信息工程系
班级
B120531
学号
B12053113
姓名
课程名称
计算机图形学
实验日期
2013-11-7
实验名称
多边形填充算法编程
成绩
实验目的:
熟悉多边形填充算法,掌握MFC图形编程的基本方法和调试技巧。
实验条件:
计算机;VS2008;OpenGL
实验内容:
1.使用MFC技术实现多边形有效边表填充算法,参考界面效果如下:
//ChildView.cpp:
CChildView类的实现
#include"stdafx.h"
#include"demo.h"
#include"ChildView.h"
#include
#defineRound(d)int(floor(d+0.5))//四舍五入宏定义
#ifdef_DEBUG
#definenewDEBUG_NEW
#endif
//CChildView
CChildView:
:
CChildView()
{
}
CChildView:
:
~CChildView()
{
}
BEGIN_MESSAGE_MAP(CChildView,CWnd)
ON_WM_PAINT()
ON_WM_CREATE()
ON_COMMAND(ID_DRAW_PIC,&CChildView:
:
OnDrawPic)
END_MESSAGE_MAP()
//CChildView消息处理程序
BOOLCChildView:
:
PreCreateWindow(CREATESTRUCT&cs)
{
if(!
CWnd:
:
PreCreateWindow(cs))
returnFALSE;
cs.dwExStyle|=WS_EX_CLIENTEDGE;
cs.style&=~WS_BORDER;
cs.lpszClass=AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS,
:
:
LoadCursor(NULL,IDC_ARROW),reinterpret_cast(COLOR_WINDOW+1),NULL);
returnTRUE;
}
voidCChildView:
:
OnPaint()
{
CPaintDCdc(this);//用于绘制的设备上下文
//TODO:
在此处添加消息处理程序代码
DrawGraph();
//不要为绘制消息而调用CWnd:
:
OnPaint()
}
voidCChildView:
:
ReadPoint()//点表
{
P[0].x=50;P[0].y=100;
P[1].x=-150;P[1].y=300;
P[2].x=-250;P[2].y=50;
P[3].x=-150;P[3].y=-250;
P[4].x=0;P[4].y=-50;
P[5].x=100;P[5].y=-250;
P[6].x=300;P[6].y=150;
}
voidCChildView:
:
DrawPolygon(CDC*pDC)//绘制多边形边界
{
CLine*line=newCLine;
CP2t;
for(inti=0;i<7;i++)//绘制多边形
{
if(i==0)
{
line->MoveTo(pDC,P[i]);
t=P[i];
}
else
{
line->LineTo(pDC,P[i]);
}
}
line->LineTo(pDC,t);//闭合多边形
deleteline;
}
voidCChildView:
:
DrawGraph()//绘制图形
{
CRectrect;//定义客户区
GetClientRect(&rect);//获得客户区的大小
CDC*pDC=GetDC();//定义设备上下文指针
pDC->SetMapMode(MM_ANISOTROPIC);//自定义坐标系
pDC->SetWindowExt(rect.Width(),rect.Height());//设置窗口比例
pDC->SetViewportExt(rect.Width(),-rect.Height());//设置视区比例,且x轴水平向右,y轴垂直向上
pDC->SetViewportOrg(rect.Width()/2,rect.Height()/2);//设置客户区中心为坐标系原点
rect.OffsetRect(-rect.Width()/2,-rect.Height()/2);//矩形与客户区重合
if(!
bFill)
DrawPolygon(pDC);//绘制多边形
else
FillPolygon(pDC);//填充多边形
ReleaseDC(pDC);//释放DC
}
voidCChildView:
:
FillPolygon(CDC*pDC)//填充多边形
{
for(inti=0;i<7;i++)//转储顶点坐标,y坐标取为整数
{
P1[i].x=P[i].x;
P1[i].y=Round(P[i].y);
P1[i].c=CRGB(bRed/255.0,bGreen/255.0,bBlue/255.0);
}
CFill*fill=newCFill;//动态分配内存
fill->SetPoint(P1,7);//初始化Fill对象
fill->CreateBucket();//建立桶表
fill->CreateEdge();//建立边表
fill->Gouraud(pDC);//填充多边形
deletefill;//撤销内存
}
intCChildView:
:
OnCreate(LPCREATESTRUCTlpCreateStruct)
{
if(CWnd:
:
OnCreate(lpCreateStruct)==-1)
return-1;
//TODO:
在此添加您专用的创建代码
bFill=FALSE;
ReadPoint();
return0;
}
voidCChildView:
:
OnDrawPic()
{
//TODO:
在此添加命令处理程序代码
COLORREFGetClr=RGB(0,0,0);//调色板颜色
CColorDialogccd(GetClr,CC_SOLIDCOLOR);
if(IDOK==ccd.DoModal())//调用颜色对话框选取填充色
GetClr=ccd.GetColor();
else
return;
bRed=GetRValue(GetClr);//获取红色分量
bGreen=GetGValue(GetClr);//获取绿色分量
bBlue=GetBValue(GetClr);//获取蓝色分量
bFill=TRUE;
Invalidate();
}
2.使用MFC技术实现多边形边缘填充算法,参考界面效果如下:
//demoView.cpp:
CdemoView类的实现
#include"stdafx.h"
#include"demo.h"
#include"demoDoc.h"
#include"demoView.h"
#include
#defineRound(d)int(floor(d+0.5))//四舍五入宏定义
#ifdef_DEBUG
#definenewDEBUG_NEW
#endif
//CdemoView
IMPLEMENT_DYNCREATE(CdemoView,CView)
BEGIN_MESSAGE_MAP(CdemoView,CView)
//标准打印命令
ON_COMMAND(ID_FILE_PRINT,&CView:
:
OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT,&CView:
:
OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW,&CdemoView:
:
OnFilePrintPreview)
ON_COMMAND(ID_DRAW_PIC,&CdemoView:
:
OnDrawPic)
END_MESSAGE_MAP()
//CdemoView构造/析构
CdemoView:
:
CdemoView()
{
//TODO:
在此处添加构造代码
}
CdemoView:
:
~CdemoView()
{
}
BOOLCdemoView:
:
PreCreateWindow(CREATESTRUCT&cs)
{
//TODO:
在此处通过修改
//CREATESTRUCTcs来修改窗口类或样式
returnCView:
:
PreCreateWindow(cs);
}
//CdemoView绘制
voidCdemoView:
:
OnDraw(CDC*/*pDC*/)
{
CdemoDoc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
if(!
pDoc)
return;
//TODO:
在此处为本机数据添加绘制代码
DrawGraph();
}
//CdemoView打印
voidCdemoView:
:
OnFilePrintPreview()
{
AFXPrintPreview(this);
}
BOOLCdemoView:
:
OnPreparePrinting(CPrintInfo*pInfo)
{
//默认准备
returnDoPreparePrinting(pInfo);
}
voidCdemoView:
:
OnBeginPrinting(CDC*/*pDC*/,CPrintInfo*/*pInfo*/)
{
//TODO:
添加额外的打印前进行的初始化过程
}
voidCdemoView:
:
OnEndPrinting(CDC*/*pDC*/,CPrintInfo*/*pInfo*/)
{
//TODO:
添加打印后进行的清理过程
}
voidCdemoView:
:
OnRButtonUp(UINTnFlags,CPointpoint)
{
ClientToScreen(&point);
OnContextMenu(this,point);
}
voidCdemoView:
:
OnContextMenu(CWnd*pWnd,CPointpoint)
{
theApp.GetContextMenuManager()->ShowPopupMenu(IDR_POPUP_EDIT,point.x,point.y,this,TRUE);
}
voidCdemoView:
:
ReadPoint()//点表
{
P[0].x=50;P[0].y=100;
P[1].x=-150;P[1].y=300;
P[2].x=-250;P[2].y=50;
P[3].x=-150;P[3].y=-250;
P[4].x=0;P[4].y=-50;
P[5].x=100;P[5].y=-250;
P[6].x=300;P[6].y=150;
}
voidCdemoView:
:
DrawPolygon(CDC*pDC)
{
for(inti=0;i<7;i++)//计算多边形边界
{
if(P[i].x>MaxX)
MaxX=P[i].x;
if(P[i].xMinX=P[i].x;
if(P[i].y>MaxY)
MaxY=P[i].y;
if(P[i].yMinY=P[i].y;
}
CLine*line=newCLine;
CP2t;
for(inti=0;i<7;i++)//绘制多边形
{
if(i==0)
{
line->MoveTo(pDC,P[i]);
t=P[i];
}
else
{
line->LineTo(pDC,P[i]);
}
}
line->LineTo(pDC,t);//闭合多边形
line->MoveTo(pDC,CP2(MinX,MinY));//绘制包围盒
line->LineTo(pDC,CP2(MinX,MaxY));
line->LineTo(pDC,CP2(MaxX,MaxY));
line->LineTo(pDC,CP2(MaxX,MinY));
line->LineTo(pDC,CP2(MinX,MinY));
deleteline;
}
voidCdemoView:
:
FillPolygon(CDC*pDC)
{
COLORREFBClr=RGB(255,255,255);//背景色
COLORREFFClr=GetClr;//填充色
intymin,ymax;//边的最小y值与最大y值
doublex,y,k;//x,y当前点,k斜率的倒数
for(inti=0;i<7;i++)//循环多边形所有边
{
intj=(i+1)%7;
k=(P[i].x-P[j].x)/(P[i].y-P[j].y);//计算/k
if(P[i].y
{
ymin=Round(P[i].y);
ymax=Round(P[j].y);
x=P[i].x;//得到x|ymin
}
else
{
ymin=Round(P[j].y);
ymax=Round(P[i].y);
x=P[j].x;
}
for(y=ymin;y{
for(intm=Round(x);m{
if(FClr==pDC->GetPixel(m,Round(y)))//如果是填充色
pDC->SetPixelV(m,Round(y),BClr);//置为背景色
else
pDC->SetPixelV(m,Round(y),FClr);//置为填充色
}
x+=k;//计算下一条扫描线的x起点坐标
}
}
}
voidCdemoView:
:
DrawGraph()//绘制图形
{
CRectrect;//定义客户区
GetClientRect(&rect);//获得客户区的大小
CDC*pDC=GetDC();//定义设备上下文指针
pDC->SetMapMode(MM_ANISOTROPIC);//自定义坐标系
pDC->SetWindowExt(rect.Width(),rect.Height());//设置窗口比例
pDC->SetViewportExt(rect.Width(),-rect.Height());//设置视区比例,且x轴水平向右,y轴垂直向上
pDC->SetViewportOrg(rect.Width()/2,rect.Height()/2);//设置客户区中心为坐标系原点
rect.OffsetRect(-rect.Width()/2,-rect.Height()/2);//矩形与客户区重合
if(!
bFill)
DrawPolygon(pDC);//绘制多边形
else
FillPolygon(pDC);//填充多边形
ReleaseDC(pDC);//释放DC
}
//CdemoView诊断
#ifdef_DEBUG
voidCdemoView:
:
AssertValid()const
{
CView:
:
AssertValid();
}
voidCdemoView:
:
Dump(CDumpContext&dc)const
{
CView:
:
Dump(dc);
}
CdemoDoc*CdemoView:
:
GetDocument()const//非调试版本是内联的
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CdemoDoc)));
return(CdemoDoc*)m_pDocument;
}
#endif//_DEBUG
//CdemoView消息处理程序
voidCdemoView:
:
OnInitialUpdate()
{
CView:
:
OnInitialUpdate();
//TODO:
在此添加专用代码和/或调用基类
bFill=FALSE;
ReadPoint();
GetClr=RGB(0,0,0);
MinX=MaxX=P[0].x;
MinY=MaxY=P[0].y;
}
voidCdemoView:
:
OnDrawPic()
{
//TODO:
在此添加命令处理程序代码
CColorDialogccd(GetClr,CC_SOLIDCOLOR);
if(IDOK==ccd.DoModal())//调用颜色对话框选取填充色
GetClr=ccd.GetColor();
else
return;
bFill=TRUE;
Invalidate(FALSE);
}
3.使用MFC技术实现种子填充算法,参考界面效果如下:
//demoView.cpp:
CdemoView类的实现
#include"stdafx.h"
#include"demo.h"
#include"demoDoc.h"
#include"demoView.h"
#include
#defineRound(d)int(floor(d+0.5))//四舍五入宏定义
#ifdef_DEBUG
#definenewDEBUG_NEW
#endif
//CdemoView
IMPLEMENT_DYNCREATE(CdemoView,CView)
BEGIN_MESSAGE_MAP(CdemoView,CView)
//标准打印命令
ON_COMMAND(ID_FILE_PRINT,&CView:
:
OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT,&CView:
:
OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW,&CdemoView:
:
OnFilePrintPreview)
ON_WM_LBUTTONDOWN()
ON_COMMAND(ID_DRAW_PIC,&CdemoView:
:
OnDrawPic)
END_MESSAGE_MAP()
//CdemoView构造/析构
CdemoView:
:
CdemoView()
{
//TODO:
在此处添加构造代码
bFill=FALSE;
SeedClr=RGB(255,0,0);
}
CdemoView:
:
~CdemoView()
{
}
BOOLCdemoView:
:
PreCreateWindow(CREATESTRUCT&cs)
{
//TODO:
在此处通过修改
//CREATESTRUCTcs来修改窗口类或样式
returnCView:
:
PreCreateWindow(cs);
}
//CdemoView绘制
voidCdemoView:
:
OnDraw(CDC*/*pDC*/)
{
CdemoDoc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
if(!
pDoc)
return;
//TODO:
在此处为本机数据添加绘制代码
DrawGraph();
}
//CdemoView打印
voidCdemoView:
:
OnFilePrintPreview()
{
AFXPrintPreview(this);
}
BOOLCdemoView:
:
OnPreparePrinting(CPrintInfo*pInfo)
{
//默认准备
returnDoPreparePrinting(pInfo);
}
voidCdemoView:
:
OnBeginPrinting(CDC*/*pDC*/,CPrintInfo*/*pInfo*/)
{
//TODO:
添加额外的打印前进行的初始化过程
}
voidCdemoView:
:
OnEndPrinting(CDC*/*pDC*/,CPrintInfo*/*pInfo*/)
{
//TODO:
添加打印后进行的清理过程
}
voidCdemoView:
:
OnRButtonUp(UINTnFlags,CPointpoint)
{
ClientToScreen(&point);
OnContextMenu(this,point);
}
voidCdemoView:
:
OnContextMenu(CWnd*pWnd,CPoi