多边形有效边表填充算法.docx
《多边形有效边表填充算法.docx》由会员分享,可在线阅读,更多相关《多边形有效边表填充算法.docx(14页珍藏版)》请在冰豆网上搜索。
多边形有效边表填充算法
多边形有效边表填充算法
案例效果如下:
具体实现:
(1)新建MFC项目:
(2)分别添加类:
AET和Bucket
在AET.h中定义
#pragmaonceclassAET
{
public:
AET(void);
〜AET(void);
doublex;
intyMax;
doublek;
AET*next;
};
在Bucket.h中定义
#pragmaonce
#include"AET.h"
classBucket
public
Bucket(void);〜Bucket(void);intScanline;AET*p;
Bucket*next;
};
(3)定义菜单
(4)添加菜单处理程序
(5)定义视图头文件
//scanfillView.h:
CscanfillView
//
类的接口
#pragmaonce
#include"AET.h"
#include"Bucket.h"
#defineNumber7
classCscanfillView:
publicCView
protected:
//仅从序列化创建
CscanfillView();
DECLARE_DYNCREATE(CscanfillView)
//属性
public:
CscanfillDoc*GetDocument()const;
//操作public:
voidPolygonFill();//上闭下开填充多边形
voidCreatBucket();//建立桶节点
voidEt();//构造边表
voidAddEdge(AET*);//将边插入AET表
voidEdgeOrder();//对AET表进行排序
//重写
public:
virtualvoidOnDraw(CDC*pDC);//重写以绘制该视图
virtualBOOLPreCreateWindow(CREATESTRUCT&cs);protected:
virtualBOOLOnPreparePrinting(CPrintlnfo*pInfo);
virtualvoidOnBeginPrinting(CDC*pDC,CPrintInfo*pInfo);
virtualvoidOnEndPrinting(CDC*pDC,CPrintInfo*pInfo);
//实现public:
virtual~CscanfillView();
#ifdef_DEBUG
virtualvoidAssertValid()const;
virtualvoidDump(CDumpContext&dc)const;
#endifprotected:
COLORREFGetColor;//调色板
CPointPoint[7];//定义多边形
Bucket*HeadB,*CurrentB;//桶的头结点和当前节点
AETE[Number],*HeadE,*CurrentE,*T1,*T2;//有效边表的节点
//生成的消息映射函数protected:
DECLARE_MESSAGE_MAP()
public:
afx_msgvoidOnMenuAET();
};
#ifndef_DEBUG//scanfillView.cpp中的调试版本
inlineCscanfillDoc*CscanfillView:
:
GetDocument()const
{returnreinterpret_cast(m_pDocument);}
#endif
(6)实现视图
//scanfillView.cpp:
CscanfillView类的实现
//
#include"stdafx.h"
#include"scanfill.h"
#include"scanfillDoc.h"
#include"scanfillView.h"
#ifdef_DEBUG
#definenewDEBUG_NEW
#endif
#defineROUND(a)int(a+0.5)//定义四舍五入
//CscanfillView
IMPLEMENT_DYNCREATE(CscanfillView,CView)
BEGIN_MESSAGE_MAP(CscanfillView,CView)
//标准打印命令
ON_COMMAND(ID_FILE_PRINT,&CView:
:
OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT,&CView:
:
OnFilePrint)ON_COMMAND(ID_FILE_PRINT_PREVIEW,&CView:
:
OnFilePrintPreview)ON_COMMAND(ID_MenuAET,&CscanfillView:
:
OnMenuAET)END_MESSAGE_MAP()
//CscanfillView构造/析构
CscanfillView:
:
CscanfillView()
{
//TODO:
在此处添加构造代码
//设置多边形的个顶点
Point[0]=CPoint(550,400);
Point[1]=CPoint(350,600);
Point[2]=CPoint(250,350);
Point[3]=CPoint(350,50);
Point[4]=CPoint(500,250);
Point[5]=CPoint(600,50);
Point[6]=CPoint(800,450);
CscanfillView:
:
〜CscanfillView()
{
}
BOOLCscanfillView:
:
PreCreateWindow(CREATESTRUCT&cs)
{
//TODO:
在此处通过修改
//CREATESTRUCTcs来修改窗口类或样式
returnCView:
:
PreCreateWindow(cs);
}
//CscanfillView绘制
voidCscanfillView:
:
OnDraw(CDC*pDC)
{
CscanfillDoc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
if(!
pDoc)
return;
//TODO:
在此处为本机数据添加绘制代码
pDC->Polygon(Point,7);
//绘制多边形
pDC->TextOutW(550,410,_T("P0"));
//注意文本的输岀
pDC->TextOutW(350,600,_T("P1"));
pDC->TextOutW(230,340,_T("P2"));
pDC->TextOutW(350,30,_T("P3"));
pDC->TextOutW(490,220,_T("P4"));
pDC->TextOutW(600,30,_T("P5"));
pDC->TextOutW(805,450,_T("P6"));
}
//CscanfillView打印
BOOLCscanfillView:
:
OnPreparePrinting(CPrintlnfo*pInfo){
//默认准备
returnDoPreparePrinting(plnfo);
}
{
//TODO:
添加额外的打印前进行的初始化过程
}
voidCscanfillView:
:
OnEndPrinting(CDC*/*pDC*/,CPrintInfo*/*pInfo*/)
{
//TODO:
添加打印后进行的清理过程
}
//CscanfillView诊断
#ifdef_DEBUG
voidCscanfillView:
:
AssertValid()const
{
CView:
:
AssertValid();
}
voidCscanfillView:
:
Dump(CDumpContext&dc)const
{
CView:
:
Dump(dc);
}
CscanfillDoc*CscanfillView:
:
GetDocument()const//非调试版本是内联的
{
ASSERT(m_pDocument->lsKindOf(RUNTIME_CLASS(CscanfillDoc)));
return(CscanfillDoc*)m_pDocument;
}
#endif//_DEBUG
//建立桶节点函数
//CscanfillView消息处理程序
voidCscanfillView:
:
CreatBucket()
ScanMax=ScanMin=Point[O].y;
for(inti=1;iif(Point[i].yif(Point[i].y>ScanMax)
{
if(ScanMin==i)//桶头结点
{
HeadB=newBucket;//建立桶的头结点
CurrentB=HeadB;//CurrentB为Bucket当前节点指针
CurrentB->Scanline=ScanMin;
CurrentB->p=NULL;//没有连接边链表
CurrentB->next=NULL;
}
else
{//建立桶的其他节点
CurrentB->next=newBucket;//新建一个桶节点
CurrentB=CurrentB->next;//使CurrentB指向新建的桶节点
CurrentB->Scanline=i;
CurrentB->p=NULL;//没有连接边链表
CurrentB->next=NULL;
}
}
}
voidCscanfillView:
:
Et()
//构造边表函数
{
for(inti=0;i//访问每个顶点
{
E[i].yMax=Point[j].y;
E[i].k=(double(Point[j].x-Point[i].x))/(Point[j].y-Point[i].y);
E[i].next=NULL;
while(CurrentE->next!
=NULL)//如果当前边已有边节点
CurrentB=NULL;
CurrentE=NULL;
//插入临时边表函数
}
voidCscanfillView:
:
AddEdge(AET*NewEdge)
T1=HeadE;
if(T1==NULL)//边表为空,将边表置为TempEdge
{
T1=NewEdge;
HeadE=T1;
}else
voidCscanfillView:
:
EdgeOrder()//对边表进行排序
{
AET*F,*T;
T1=HeadE;
if(T1==NULL)
{
return;
}
if仃1