这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战
1 引言
圆与椭圆的绘制,其核心算法也是Bresenham中点算法,只是分界点的条件不同。
由于圆与椭圆的对称性也有所区别,如圆是八分之一对称,而椭圆是四分之一对称,故绘制方法也有所差异。
2 思路
2.1 圆
假设从(0,R)开始推算递归公式,当x=y时,即X方向的法向量与y方向的法向量相等。
故只需绘制八分之一圆弧,再根据对称性完成整个圆的绘制。
算法大致步骤如下:
-
首先将圆心在原点的圆标准方程化为隐式形式,得到:
-
递归判断两个待选点中点与圆弧的位置关系,进而在两个待选点中选择其一,再继续向前判断
-
表达式的两种情况:
-
递归构造表达式,循环保存点坐标,最后一次绘制
2.2 椭圆
关于椭圆,只需绘制第一象限的椭圆弧,再根据其对称性完成整个椭圆的绘制
算法大致步骤如下:
-
首先将中心点在圆心的椭圆标准方程化为隐式形式,得到:
-
再找到X方向的法向量与y方向的法向量相等的点作为分界点,以此分为椭圆弧的上半部分和下半部分
-
分别对上半部分和下半部分构造不同的初始判别表达式
-
递归构造表达式,循环保存点坐标,最后一次绘制
3 过程
3.1 圆
首先,为判断表达式赋初始值,即d=1.25-R;
再循环判断,并保存点坐标
while x<=(2^0.5/2)*R
if d<0
d=d+2*(x(end))+3;
x(end+1)=x(end)+1;
y(end+1)=y(end);
else
d=d+2*(x(end)-y(end))+5;
x(end+1)=x(end)+1;
y(end+1)=y(end)-1;
end
end
复制代码
如需导出坐标矩阵,还可分段保存点坐标;最后一次绘制即可完成。
3.2 椭圆
首先,在第一象限椭圆弧上半部分,构造判断表达式,并循环为x,y坐标矩阵赋值
d=b*b-a*a+0.25*a*a;
while(b*b*x(end)<a*a*y(end))
if(d<=0)
d=d+b*b*(2*x(end)+3);
x(end+1)=x(end)+1;
y(end+1)=y(end);
else
d=d+b*b*(2*x(end)+3)+2*a*a*(1-y(end));
x(end+1)=x(end)+1;
y(end+1)=y(end)-1;
end
end
复制代码
同理,在下半部分,构造相应的表达式如下:
d=b*b*(x(end)+0.5)*(x(end)+0.5)+a*a*(y(end)-1)*(y(end)-1)-a*a*b*b;
复制代码
如需转换为中心点在任意位置的情况,需将原点平移,调用时再将平移参数作为函数的入口参数传入
%平移坐标原点
x=x+m;
y=y+n;
复制代码
如需导出坐标矩阵,还可分段保存点坐标
%存储椭圆上点坐标
xx=[x,fliplr(x),2*m-x,fliplr(2*m-x)];
yy=[y,fliplr(2*n-y),2*n-y,fliplr(y)];
复制代码
最后只需一次绘制,即可完成
plot(xx,yy,'y-');
复制代码
4 结果
同时绘制圆和椭圆再叠加,结果如下:
完整代码请见
Bresenham_circle(gitee.com)
近期评论