实验目的:
- 理解扫描转换的目的
- 掌握Bresenham圆扫描转换的算法
实验内容:
一、Bresenham圆扫描转换
圆的八对称性:
根据圆的对称性,可以用四条对称轴x=0,y=0,x=y,x=-y将圆分成8等份。只要绘制出第一象限内的1/8圆弧,根据对称性就可绘制出整圆,这称为八分法画圆算法。假定第一象限内的任意点为P(x,y),可以顺时针确定另外7个点:P(y,x),P(-y,x),P(x,-y),P(-x,-y),P(-y,-x),P(y,-x),P(-x,y)。
绘制第一象限内的1/8圆弧的算法如下:
1.初始化,x=0,y=r,d=3-2r
2.当 xi < yi 时,执行以下操作:
画像素点(xi, yi)
求下一个像素点:
求下一步的误差:
3.若 xi = yi,画像素点 (x, y);否则重复第二步
练习:
请完成下面的程序:
(1) 使用Bresenham圆扫描转换算法,完成圆心在(100,100),半径是20的圆的绘制。
代码:
在Bresenham_CircleView.h中:
public:
void Bresenham_Circle(CPoint ¢er,int r,CDC *pdc,COLORREF color );
在Bresenham_CircleView.cpp中:
void CBresenham_CircleView::OnDraw(CDC* pDC)
{
CBresenham_CircleDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
CPoint center(100,100);int r=20;
Bresenham_Circle(center,r,pDC,RGB(0,255,0));
// TODO: 在此处为本机数据添加绘制代码
}
void CBresenham_CircleView::Bresenham_Circle(CPoint ¢er,int r ,CDC *pdc,COLORREF color )
{
CPoint center1=center;
center1.x=0;center1.y=r;
int d=3-2*r;
//pdc->SetPixel(center1,color);
pdc->SetPixel((center1.x+100),(center1.y+100),color);
pdc->SetPixel((center1.x+100),(-center1.y+100),color);
pdc->SetPixel((-center1.x+100),(-center1.y+100),color);
pdc->SetPixel((-center1.x+100),(center1.y+100),color);
pdc->SetPixel((center1.y+100),(center1.x+100),color);
pdc->SetPixel((center1.y+100),(-center1.x+100),color);
pdc->SetPixel((-center1.y+100),(-center1.x+100),color);
pdc->SetPixel((-center1.y+100),(center1.x+100),color);
while(center1.x<center1.y)
{
int temp_d=d;
center1.x++;
if(d<0)
{
center1.y=center1.y;
d=temp_d+4*center1.x+6;
}
else
{
center1.y=center1.y-1;
d=temp_d+4*(center1.x-center1.y)+10;
}
pdc->SetPixel((center1.x+100),(center1.y+100),color);
pdc->SetPixel((center1.x+100),(-center1.y+100),color);
pdc->SetPixel((-center1.x+100),(-center1.y+100),color);
pdc->SetPixel((-center1.x+100),(center1.y+100),color);
pdc->SetPixel((center1.y+100),(center1.x+100),color);
pdc->SetPixel((center1.y+100),(-center1.x+100),color);
pdc->SetPixel((-center1.y+100),(-center1.x+100),color);
pdc->SetPixel((-center1.y+100),(center1.x+100),color);
}
}
截图:
老师给的答案
public:
void BresenhamCircle(CPoint center,int radius,CDC *pdc,COLORREF color);
void CBresenhamCircleView::OnDraw(CDC* pDC)
{
CBresenhamCircleDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
CPoint center(100,100);int raduis=20;
BresenhamCircle(center,raduis,pDC,RGB(255,0,0,));
// TODO: 在此处为本机数据添加绘制代码
}
void CBresenhamCircleView::BresenhamCircle(CPoint center,int radius,CDC *pdc,COLORREF color)
{
CPoint p(0,radius);
int d = 3 - 2*radius;
while(p.x <= p.y)
{
pdc->SetPixelV(p.x+center.x,p.y+center.y,color);
pdc->SetPixelV(-p.x+center.x,p.y+center.y,color);
pdc->SetPixelV(p.x+center.x,-p.y+center.y,color);
pdc->SetPixelV(-p.x+center.x,-p.y+center.y,color);
pdc->SetPixelV(p.y+center.x,p.x+center.y,color);
pdc->SetPixelV(-p.y+center.x,p.x+center.y,color);
pdc->SetPixelV(p.y+center.x,-p.x+center.y,color);
pdc->SetPixelV(-p.y+center.x,-p.x+center.y,color);
if(d>=0)
{ d += 4*(p.x-p.y)+10;
p.y--;
p.x++;
}
else
{
d += 4*p.x+6;
p.x++;
}
}
}
截图: