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

1,045 阅读2分钟

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

1 引言

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

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

2 思路

2.1 圆

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

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

算法大致步骤如下:

  1. 首先将圆心在原点的圆标准方程化为隐式形式,得到:F(x,y)=x2+y2R2F(x,y)=x^2+y^2-R^2

  2. 递归判断两个待选点中点与圆弧的位置关系,进而在两个待选点中选择其一,再继续向前判断

  3. 表达式的两种情况:

    • d0,d=d+2x+3d\leq0,d=d+2x+3
    • d>0,d=d+2(xy)+5d>0,d=d+2(x-y)+5
  4. 递归构造表达式,循环保存点坐标,最后一次绘制

2.2 椭圆

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

算法大致步骤如下:

  1. 首先将中心点在圆心的椭圆标准方程化为隐式形式,得到:F(x,y)=b2x2+a2y2a2b2F(x,y)=b^2x^2+a^2y^2-a^2b^2

  2. 再找到X方向的法向量与y方向的法向量相等的点作为分界点,以此分为椭圆弧的上半部分和下半部分

  3. 分别对上半部分和下半部分构造不同的初始判别表达式

    • d=b2a2+0.25a2d=b^2-a^2+0.25a^2
    • d=b2(x+0.5)2+a2(y1)2a2b2d=b^2(x+0.5)^2+a^2(y-1)^2-a^2b^2
  4. 递归构造表达式,循环保存点坐标,最后一次绘制

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)