声明:凡代码问题,欢迎私信或在评论区沟通。承蒙指正,一起成长!
目录
实验2:按下鼠标拖动绘制椭圆,然后在区域内双击鼠标,填充该椭圆区域。
1. 了解并掌握圆形绘制算法;
2.掌握多边形的填充算法,已知多边形的顶点,通过绘制直线的函数或种子填充算法填充该多边形。
一、实验1:绘制如下图所示扇形,并进行填充。
(1)程序源代码
// shiyan2View.cpp : implementation of the CShiyan2View class
//
#include "stdafx.h"
#include "shiyan2.h"
#include <math.h>
#include "shiyan2Doc.h"
#include "shiyan2View.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//int x1,y1,x2,y2; //全局变量圆弧首尾两点坐标
/
// CShiyan2View
IMPLEMENT_DYNCREATE(CShiyan2View, CView)
BEGIN_MESSAGE_MAP(CShiyan2View, CView)
//{{AFX_MSG_MAP(CShiyan2View)
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_LBUTTONDBLCLK()
//}}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()
/
// CShiyan2View construction/destruction
CShiyan2View::CShiyan2View()
{
// TODO: add construction code here
}
CShiyan2View::~CShiyan2View()
{
}
BOOL CShiyan2View::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
/
// CShiyan2View drawing
void Midpointcircle_2(int radius,int color,CDC *p)
{
int x,y,d,E=12,SE=20-8*radius;
x=0;y=radius;
d=3-4*radius;
p->SetPixel(x+200,y+150,color);
while(y>x)
{
if(d<=0)
{
d+=E;
SE+=8;
}
else
{
d+=SE;
SE+=16;
y--;
}
E+=8;
x++;
p->SetPixel(x+200,y+150,color);
}
}
/*
void Midpointcircle_1(int radius,int color,CDC *p)
{
int x,y; float d;x=0;y=radius;
d=3.0/4-radius;
p->SetPixel(x+500,y+150,color);
while(y>x)
{
if(d<=0)
d+=2.0*x+3;
else
{
d+=2.0*(x-y)+5;
y--;
}
x++;
p->SetPixel(-x+500,-y+150,color);
p->SetPixel(x+500,-y+150,color);
}
x1=-x+500;y1=-y+150;
x2=x+500;y2=-y+150;
}
*/
void B(int x,int y,int c1,int c2,CDC *p)
{
long c;
c=p->GetPixel(x,y);
if(c!=c1 && c!=c2)
{
p->SetPixel(x,y,c1);
B(x+1,y,c1,c2,p); B(x-1,y,c1,c2,p);
B(x,y+1,c1,c2,p); B(x,y-1,c1,c2,p);
}
}
///
///
///
struct Edge
{
//用来存储边的
int yUpper;
float xIntersect, dxPerScan;
struct Edge * next; //指向下一条边
} tEdge; //结构体变
///
void insertEdge(Edge *list,Edge *edge)
{
Edge*p,*q=list;
p=q->next;
while(p!=NULL)
{
if(edge->xIntersect<p->xIntersect)
p=NULL;
else
{
q=p;
p=p->next;
}
}
edge->next=q->next;
q->next=edge;
}
///
int yNext(int k,int cnt, CPoint * pts)
{
int j;
if((k+1)>(cnt-1))
j=0;
else
j=k+1;
while(pts[k].y==pts[j].y)
{
if((k+1)>(cnt-1))
j=0;
else
j++;
}
return pts[j].y;
}
void makeEdgeRec (CPoint lower, CPoint upper, int yComp, Edge * edge, Edge *edges[])
{
edge->dxPerScan=(float)(upper.x-lower.x)/(upper.y-lower.y);
edge->xIntersect=lower.x;
if(upper.y<yComp)
edge->yUpper=upper.y-1;
else
edge->yUpper=upper.y;
insertEdge(edges[lower.y],edge);
}
///
void buildEdgeList (int cnt, CPoint *pts, Edge *edges[])
{
Edge * edge;
CPoint v1,v2;
int i,yPrev=pts[cnt-2].y;
v1.x=pts[cnt-1].x;
v1.y=pts[cnt-1].y;
for(i=0; i<cnt; i++)
{
v2=pts[i];
if(v1.y!=v2.y)
{
edge=(Edge*)malloc(sizeof(Edge));
if(v1.y<v2.y)
makeEdgeRec(v1,v2,yNext(i,cnt,pts),edge,edges);
else
makeEdgeRec(v2,v1,yPrev,edge,edges);
}
yPrev=v1.y;
v1=v2;
}
}
///
void buildActiveList (int scan, Edge * active, Edge * edges[])
{
Edge*p,*q;
p=edges[scan]->next;
while(p)
{
q=p->next;
insertEdge(active,p);
p=q;
}
}
void fillScan (int scan, Edge * active, CDC * pDC)
{
Edge*p1,*p2;
int i;
p1=active->next;
while(p1)
{
p2=p1->next;
for(i=p1->xIntersect; i<p2->xIntersect; i++)
pDC->SetPixel(i,scan,0);
p1=p2->next;
}
}
void deleteAfter(Edge *q)
{
Edge * p=q-> next;
q->next=p->next;
free(p);
}
//
void updateActiveList (int scan, Edge * active)
{
Edge *q=active,*p=active->next;
while(p)
if(scan>=p->yUpper)
{
p=p->next;
deleteAfter(q);
}
else
{
p->xIntersect=p->xIntersect+p->dxPerScan;
q=p;
p=p->next;
}
}
//
void resortActiveList(Edge *active)
{
Edge*q,*p=active->next;
active->next=NULL;
while(p)
{
q=p->next;
insertEdge(active,p);
p=q;
}
}
///
void scanFill(int cnt,CPoint *pts,CDC *pDC)
{
Edge *edges[300],*active; //edges是指针数组
int i,scan;
for(i=0; i<300; i++)
{
edges[i]=(Edge*)malloc(sizeof(Edge));//开辟内存区
edges[i]->next=NULL;
}
buildEdgeList(cnt,pts,edges);
active=(Edge*)malloc(sizeof(Edge));
active->next=NULL;
for(scan=0; scan<300; scan++)
{
buildActiveList(scan,active,edges);
if(active->next)
{
fillScan(scan,active,pDC);
updateActiveList(scan,active);
resortActiveList(active);
}
}
}
///
///
///
CPoint vx[6];
//画六边形 104.7 *6
void Hexagan(CDC *p)
{
int r=50;
int j=0;
p->MoveTo((int)(200+r*cos(52/100)),(int)(200+r*sin(52/100)));
for(float i=0;i<=628;i=i+104.7)
{
int a=(int)(200+r*cos(i/100));
int b=(int)(200+r*sin(i/100));
p->LineTo(a,b);
vx[j].x=a, vx[j].y=b;
Sleep(500);
}
p->LineTo((int)(200+r*cos(52/100)),(int)(200+r*sin(52/100)));
vx[j].x=(int)(200+r*cos(52/100));
vx[j].y=(int)(200+r*sin(52/100));
}
void CShiyan2View::OnDraw(CDC* pDC)
{
CShiyan2Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
/*
Midpointcircle_1(145,0,pDC);
pDC->MoveTo(x1,y1);
pDC->LineTo(500,150);
pDC->LineTo(x2,y2);
B(500,1,255,0,pDC);
*/
// Hexagan(pDC);
int cnt=6;
CPoint he[6];
he[0].x=200,he[0].y=100;
he[1].x=300,he[1].y=100;
he[2].x=350,he[2].y=187;
he[3].x=300,he[3].y=274;
he[4].x=200,he[4].y=274;
he[5].x=150,he[5].y=187;
pDC->MoveTo(he[0].x,he[0].y);
pDC->LineTo(he[1].x,he[1].y);
pDC->LineTo(he[2].x,he[2].y);
pDC->LineTo(he[3].x,he[3].y);
pDC->LineTo(he[4].x,he[4].y);
pDC->LineTo(he[5].x,he[5].y);
pDC->LineTo(he[0].x,he[0].y);
scanFill(cnt,he,pDC);
// TODO: add draw code for native data here
}
/
// CShiyan2View printing
BOOL CShiyan2View::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CShiyan2View::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CShiyan2View::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
/
// CShiyan2View diagnostics
#ifdef _DEBUG
void CShiyan2View::AssertValid() const
{
CView::AssertValid();
}
void CShiyan2View::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CShiyan2Doc* CShiyan2View::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CShiyan2Doc)));
return (CShiyan2Doc*)m_pDocument;
}
#endif //_DEBUG
/
// CShiyan2View message handlers
CPoint DownPoint;
//全局变量
void CShiyan2View::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
DownPoint=point;
CView::OnLButtonDown(nFlags, point);
}
void CShiyan2View::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CDC *p=GetDC();
p->Ellipse(DownPoint.x,DownPoint.y,point.x,point.y);
// p->Rectangle(DownPoint.x,DownPoint.y,point.x,point.y);
CView::OnLButtonUp(nFlags, point);
}
void CShiyan2View::OnLButtonDblClk(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CDC *pDC=GetDC();
B(point.x,point.y,90000,0,pDC);
// scanFill(4,&point,pDC);
CView::OnLButtonDblClk(nFlags, point);
}
(2)运行结果
半径R=145;圆心坐标(500,150);
二、实验2:编写程序,运行后按下鼠标拖动绘制椭圆,然后在区域内双击鼠标,填充该椭圆区域。
(1)程序源代码
CPoint DownPoint;
//全局变量
void CShiyan2View::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
DownPoint=point;
CView::OnLButtonDown(nFlags, point);
}
void CShiyan2View::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CDC *p=GetDC();
p->Ellipse(DownPoint.x,DownPoint.y,point.x,point.y);
CView::OnLButtonUp(nFlags, point);
}
void CShiyan2View::OnLButtonDblClk(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CDC *pDC=GetDC();
B(point.x,point.y,90000,0,pDC);
CView::OnLButtonDblClk(nFlags, point);
}
(2)运行结果
三、实验3:绘制正六边形,并使用扫描线方式进行填充。
(1)程序源代码
/// 扫描线填充函数 /
struct Edge
{
//用来存储边的
int yUpper;
float xIntersect, dxPerScan;
struct Edge * next; //指向下一条边
} tEdge; //结构体变
///
void insertEdge(Edge *list,Edge *edge)
{
Edge*p,*q=list;
p=q->next;
while(p!=NULL)
{
if(edge->xIntersect<p->xIntersect)
p=NULL;
else
{
q=p;
p=p->next;
}
}
edge->next=q->next;
q->next=edge;
}
///
int yNext(int k,int cnt, CPoint * pts)
{
int j;
if((k+1)>(cnt-1))
j=0;
else
j=k+1;
while(pts[k].y==pts[j].y)
{
if((k+1)>(cnt-1))
j=0;
else
j++;
}
return pts[j].y;
}
void makeEdgeRec (CPoint lower, CPoint upper, int yComp, Edge * edge, Edge *edges[])
{
edge->dxPerScan=(float)(upper.x-lower.x)/(upper.y-lower.y);
edge->xIntersect=lower.x;
if(upper.y<yComp)
edge->yUpper=upper.y-1;
else
edge->yUpper=upper.y;
insertEdge(edges[lower.y],edge);
}
///
void buildEdgeList (int cnt, CPoint *pts, Edge *edges[])
{
Edge * edge;
CPoint v1,v2;
int i,yPrev=pts[cnt-2].y;
v1.x=pts[cnt-1].x;
v1.y=pts[cnt-1].y;
for(i=0; i<cnt; i++)
{
v2=pts[i];
if(v1.y!=v2.y)
{
edge=(Edge*)malloc(sizeof(Edge));
if(v1.y<v2.y)
makeEdgeRec(v1,v2,yNext(i,cnt,pts),edge,edges);
else
makeEdgeRec(v2,v1,yPrev,edge,edges);
}
yPrev=v1.y;
v1=v2;
}
}
///
void buildActiveList (int scan, Edge * active, Edge * edges[])
{
Edge*p,*q;
p=edges[scan]->next;
while(p)
{
q=p->next;
insertEdge(active,p);
p=q;
}
}
void fillScan (int scan, Edge * active, CDC * pDC)
{
Edge*p1,*p2;
int i;
p1=active->next;
while(p1)
{
p2=p1->next;
for(i=p1->xIntersect; i<p2->xIntersect; i++)
pDC->SetPixel(i,scan,0);
p1=p2->next;
}
}
void deleteAfter(Edge *q)
{
Edge * p=q-> next;
q->next=p->next;
free(p);
}
//
void updateActiveList (int scan, Edge * active)
{
Edge *q=active,*p=active->next;
while(p)
if(scan>=p->yUpper)
{
p=p->next;
deleteAfter(q);
}
else
{
p->xIntersect=p->xIntersect+p->dxPerScan;
q=p;
p=p->next;
}
}
//
void resortActiveList(Edge *active)
{
Edge*q,*p=active->next;
active->next=NULL;
while(p)
{
q=p->next;
insertEdge(active,p);
p=q;
}
}
///
void scanFill(int cnt,CPoint *pts,CDC *pDC)
{
Edge *edges[300],*active; //edges是指针数组
int i,scan;
for(i=0; i<300; i++)
{
edges[i]=(Edge*)malloc(sizeof(Edge));//开辟内存区
edges[i]->next=NULL;
}
buildEdgeList(cnt,pts,edges);
active=(Edge*)malloc(sizeof(Edge));
active->next=NULL;
for(scan=0; scan<300; scan++)
{
buildActiveList(scan,active,edges);
if(active->next)
{
fillScan(scan,active,pDC);
updateActiveList(scan,active);
resortActiveList(active);
}
}
}
/// 扫描线填充函数 /
void CShiyan2View::OnDraw(CDC* pDC)
{
CShiyan2Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
int cnt=6;
CPoint he[6];
he[0].x=200,he[0].y=100;
he[1].x=300,he[1].y=100;
he[2].x=350,he[2].y=187;
he[3].x=300,he[3].y=274;
he[4].x=200,he[4].y=274;
he[5].x=150,he[5].y=187;
pDC->MoveTo(he[0].x,he[0].y);
pDC->LineTo(he[1].x,he[1].y);
pDC->LineTo(he[2].x,he[2].y);
pDC->LineTo(he[3].x,he[3].y);
pDC->LineTo(he[4].x,he[4].y);
pDC->LineTo(he[5].x,he[5].y);
pDC->LineTo(he[0].x,he[0].y);
scanFill(cnt,he,pDC);
// TODO: add draw code for native data here
}
(2)运行结果