小张学算法:0.bresenham画圆算法

一个圆可以切成8块,这每一块都对称;
沿x轴对称,y值符号变,x不变;
沿y轴对称,x值不变,y符号变相反;
沿y=x对称,y和x交换。

一个概念:这样我们只需要画第一象限的1/8圆弧即可;沿x轴方向进行描点画圆,x每次增加1,y减1否,需要做判断,这也是我们算法的核心:
y到底要不要减小,我们取(x+1,y-0.5)的点到圆心的距离与r作比较,如果该点在园外,则减,否则不变。即 插值公式:F(x+1, y-0.5) = (x+1)2+(y-0.5)2 - r2然后递推得到递推公式:
1. 当d=F(x+1,y-0.5)-r2 > 0: 则下一个d值:d = F(x + 2, y - 1.5) = (x + 2)^2 + (y - 1.5)^2 - R^2 = (x + 1)^2 + (x - 0.5)^2 - R^2 + 2x + 3 - 2y + 2 = d + 2x - 2y + 5
2. 当前d = F(x + 1, y - 0.5) < 0,则y不变,只有x增1,则下一d值为d = F(x + 2, y - 0.5) = d + 2x + 3
3. d的初值,d0 = F(1, R - 0.5) = 1.25 - R,因为递推关系中只有整数运算,所以d取初值1 - R

python代码:


from matplotlib import pyplot as plt
import numpy as np

def draw_circle(centre, r, out):
	a = 0
	b = r
	d = 1-r
	x0 = centre[0]
	y0 = centre[1]
	while a <= b:
		out[0].append(x0+a)
		out[1].append(y0+b)
		out[0].append(x0+b)
		out[1].append(y0+a)   #1/8circle duicheng

		out[0].append(x0-a) #y duicheng
		out[1].append(y0+b)
		out[0].append(x0-b)
		out[1].append(y0+a)   

		out[0].append(x0+a) #xduicheng
		out[1].append(y0-b)
		out[0].append(x0+b)
		out[1].append(y0-a)   

		out[0].append(x0-a) #yuandian duicheng
		out[1].append(y0-b)
		out[0].append(x0-b)
		out[1].append(y0-a)  
		a = a + 1
		if (d < 0):
			d = d + 2*a + 3
		else:
			d = d + 5 + 2*(a-b)
			b = b - 1
pix_array=[[]for i in range(2)]

draw_circle((0,0), 1000, pix_array)

fig = plt.figure()
ax1 = fig.add_subplot(1,1,1)
ax1.scatter(pix_array[0], pix_array[1], marker='.')
plt.show()

结合我做嵌入式正点原子的代码:
他这里给系数都乘2了,效果和上面一样,bresenham算法对半径越大的,越圆。

//画圆
void LCD_Draw_Circle(u16 x0,u16 y0,u8 r)
{
	int a,b;
	int di;
	a=0;b=r;	  
	di=3-(r<<1);             //判断下个点位置的标志
	while(a<=b)
	{
		LCD_DrawPoint(x0+a,y0-b);             //5
 		LCD_DrawPoint(x0+b,y0-a);             //0           
		LCD_DrawPoint(x0+b,y0+a);             //4               
		LCD_DrawPoint(x0+a,y0+b);             //6 
		LCD_DrawPoint(x0-a,y0+b);             //1       
 		LCD_DrawPoint(x0-b,y0+a);             
		LCD_DrawPoint(x0-a,y0-b);             //2             
  		LCD_DrawPoint(x0-b,y0-a);             //7     	         
		a++;
		//使用Bresenham算法画圆     
		if(di<0)di +=4*a+6;	  
		else
		{
			di+=10+4*(a-b);   
			b--;
		} 						    
	}
} 

https://blog.csdn.net/bagboy_taobao_com/article/details/5774628
正点原子stm32 lcd驱动教程

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值