填充算法C++实现
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 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].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->x
break;//找到插入点
else if(p->x==cp->x)
{//当
x值相等时
if(p->deltax
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->x
于绘制自交多边形
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;i
{
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->x
break;//找到插入点
else if(p->x==cp->x)
{
//当
x值相等时
if(p->deltax
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].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->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->x
p1=p3;
else
{
p1=p1->next;
p2=p3;
}
}
else if(y==p2->ymax)
{//删除
p2
if(p3->x
{
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);
}