Bresenham圆的生成算法

圆,最开始我们学习的时候,圆是怎么生成的?
给出圆心坐标(xc, yc)和半径r,逐点画出一个圆周的公式有下列两种:

1.直角坐标法

推导出:

2.极坐标法

当θ从0到π作递增时,由此式便可求出圆周上均匀分布的360个点的(x, y)坐标。

利用圆周坐标的对称性,此算法还可以简化。将圆周分为8个象限,只要将第1a象限中的圆周光栅点求出,其余7部分圆周就可以通过对称法则计算出来。

设圆的半径为r。先考虑圆心在(0, 0),并从x=0、y=r开始的顺时针方向的1/8圆周的生成过程。在这种情况下,x每步增加1,从x=0开始,到x=y结束。即有
xi+1 = xi + 1
相应的yi+1则在两种可能中选择:
yi+1 = yi 或者 yi+1 = yi-1

选择的原则是考察精确值y是靠近yi还是靠近yi-1,计算式为

pi=d1-d2,并代入d1d2,则有

这里我们把pi称为误差

根据上面的推导,圆周生成算法思想如下:
⒈ 求误差初值,p1=3-2r,i=1,画点(0, r);
⒉ 求下一个光栅位置,其中xi+1=xi+1,如果pi<0,则yi+1=yi,否则yi+1=yi-1;
⒊ 画点(xi+1, yi+1);
⒋ 计算下一个误差,如果pi<0,则pi+1=pi+4xi+6,否则,pi+1= pi+4(xi-yi)+10;
⒌ i=i+1,如果x=y,则结束,否则返回步骤2。

代码如下:

#include "graphics.h"
#include <conio.h>
#include "windows.h"
#include <math.h>

void plot_circle_points(int xc,int yc,int x,int y,COLORREF c)//根据对称性画出另外7部分的点
{
	putpixel(xc+x, yc+y, c);
	putpixel(xc-x, yc+y, c);
	putpixel(xc+x, yc-y, c);
	putpixel(xc-x, yc-y, c);
	putpixel(xc+y, yc+x, c);
	putpixel(xc-y, yc+x, c);
	putpixel(xc+y, yc-x, c);
	putpixel(xc-y, yc-x, c);
}


void BresenhamCircle(int x1,int y1,int r,COLORREF c)//圆的生成
{
	int x,y,p;
	x=0;
	y=r;
	p=3-2*r;
	while(x<y)
	{
		plot_circle_points(x1,y1,x,y,c);
		if(p<0)
			p=p+4*x+6;
		else
		{
			p=p+4*(x-y)+10;
			y-=1;
		}
		x+=1;
	}
	if(x==y)
	plot_circle_points(x1,y1,x,y,c);
}

void main()
{
	int gd=DETECT,gm; /*图形屏幕初始化*/
	initgraph(&gd,&gm,"");

	BresenhamCircle(200,200,50,LIGHTBLUE);
	BresenhamCircle(300,200,50,WHITE);
	BresenhamCircle(400,200,50,RED);
	BresenhamCircle(250,250,50,YELLOW);
	BresenhamCircle(350,250,50,GREEN);

	getch();
 	closegraph();
}    

最终效果:

  • 9
    点赞
  • 59
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值