填充算法C++实现

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

2.6.5 填充算法的
C++实现
目的:
理解有序边、种子填充及图案填充算法的原理并可以编程实现。
实现内容:
1、分别用有序边及种子填充算法编程实现任意多变形的填充
2、编程实现图案填充多变形
基本要求:
1、程序能实现任意凹、凸多边形的填充
2、多变形边界用交互式方法输入


程序实例实现的功能:填充三角形、填充
20条边以下的多边形,算法为边填充算法。
边填充算法程序实现的基本思路如下:


①构造初始边表(EOT)——对各斜边按
ymax值从上到下排序,存放于一个高度表(y桶表)中,高
度表的内容为指向各斜边的指针。
②构造活性边表(
AET)——从上到下计算出每条扫描线与多边形各斜边的交点,这些交点用活性边
表来保存,活性边表有与初始边表具有相同的节点结构。
③对每条扫描线对应的活性边表中求交点。
④判断交点类型,并两两配对。
⑤对符合条件的交点之间进行填充。
⑥进行下一条扫描线,直到满足扫描结束条件。
程序实现步骤如下:

步骤一:
创建工程:
创建一单文档工程,工程名
MyPriciple。


步骤二:
创建两个新类:CPolygon、CTriangle,分别用于绘制三角形和多边形
实现的基本功能分别如下:
CPolygon类:


①定义边的结构体
typedef struct _edge

{
int ymax;
float x,deltax;
struct _edge *next;


}Edge;

②实现绘图的外部接口:
函数为:
drawpolygon(CDC *pDC,POINT *polyGP,int m_polygonNum,int m_pColor);为外部接口
参数分别为:

POINT *polyGP,存放多边形顶点的
POINT型数组
int m_polygonNum,多边形的顶点个数
int m_pColor,画笔颜色
该函数需要调用两个函数:建立边表和绘制填充多边形。

建立边表函数如下:


void CPolygon::CreateET(POINT *polyGP)
此函数完成多边形边的分类表
ET的建立
参数
POINT *polyGP为存放多边形顶点的数组
在此过程中得到多边形的最低点
pymin及最高点
pymax

在建立边表过程中用到插入边节点,其相应的函数为:


void CPolygon::insertEdge(Edge* & head,Edge* &p)

此函数完成向分类表或活性表中插入边结点
参数
Edge *& head为链表头结点
,Edge *& p为一个边结点
按照
p->x的增序插入
绘制填充多边形函数如下:


void CPolygon::dPolygon(CDC * pDC,int color)

在绘制多边形过程中用到判断边表是否为空,其相应的函数如下:


bool CPolygon::isemptyET()

此函数判断边的分类表是否为空
为空,则返回
true
不为空,则返回
false


CTriangle类:
该类与
CPolygon类类似,但期间调用了
CPolygon类的结构体,故需包含其头文件。


步骤三:
创建相应的菜单,填充三角形和填

充多边形


IDM_MTRIANGLE
IDM_MSCAN
附加一选择填充颜色的菜单
IDM_MFILL,该菜单调用颜色对话框其程序代码如下:
//填充颜色的选择
void CMyPricipleView::OnMfill()
{

// TODO: Add your command handler code here
m_dSort=6;
m_oColor=m_pColor;
CColorDialog ColorDialog;
if(ColorDialog.DoModal()==IDOK)


m_pColor=ColorDialog.GetColor();
UpdateData(0);
}

菜单的消息相应如下:


void CMyPricipleView::OnMtriangle()

{
// TODO: Add your command handler code here
m_dSort=4;


}
void CMyPricipleView::OnMscan()
{


// TODO: Add your command handler code here
m_dSort=5;
CDC *pDC=GetDC();
OnDraw(pDC);
pDC->TextOut(50,50,"单击左键确定多边形顶点,右击开始绘图");


}

其参数传递给相应的鼠标单击和右击事件,鼠标单击和右击事件通过相应参数实现相应操作。

步骤四:
添加鼠标左键、右键单击消息映射,左键为抬起,右键为按下,并完成相应代码如下:
//相应抬起鼠标消息
void CMyPricipleView::OnLButtonUp(UINT nFlags, CPoint point)
{


// TODO: Add your message handler code here and/or call default
CDC* pDC=GetDC();
switch(m_dSort)
{
case 0:
case 1:
case 3:
case 4://三角形


polyGP[m_PolygonNum++]=point;
pDC->SetPixel(point.x,point.y,RGB(255,0,0));
if(m_PolygonNum==3)
{


m_Triangle.drawtriangle(pDC,polyGP,m_pColor);
inLength=m_PolygonNum;
m_PolygonNum=0;


}
break;


case 5:
polyGP[m_PolygonNum++]=point;
pDC->SetPixel(point.x,point.y,RGB(255,0,0));
if(m_PolygonNum>20)


MessageBox("您的输入超过了本程序允许的最大顶点个数
20!\t\n绘图中
止!!",NULL,MB_OK);
break;
}


CView::OnLButtonUp(nFlags, point);
}

void CMyPricipleView::OnRButtonDown(UINT nFlags, CPoint point)

{
// TODO: Add your message handler code here and/or call default
CDC *pDC=GetDC();
if(m_dSort==5)
{

if(m_PolygonNum>=3)
m_polygon.drawpolygon(pDC,polyGP,m_PolygonNum,m_pColor);
else


MessageBox("顶点数不足三个,请重新设定!",NULL,MB_OK);
inLength=m_PolygonNum;
m_PolygonNum=0;


}

CView::OnRButtonDown(nFlags, point);
}

期间用到一些相关变量,在视图类头文件中定义,在构造函数中实现。
程序完整源代码如下:


// Polygon.h: interface for the CPolygon class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_POLYGON_H__EA547C5F_92DD_4847_A7BF_D702BFB41CDA__INCLUDED_)
#define AFX_POLYGON_H__EA547C5F_92DD_4847_A7BF_D702BFB41CDA__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

//定义边的结构体
typedef struct _edge
{

int ymax;
float x,deltax;
struct _edge *next;


}Edge;
/*---------------------------------------------------------*/
/*一个绘制多边形的类
*/
//drawpolygon(CDC *pDC,POIN

T *polyGP,int m_polygonNum,int m_pColor);为外部接口
//参数分别为:
//POINT *polyGP,存放多边形顶点的
POINT型数组



//int m_polygonNum,多边形的顶点个数
//int m_pColor, 画笔颜色
/*---------------------------------------------------------*/
class CPolygon
{
public:


void drawpolygon(CDC *pDC,POINT *polyGP,int polygonNum,int m_pColor);
CPolygon();
virtual ~CPolygon();


private:
bool isemptyET();
int pymin;
int pymax;
int Num;
Edge **ET;
Edge *AEL;
void dPolygon(CDC *pDC,int color);
void insertEdge(Edge* & head,Edge* &p);
void CreateET(POINT *polyGP);


};

#endif
// !defined(AFX_POLYGON_H__EA547C5F_92DD_4847_A7BF_D702BFB41CDA__INCLUDED_)

#include "stdafx.h"
#include "MyPriciple.h"
#include "Polygon.h"


#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif


//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////


CPolygon::CPolygon()
{


}


CPolygon::~CPolygon()
{

}

/*---------------------------------------------------------*/
/*此函数完成多边形边的分类表
ET的建立
/*参数
POINT *polyGP为存放多边形顶点的数组
/*在此过程中得到多边形的最低点
pymin及最高点
pymax
/*---------------------------------------------------------*/
void CPolygon::CreateET(POINT *polyGP)
{

ET=new _edge*[768];
polyGP[Num]=polyGP[0];//降低一个点复制到最后,便于求最后一条边
pymin=polyGP[0].y;
//初始化边的分类表
for(int i=0;i<768;i++)


ET[i]=NULL;
for(i=0;i{


//获得多边形的最低点和最高点
if(polyGP[i].y>pymax)
pymax=polyGP[i].y;
if(polyGP[i].ypymin=polyGP[i].y;


//将边按下端点的
y值分类
Edge *p=new Edge;
if(polyGP[i].y{


p->ymax=polyGP[i+1].y;
p->x=(float)polyGP[i].x;
p->deltax=(float)(polyGP[i+1].x-polyGP[i].x)/(float)(polyGP[i+1].y-polyGP[i].y);
p->next=NULL;
insertEdge(ET[polyGP[i].y],p);//按
p->x增序插入边的分类表


}

else
if(polyGP[i].y>polyGP[i+1].y)
{


p->ymax=polyGP[i].y;
p->x=(float)polyGP[i+1].x;
p->deltax=(float)(polyGP[i+1].x-polyGP[i].x)/(float)(polyGP[i+1].y-polyGP[i].y);
p->next=NULL;
insertEdge(ET[polyGP[i+1].y],p);//按
p->x增序插入边的分类表


}


}//end of for(i=0;i
}
/*---------------------------------------------------------*/
/*此函数完成向分类表或活性表中插入边结点
/*参数
Edge *& head为链表头结点
,Edge *& p为一个边结点
/*按照
p->x的增序插入
/*---------------------------------------------------------*/
void CPolygon::insertEdge(Edge* & head,Edge* &p)
{

Edge * cp;
Edge* ap;
ap=NULL;
cp=head;//ap,cp均为游标,ap紧随


cp之后,找到的插入点在
ap,cp之间


while(cp!=NULL)
{//此循环结束后
,将找到插入点
if(p->xx)


break;//找到插入点
else if(p->x==cp->x)
{//当
x值相等时


if(p->deltaxdeltax)

break;//插入当前结点
cp前
else
{//插入当前结点后

ap=cp;
cp=cp->next;
break;


}
}
else


{//p->x>cp->x时
ap=cp;
cp=cp->next;


}
}//end of while


if(ap==NULL)

{//在第一个结点之前插入
p->next=head;
head=p;


}
else
{//在
ap,cp之间插入


ap->next=p;


p->next=cp;
}


}
/*---------------------------------------------------------*/
/*此函数根据边的分类表和活性表绘制多边形
/*---------------------------------------------------------*/
void CPolygon::dPolygon(CDC * pDC,int color)
{


//将扫描线的
y坐标初值置为多边形的最低点
int y=pymin;


//置
AEL为空
AEL=NULL;


while(!isemptyET()||AEL!=NULL)

{//当
ET不为空或
AEL不为空,执行下列步骤
Edge *p_ET=NULL;//用于指向
ET表的指针
while(ET[y]!=NULL)
{//如果
ET中第
y类非空,将其所有的边按
x增序插入
AEL


p_ET=ET[y];
ET[y]=ET[y]->next;
p_ET->next=NULL;
insertEdge(AEL,p_ET);


}

Edge *p_AEL=AEL;//用于指向
AEL表的指针
while(p_AEL!=NULL)
{//将
AEL中边两两配对,并按
x进行填充


Edge *p1=p_AEL;
Edge *p2=p_AEL->next;
for(int i=(p1->xx?(int)p1->x:(int)p2->x);i<(p1->x>p2->x?(int)p1->x:(int)p2->x);i++)//用


于绘制自交多边形

pDC->SetPixel(i,y,color);
p_AEL=p_AEL->next;
p_AEL=p_AEL->next;


}

y++;//扫描线
y值增一

//将
AEL中满足
y=ymax的边删除
while(AEL!=NULL&&AEL->ymax==y)
AEL=AEL->next;
if(AEL!=NULL){
Edge * p1,*p2;



p1=AEL;
p2=AEL->next;
while(p2!=NULL)
{

if(p2->ymax==y)

{
p1->next=p2->next;
p2->next=NULL;
p2=p1->next;

}
else
{

p1=p1->next;
p2=p2->next;
}
}
}


p_AEL=AEL;
while(p_AEL!=NULL)
{//对
AEL中剩下的边的
x递增
deltax


p_AEL->x=p_AEL->x+p_AEL->deltax;

p_AEL=p_AEL->next;
}
p_AEL=NULL;
p_ET=NULL;


}//end of while(!isemptyET()||AEL!=NULL)

}
/*---------------------------------------------------------*/
/*此函数判断边的分类表是否为空
/*为空,则返回
true
/*不为空,则返回
false
/*---------------------------------------------------------*/
bool CPolygon::isemptyET()
{

bool flag=true;

for(int i=pymin;iif(ET[i]!=NULL)
{


flag=false;

break;
}
return flag;


}


/*---------------------------------------------------------*/
/*此函数为此类的外部接口
//参数分别为:
//POINT *polyGP,存放多边形顶点的
POINT型数组
//int m_polygonNum,多边形的顶点个数
//int m_pColor, 画笔颜色
/*------------------------------

---------------------------*/
void CPolygon::drawpolygon(CDC *pDC, POINT *polyGP, int polygonNum, int m_pColor)
{

Num=polygonNum;
CreateET(polyGP);//建立边表
dPolygon(pDC,m_pColor);//绘制多边形


}

// Triangle.h: interface for the CTriangle class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_TRIANGLE_H__5A144E33_E490_475B_847F_49E72831A595__INCLUDED_)
#define AFX_TRIANGLE_H__5A144E33_E490_475B_847F_49E72831A595__INCLUDED_

//包含多边形的头文件
#include"polygon.h"

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class CTriangle
{
public:

CTriangle();
virtual ~CTriangle();


//定义相关函数
void init();
void drawtriangle(CDC *pDC,POINT *polyGP,int m_pColor);
int pymax;
int pymin;
void insertEdge(Edge* &head,Edge* &p);
void CreateEdge(POINT *polyGP);
void d_triangle(CDC* pDC,int m_pColor);
Edge *AEL;
int AEL_num;



};

#endif // !defined(AFX_TRIANGLE_H__5A144E33_E490_475B_847F_49E72831A595__INCLUDED_)

// Triangle.cpp: implementation of the CTriangle class.
//
//////////////////////////////////////////////////////////////////////


#include "stdafx.h"
#include "MyPriciple.h"
#include "Triangle.h"


#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif


//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////


CTriangle::CTriangle()
{


}


CTriangle::~CTriangle()
{


}


void CTriangle::init()


{


AEL_num=0;

AEL=NULL;

pymax=0;

pymin=0;
}

void CTriangle::insertEdge(Edge* &head, Edge *&p)

{

Edge * cp;

Edge* ap;

//ap,cp均为游标
,ap紧随
cp之后,找到的插入点在
ap,cp之间


ap=NULL;

cp=head;

//此循环结束后
,将找到插入点
while(cp!=NULL)
{


if(p->xx)

break;//找到插入点
else if(p->x==cp->x)
{

//当
x值相等时
if(p->deltaxdeltax)

break;//插入当前结点
cp前
else
{

//插入当前结点后
ap=cp;
cp=cp->next;
break;

}
}
else


{

//p->x>cp->x时
ap=cp;
cp=cp->next;

}
}//end of while


if(ap==NULL)

{
//在第一个结点之前插入
p->next=head;
head=p;


}
else
{


//在
ap,cp之间插入
ap->next=p;
p->next=cp;
}


}

void CTriangle::CreateEdge(POINT *polyGP)
{


polyGP[3]=polyGP[0];//降低一个点复制到最后
,便于求最后一条边
pymin=polyGP[0].y;
int i;
for(i=0;i<3;i++)
{


//获得多边形的最低点和最高点
if(polyGP[i].y>pymax)
pymax=polyGP[i].y;
if(polyGP[i].ypymin=polyGP[i].y;


//将边按下端点的
y值分类
Edge *p=new Edge;
if(polyGP[i].y{


p->yma

x=polyGP[i+1].y;
p->x=(float)polyGP[i].x;
p->deltax=(float)(polyGP[i+1].x-polyGP[i].x)/(float)(polyGP[i+1].y-polyGP[i].y);
p->next=NULL;
insertEdge(AEL,p);//按
p->x增序插入边的分类表
AEL_num++;


}

else
if(polyGP[i].y>polyGP[i+1].y)
{


p->ymax=polyGP[i].y;
p->x=(float)polyGP[i+1].x;
p->deltax=(float)(polyGP[i+1].x-polyGP[i].x)/(float)(polyGP[i+1].y-polyGP[i].y);
p->next=NULL;
insertEdge(AEL,p);//按
p->x增序插入边的分类表
AEL_num++;


}
}//end of for(i=0;i<4;i++)


}

void CTriangle::d_triangle(CDC *pDC, int m_pColor)
{
int y=pymin;//将扫描线赋为最小值

if(AEL_num==2)//AEL中有两个节点

{//此三角形有一水平边
Edge *p1,*p2;
p1=AEL;



p2=p1->next;
while(y<=pymax)
{


for(int i=(int)(p1->x+0.5);i<(int)(p2->x+0.5);i++)

pDC->SetPixel(i,y,m_pColor);
p1->x=p1->x+p1->deltax;
p2->x=p2->x+p2->deltax;
y++;

}
}
else if(AEL_num==3)
{//此三角形无水平边

Edge *p1,*p2,*p3;//此三个节点分别对应
AEL中三个点
p1=AEL;
p2=p1->next;
if(p1->x!=p2->x)
{


p3=p1;
p1=p1->next;
p2=p2->next;


}
else


p3=p2->next;
//
while(y<(p1->ymaxymax?p1->ymax:p2->ymax))
{//扫描三角形的下半部分

for(int i=(int)(p1->x+0.5);i<(int)(p2->x+0.5);i++)

pDC->SetPixel(i,y,m_pColor);
p1->x=p1->x+p1->deltax;
p2->x=p2->x+p2->deltax;
y++;

}

if(y==p1->ymax)
{//删除
p1
if(p3->xx)


p1=p3;
else
{


p1=p1->next;
p2=p3;


}
}
else if(y==p2->ymax)
{//删除
p2



if(p3->xx)

{
p2=p1;
p1=p3;


}
else


p2=p2->next;
}
while(y{//扫描三角形的上半部分


for(int i=(int)(p1->x+0.5);i<(int)(p2->x+0.5);i++)

pDC->SetPixel(i,y,m_pColor);
p1->x=p1->x+p1->deltax;
p2->x=p2->x+p2->deltax;
y++;


}
}
}


void CTriangle::drawtriangle(CDC *pDC, POINT *polyGP,int m_pColor)

{
init();
CreateEdge(polyGP);
d_triangle(pDC,m_pColor);


}

// MyPricipleView.h : interface of the CMyPricipleView class
//
/////////////////////////////////////////////////////////////////////////////


#if !defined(AFX_MYPRICIPLEVIEW_H__F6C0B217_4854_438D_97AA_43FD39707C19__INCLUDE
D_)
#define AFX_MYPRICIPLEVIEW_H__F6C0B217_4854_438D_97AA_43FD39707C19__INCLUDED_

//包含多边形和三角形相关的头文件
#include "polygon.h"
#include "triangle.h"


#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000


//定义
OutCode结构体
typedef struct



{
unsigned all;
unsigned left,right,top,bottom;

}OutCode;

class CMyPricipleView : public CView
{
protected: // create from serialization only

CMyPricipleView();
DECLARE_DYNCREATE(CMyPricipleView)


// Attributes
public:
CMyPricipleDoc* GetDocument();

// Operations
public:

// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIR

TUAL(CMyPricipleView)
public:
virtual void OnDraw(CDC* pDC); // overridden to draw this view
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
//}}AFX_VIRTUAL

// Implementation
public:
virtual ~CMyPricipleView();

#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;

#endif

protected:

// Generated message map functions

protected:
//{{AFX_MSG(CMyPricipleView)
afx_msg void OnMtriangle();
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);


afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnMscan();
afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
afx_msg void OnMfill();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
//自定义相关变量和函数


public:
int m_dSort; //控制菜单的选择
int inLength;
CPoint p1,p2;
int m_PolygonNum;
int m_pColor;
POINT polyGP[20];
void CohenSutherlandLineClip(CDC *pDC,POINT p1,POINT p2,CRect *rect);
void CompOutCode(float x,float y,CRect *rect,OutCode* outCode);
CTriangle m_Triangle;
CPolygon m_polygon;
int m_oColor;


};

#ifndef _DEBUG // debug version in MyPricipleView.cpp
inline CMyPricipleDoc* CMyPricipleView::GetDocument()
{ return (CMyPricipleDoc*)m_pDocument; }
#endif


/////////////////////////////////////////////////////////////////////////////


//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.


#endif
// !defined(AFX_MYPRICIPLEVIEW_H__F6C0B217_4854_438D_97AA_43FD39707C19__INCLUDED_)

// MyPricipleView.cpp : implementation of the CMyPricipleView class
//


#include "stdafx.h"
#include "MyPriciple.h"


#include "MyPricipleDoc.h"
#include "MyPricipleView.h"


#ifdef _DEBUG
#define new DEBUG_NEW



#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CMyPricipleView

IMPLEMENT_DYNCREATE(CMyPricipleView, CView)

BEGIN_MESSAGE_MAP(CMyPricipleView, CView)
//{{AFX_MSG_MAP(CMyPricipleView)
ON_COMMAND(IDM_MTRIANGLE, OnMtriangle)
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_COMMAND(IDM_MSCAN, OnMscan)
ON_WM_RBUTTONDOWN()
ON_COMMAND(IDM_MFILL, OnMfill)
//}}AFX_MSG_MAP
// Standard printing commands
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()

/////////////////////////////////////////////////////////////////////////////
// CMyPricipleView construction/destruction

CMyPricipleView::CMyPricipleView()

{
// TODO: add construction code here
//初始化相关数据
p1=p2=0;
m_dSort=0;
m_Pol

ygonNum=0;
m_pColor=RGB(255,0,0);

}

CMyPricipleView::~CMyPricipleView()
{
}

BOOL CMyPricipleView::PreCreateWindow(CREATESTRUCT& cs)

{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs


return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CMyPricipleView drawing

void CMyPricipleView::OnDraw(CDC* pDC)

{

CMyPricipleDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

// TODO: add draw code for native data here
}

/////////////////////////////////////////////////////////////////////////////
// CMyPricipleView printing

BOOL CMyPricipleView::OnPreparePrinting(CPrintInfo* pInfo)

{

// default preparation

return DoPreparePrinting(pInfo);
}

void CMyPricipleView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{

// TODO: add extra initialization before printing
}

void CMyPricipleView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{

// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CMyPricipleView diagnostics

#ifdef _DEBUG
void CMyPricipleView::AssertValid() const
{

CView::AssertValid();
}

void CMyPricipleView::Dump(CDumpContext& dc) const
{

CView::Dump(dc);


}

CMyPricipleDoc* CMyPricipleView::GetDocument() // non-debug version is inline

{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMyPricipleDoc)));
return (CMyPricipleDoc*)m_pDocument;

}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CMyPricipleView message handlers

void CMyPricipleView::OnMtriangle()

{
// TODO: Add your command handler code here
m_dSort=4;

}

//相应按下鼠标消息
void CMyPricipleView::OnLButtonDown(UINT nFlags, CPoint point)
{

// TODO: Add your message handler code here and/or call default
int i=0;
CDC* pDC=GetDC();
CRectTracker tracker;
POINT ps,pe,rect[4];
switch(m_dSort)
{
case 0:
case 1:
case 2:
case 3:


break;
case 7:
if(tracker.TrackRubberBand(this,point,false))


pDC->Rectangle(&tracker.m_rect);
for(i=0;i{


ps=polyGP[i];
pe=polyGP[++i];
CohenSutherlandLineClip(pDC,ps,pe,&tracker.m_rect);


}
m_PolygonNum=0;
break;


default:


p1=point;

break;
}
CView::OnLButtonDown(nFlags, point);


}

//相应抬起鼠标消息
void CMyPricipleView::OnLButtonUp(UINT nFlags, CPoint point)
{


// TODO: Add your message handler code here and/or call default
CDC* pDC=GetDC();
switch(m_dSort)
{
case 0:
case 1:
case 3:
case 4://三角形


polyGP[m_PolygonNum++]=point;
pDC->SetPixel(point.x,point.y,RGB(255,0,0));
if(m_PolygonNum==3)
{


m_Triangle.drawtriangle(pDC,polyGP,m_pColor);
inLength=m_PolygonNum;
m_PolygonNum=0;


}
break;


c

ase 5:
polyGP[m_PolygonNum++]=point;
pDC->SetPixel(point.x,point.y,RGB(255,0,0));
if(m_PolygonNum>20)


MessageBox("您的输入超过了本程序允许的最大顶点个数
20!\t\n绘图中
止!!",NULL,MB_OK);

break;
}
CView::OnLButtonUp(nFlags, point);


}

//完成CohenSutherlandLineClip函数
void CMyPricipleView::CohenSutherlandLineClip(CDC *pDC,POINT p1, POINT p2, CRect *rect)
{

bool accept,done;
OutCode outCode0,outCode1;
OutCode *outCodeOut;


float x,y,x0,y0,x1,y1;


x0=(float)p1.x;
y0=(float)p1.y;
x1=(float)p2.x;
y1=(float)p2.y;


accept=false;
done=false;
CompOutCode(x0,y0,rect,&outCode0);
CompOutCode(x1,y1,rect,&outCode1);


do{
if(outCode0.all==0&&outCode1.all==0)
{//完全可见


accept=true;
done=true;
}
//// else if((outCode0.all & outCode1.all)!= 0)//显然不可见条件有误
else if((outCode0.left & outCode1.left)!= 0||(outCode0.right & outCode1.right)!= 0||
(outCode0.top & outCode1.top)!= 0||(outCode0.bottom & outCode1.bottom)!= 0)

done=true;
else
{//进行求交测试


if(outCode0.all!=0)//判断哪一点位于窗口之外
outCodeOut=&outCode0;
else


outCodeOut=&outCode1;
if(outCodeOut->left)
{//线段与窗口的左边求交


y=y0+(y1-y0)*(rect->left-x0)/(x1-x0);

x=(float)rect->left;
}
else if(outCodeOut->top)
{//线段与窗口的上边求交


x=x0+(x1-x0)*(rect->bottom-y0)/(y1-y0);

y=(float)rect->bottom;
}
else if(outCodeOut->right)
{//线段与窗口的右边求交


y=y0+(y1-y0)*(rect->right-x0)/(x1-x0);

x=(float)rect->right;
}
else if(outCodeOut->bottom)
{//线段与窗口的下边求交


x=x0+(x1-x0)*(rect->top-y0)/(y1-y0);
y=(float)rect->top;



}

if(outCodeOut->all==outCode0.all)/*以交点为界,将线段位于窗口所在直线的外侧部分丢
弃*/

{ /*对剩余的部分继续裁剪
*/
x0=x;
y0=y;
CompOutCode(x0,y0,rect,&outCode0);

}
else
{


x1=x;
y1=y;
CompOutCode(x1,y1,rect,&outCode1);


}

}
}while(done!=true);


if(accept)

{
CPen Pen(PS_SOLID,2,~m_pColor);
pDC->SelectObject(&Pen);
pDC->MoveTo((int)x0,(int)y0);
pDC->LineTo((int)x1,(int)y1);


}
}


void CMyPricipleView::CompOutCode(float x, float y, CRect *rect, OutCode *outCode)

{
outCode->all=0;
outCode->top=outCode->bottom=0;
if(y>(float)rect->bottom)
{


outCode->top=1;

outCode->all+=1;
}
else if(y<(float)rect->top)
{


outCode->bottom=1;

outCode->all+=1;
}
outCode->right=outCode->left=0;
if(x>(float)rect->right)
{



outCode->right=1;

outCode->all+=1;
}
else if(x<(float)rect->left)
{


outCode->left=1;
outCode->all+=1;
}


}

void CMyPricipleView::OnMscan()

{
// TODO: Add your command handler code here
m_dSort=5;
CDC *pDC=GetDC();
OnDraw(pDC);
pDC->TextOut(50,50,"单击左键确定多边形顶点,右击开始绘图"

);

}

void CMyPricipleView::OnRButtonDown(UINT nFlags, CPoint point)

{
// TODO: Add your message handler code here and/or call default
CDC *pDC=GetDC();
if(m_dSort==5)
{

if(m_PolygonNum>=3)
m_polygon.drawpolygon(pDC,polyGP,m_PolygonNum,m_pColor);
else

MessageBox("顶点数不足三个,请重新设定!",NULL,MB_OK);
inLength=m_PolygonNum;
m_PolygonNum=0;

}

CView::OnRButtonDown(nFlags, point);
}

//填充颜色的选择
void CMyPricipleView::OnMfill()
{

// TODO: Add your command handler code here
m_dSort=6;
m_oColor=m_pColor;
CColorDialog ColorDialog;
if(ColorDialog.DoModal()==IDOK)



m_pColor=ColorDialog.GetColor();
UpdateData(0);
}



相关文档
最新文档