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