【计算机图形学】圆与椭圆的绘制——MATLAB实现

这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战

1 引言

圆与椭圆的绘制,其核心算法也是Bresenham中点算法,只是分界点的条件不同。

由于圆与椭圆的对称性也有所区别,如圆是八分之一对称,而椭圆是四分之一对称,故绘制方法也有所差异。

2 思路

2.1 圆

假设从(0,R)开始推算递归公式,当x=y时,即X方向的法向量与y方向的法向量相等。

故只需绘制八分之一圆弧,再根据对称性完成整个圆的绘制。

算法大致步骤如下:

  1. 首先将圆心在原点的圆标准方程化为隐式形式,得到:F(x,y)=x2+y2−R2F(x,y)=x^2+y^2-R^2F(x,y)=x2+y2−R2
  2. 递归判断两个待选点中点与圆弧的位置关系,进而在两个待选点中选择其一,再继续向前判断
  3. 表达式的两种情况:
* 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
  1. 递归构造表达式,循环保存点坐标,最后一次绘制

2.2 椭圆

关于椭圆,只需绘制第一象限的椭圆弧,再根据其对称性完成整个椭圆的绘制

算法大致步骤如下:

  1. 首先将中心点在圆心的椭圆标准方程化为隐式形式,得到:F(x,y)=b2x2+a2y2−a2b2F(x,y)=b^2x^2+a^2y^2-a^2b^2F(x,y)=b2x2+a2y2−a2b2
  2. 再找到X方向的法向量与y方向的法向量相等的点作为分界点,以此分为椭圆弧的上半部分和下半部分
  3. 分别对上半部分和下半部分构造不同的初始判别表达式
* 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
  1. 递归构造表达式,循环保存点坐标,最后一次绘制

3 过程

3.1 圆

首先,为判断表达式赋初始值,即d=1.25-R;

再循环判断,并保存点坐标

1
2
3
4
5
6
7
8
9
10
11
matlab复制代码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坐标矩阵赋值

1
2
3
4
5
6
7
8
9
10
11
12
matlab复制代码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

同理,在下半部分,构造相应的表达式如下:

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
2
3
matlab复制代码%平移坐标原点
x=x+m;
y=y+n;

如需导出坐标矩阵,还可分段保存点坐标

1
2
3
matlab复制代码%存储椭圆上点坐标
xx=[x,fliplr(x),2*m-x,fliplr(2*m-x)];
yy=[y,fliplr(2*n-y),2*n-y,fliplr(y)];

最后只需一次绘制,即可完成

1
matlab复制代码plot(xx,yy,'y-');

4 结果

同时绘制圆和椭圆再叠加,结果如下:

完整代码请见
Bresenham_circle(gitee.com)

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%