算法系列之十三:椭圆的生成算法

椭圆和直线、圆一样,是图形学领域中的一种常见图元,椭圆的生成算法(光栅转换算法)也是图形学软件中最常见的生成算法之一。在平面解析几何中,椭圆的方程可以描述为(x – x0)2 / a2+ (y – y0)2 / b2 = 1,其中(x0, y0)是圆心坐标,ab是椭圆的长短轴,特别的,当(x0, y0)就是坐标中心点时,椭圆方程可以简化为x2 / a2 + y2 / b2 = 1。在计算机图形学中,椭圆图形也存在在点阵输出设备上显示或输出的问题,因此也需要一套光栅扫描转换算法。为了简化,我们先考虑圆心在原点的椭圆的生成,对于中心不是原点的椭圆,可以通过坐标的平移变换获得相应位置的椭圆。

在进行扫描转换之前,需要了解一下椭圆的对称性,如图(1)所示:

图(1)椭圆的对称性

中心在原点。焦点在坐标轴上的标准椭圆具有X轴对称、Y轴对称和原点对称特性,已知椭圆上第一象限的P点坐标是(x, y),则椭圆在另外三个象限的对称点分别是(x, -y)(-x, y)(-x, -y)。因此,只要画出第一象限的四分之一椭圆,就可以利用这三个对称性得到整个椭圆。

在光栅设备上输出椭圆有很多种方法,可以根据直角平面坐标方程直接求解点坐标,yekeyii利用极坐标方程求解,但是因为涉及到浮点数取整,效果都不好,一般都不使用直接求解的方式。本文就介绍几种计算机图形学中两种比较常用的椭圆生成方法:中点画椭圆算法和Bresenham椭圆生成算法。

1、 中点画椭圆法

中点在坐标原点,焦点在坐标轴上(轴对齐)的椭圆的平面集合方程是:

x2 / a2 + y2 / b2 = 1,也可以转化为如下非参数化方程形式:

F(x, y) = b2x2 + a2y2 - a2b2 = 0 (方程 1

无论是中点画线算法、中点画圆算法还是本节要介绍的中点画椭圆算法,对选择x方向像素Δ增量还是y方向像素Δ增量都是很敏感的。举个例子,如果某段圆弧上,x方向上增量+1个像素时,y方向上的增量如果 < 1,则比较适合用中点算法,如果y方向上的增量 > 1,就会产生一些跳跃的点,最后生成的光栅位图圆弧会有一些突变的点,看起来好像不在圆弧上。因此,对于中点画圆弧算法,要区分出椭圆弧上哪段Δx增量变化显著,哪段Δy增量变化显著,然后区别对待。由于椭圆的对称性,我们只考虑第一象限的椭圆圆弧,如图(2)所示:

图(2)第一象限椭圆弧示意图

定义椭圆弧上某点的切线法向量N如下:

对方程1分别求x偏导和y偏导,最后得到椭圆弧上(x,y)点处的法向量是(2b2x, 2a2y)。dy/dx = -1的点是椭圆弧上的分界点。此点之上的部分(橙褐色部分)椭圆弧法向量的y分量比较大,即:2b2(x + 1) < 2a2(y – 0.5);此点之下的部分(蓝紫色部分)椭圆弧法向量的x分量比较大,即:2b2(x + 1) > 2a2(y – 0.5)

对于图(2)中橙褐色标识的上部区域,y方向每变化1个单位,x方向变化大于一个单位,因此中点算法需要沿着x方向步进画点,x每次增量加1,求y的值。同理,对于图(2)中蓝紫色标识的下部区域,中点算法沿着y方向反向步进,y每次减1,求x的值。先来讨论上部区域椭圆弧的生成,如图(3)所示:

图(3)中点画椭圆算法对上部区域处理示意图

假设当前位置是P(xi, yi),则下一个可能的点就是P点右边的P1(xi+1, yi)点或右下方的P2(xi+1, yi-1)点,取舍的方法取决于判别式didi的定义如下:

di = F(xi+1, yi-0.5) = b2(xi+1)2 + a2(yi-0.5)2 – a2b2

di < 0,表示像素点P1P2的中点在椭圆内,这时可取P1为下一个像素点。此时xi+1 = xi + 1yi+1 = yi,代入判别式di得到di+1

di+1 = F(xi+1+1, yi+1-0.5) = b2(xi+2)2 + a2(yi-0.5)2 – a2b2 = di + b2(2xi + 3)

计算出di的增量是b2(2xi + 3)。同理,若di >= 0,表示像素点P1P2的中点在椭圆外,这时应当取P2为下一个像素点。此时xi+1 = xi + 1yi+1 = yi - 1,代入判别式di得到di+1

di+1 = F(xi+1+1, yi+1-0.5) = b2(xi+2)2 + a2(yi-1.5)2 – a2b2 = d1 + b2(2xi+3) + a2(-2yi+2)

计算出di的增量是b2(2xi+3)+a2(-2yi+2)。计算di的增量的目的是减少计算量,提高算法效率,每次判断一个点时,不必完整的计算判别式di,只需在上一次计算出的判别式上增加一个增量即可。

接下来继续讨论下部区域椭圆弧的生成,如图(4)所示:

图(4)中点画椭圆算法对下部区域处理示意图

假设当前位置是P(xi, yi),则下一个可能的点就是P点左下方的P1(xi -1, yi-1)点或下方的P2(xi, yi-1)点,取舍的方法同样取决于判别式didi的定义如下:

di = F(xi+0.5, yi-1) = b2(xi+0.5)2 + a2(yi-1)2 – a2b2

di < 0,表示像素点P1P2的中点在椭圆内,这时可取P2为下一个像素点。此时xi+1 = xi + 1yi+1 = yi - 1,代入判别式di得到di+1

di+1 = F(xi+1+0.5, yi+1-1) = b2(xi+1.5)2 + a2(yi-2)2 – a2b2 = di + b2(2xi+2)+a2(-2yi+3)

计算出di的增量是b2(2xi+2)+a2(-2yi+3)。同理,若di >= 0,表示像素点P1P2的中点在椭圆外,这时应当取P1为下一个像素点。此时xi+1 = xiyi+1 = yi - 1,代入判别式di得到di+1

di+1 = F(xi+1+0.5, yi+1-1) = b2(xi+0.5)2 + a2(yi-2)2 – a2b2 = d1 + a2(-2yi+3)

计算出di的增量是a2(-2yi+3)

中点画椭圆算法从(0, b)点开始,第一个中点是(1, b – 0.5),判别式d的初始值是:

d0 = F(1, b–0.5) = b2 + a2(-b+0.25)

上部区域生成算法的循环终止条件是:2b2(x + 1) >= 2a2(y – 0.5),下部区域的循环终止条件是y = 0,至此,中点画椭圆算法就可以完整给出了:

20void MP_Ellipse(int xc , int yc , int a, int b)

21{

22 double sqa = a * a;

23 double sqb = b * b;

24

25 double d = sqb + sqa * (-b + 0.25);

26 int x = 0;

27 int y = b;

28 EllipsePlot(xc, yc, x, y);

29 while( sqb * (x + 1) < sqa * (y - 0.5))

30 {

31 if (d < 0)

32 {

33 d += sqb * (2 * x + 3);

34 }

35 else

36 {

37 d += (sqb * (2 * x + 3) + sqa * (-2 * y + 2));

38 y--;

39 }

40 x++;

41 EllipsePlot(xc, yc, x, y);

42 }

43 d = (b * (x + 0.5)) * 2 + (a * (y - 1)) * 2 - (a * b) * 2;

44 while(y > 0)

45 {

46 if (d < 0)

47 {

48 d += sqb * (2 * x + 2) + sqa * (-2 * y + 3);

49 x++;

50 }

51 else

52 {

53 d += sqa * (-2 * y + 3);

54 }

55 y--;

56 EllipsePlot(xc, yc, x, y);

57 }

58}

EllipsePlot()函数利用椭圆的三个对称性,一次完成四个对称点的绘制,因为简单,此处就不再列出代码。

2、 Bresenham算法

中点画椭圆法中,计算判别式d使用了浮点运算,影响了椭圆的生成效率。如果能将判别式规约到整数运算,则可以简化计算,提高效率。于是人们针对中点画椭圆法进行了多种改进,提出了很多种中点生成椭圆的整数型算法,Bresenham椭圆生成算法就是其中之一。

在生成椭圆上部区域时,以x轴为步进方向,如图(5-a)所示:

图(5Bresenham椭圆生成算法判别式

x每步进一个单位,就需要在判断y保持不变还是也步进减1bresenham算法定义判别式为:

D = d1 – d2

如果D < 0,则取P1为下一个点,否则,取P2为下一个点。采用判别式D,避免了中点算法因y-0.5而引入的浮点运算,使得判别式规约为全整数运算,算法效率得到了很大的提升。根据椭圆方程,可以计算出d1d2分别是:

d1 = a2(yi2 – y2)

d2 = a2(y2 – yi+12)

(0, b)作为椭圆上部区域的起点,将其代入判别式D可以得到如下递推关系:

Di+1 = Di + 2b2(2xi + 3) (Di < 0)

Di+1 = Di + 2b2(2xi + 3) – 4a2(yi - 1) (Di >= 0)

D0 = 2b2 – 2a2b + a2

在生成椭圆下部区域时,以y轴为步进方向,如图(5-b)所示,y每步进减一个单位,就需要在判断x保持不变还是步进加一个单位,对于下部区域,计算出d1d2分别是:

d1 = b2(xi+12 – x2)

d2 = b2(x2 – xi2)

(xp, yp)作为椭圆下部区域的起点,将其代入判别式D可以得到如下递推关系:

Di+1 = Di – 4a2(yi - 1) + 2a2 (Di < 0)

Di+1 = Di + 2b2(xi + 1) – 4a2(y - 1) + 2a2 + b2 (Di >= 0)

D0 = b2(xp + 1)2 +b2xp2 - 2a2b2 + 2a2(yp - 1)2

根据以上分析,Bresenham椭圆生成算法的实现就比较简单了:

61void Bresenham_Ellipse(int xc , int yc , int a, int b)

62{

63 int sqa = a * a;

64 int sqb = b * b;

65

66 int x = 0;

67 int y = b;

68 int d = 2 * sqb - 2 * b * sqa + sqa;

69 EllipsePlot(xc, yc, x, y);

70 int P_x = ROUND_INT( (double)sqa/sqrt((double)(sqa+sqb)) );

71 while(x <= P_x)

72 {

73 if(d < 0)

74 {

75 d += 2 * sqb * (2 * x + 3);

76 }

77 else

78 {

79 d += 2 * sqb * (2 * x + 3) - 4 * sqa * (y - 1);

80 y--;

81 }

82 x++;

83 EllipsePlot(xc, yc, x, y);

84 }

85

86 d = sqb * (x * x + x) + sqa * (y * y - y) - sqa * sqb;

87 while(y >= 0)

88 {

89 EllipsePlot(xc, yc, x, y);

90 y--;

91 if(d < 0)

92 {

93 x++;

94 d = d - 2 * sqa * y - sqa + 2 * sqb * x + 2 * sqb;

95 }

96 else

97 {

98 d = d - 2 * sqa * y - sqa;

99 }

100 }

101}

总结一下,本文介绍了两种计算机图形学中常见的椭圆生成算法,实际上还有很多种改进算法,包括提高效率,引入反走样技术等等,但那已经不是本文的重点,能把算法的基本原理讲清楚才是本文的目的。

参考资料:

1】计算几何:算法设计与分析周培德 清华大学出版社 2005

2】计算几何:算法与应用德贝尔赫(邓俊辉译) 清华大学出版社 2005

3】计算机图形学孙家广、杨常贵清华大学出版社 1995

  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
计算机算法分析与设计 计算机算法分析与设计(共33张PPT)全文共33页,当前为第1页。 学习目标 掌握算法分析与设计的基本理论 掌握进行算法分析与设计的基本方法(时间、空间复杂度分析,算法正确性的证明) 掌握计算机领域中常用的非数值计算方法,并学会用这些算法解决实际问题 计算机算法分析与设计(共33张PPT)全文共33页,当前为第2页。 课程要求 教学方式:理论(32学时),实践(16学时) 考核方式:考试(80%)+实验作业(20%) 课程学分:3 先修课程:《离散数学》《数据结构》《数值分析》《C语言程序设计》 计算机算法分析与设计(共33张PPT)全文共33页,当前为第3页。 授课教材 选用教材: 《计算机算法基础》(第二版) 余祥宣,崔国华,邹海明 华中科技大学出版社 参考书目: 《算法引论》 张益新,沈雁 国防科技大学出版社 《算法设计与分析》 周培德 机械工业出版社 计算机算法分析与设计(共33张PPT)全文共33页,当前为第4页。 第一章 导引 ---计算机算法分析与设计是面向设计的、处于核心地位的教育课程 ---计算机算法是计算机科学和计算机应用的核心。 1.什么是算法? 2.如何分析算法? 3.如何表示算法? 4.基本数据结构 计算机算法分析与设计(共33张PPT)全文共33页,当前为第5页。 1.什么是算法 算法 数值计算方法(求解数值问题,插值计算、数值积分等) 非数值计算方法(求解非数值问题,主要进行判断比较) 算法笼统的定义:求解一确定类问题的任意一种特殊方法。 非形式描述:算法就是一组有穷的规则,它规定了解决某一特定类型问题的一系列运算。 计算机算法分析与设计(共33张PPT)全文共33页,当前为第6页。 例1 求两个正整数m,n的最大公因子 算法1-1 欧几里得算法 输入:正整数m和n 输出:m和n的最大公因子 第一步:求余数。r m%n 第二步:判断r=0?,若是,终止(n为答案),否则,转第三步。 第三步:互换,m n,n r,返回第一步。 Begin R m%n r=0? Swap(m.n) End N Y 计算机算法分析与设计(共33张PPT)全文共33页,当前为第7页。 例1 求两个正整数最大公因子的一个实例 假设 m=21 和 n=45,求21和45的最大公因子 第一步:r=m%n=21%45=21; 第二步:r 不等于0,转入第三步; 第三步:互换,m=n=45, n=r=21,返回第一步。 第一步:r=m%n=45%21=3; 第二步:r 不等于0,转入第三步; 第三步:互换,m=n=21, n=r=3,返回第一步。 第一步:r=m%n=21%3=0; 第二步:r 等于0,算法结束,3即为21和45的最大公因子。 计算机算法分析与设计(共33张PPT)全文共33页,当前为第8页。 算法的五个重要特性 确定性 每一种运算必须要有确切的定义,无二义性 可行性 运算都是基本运算,原理上能在有限时间内完成 输入 有 1个或多个输入 输出 一个或多个输出 有穷性 在执行了有穷步运算后终止 计算机算法分析与设计(共33张PPT)全文共33页,当前为第9页。 算法的特性 凡是算法,都必须满足以上五条特性。 只满足前四条特性的一组规则不能称之为算法,只能叫做计算过程。 操作系统就是计算过程的一个典型例子。设计操作系统的目的是为了控制作业的运行,当没有作业时,这一计算过程并不终止,而是处于等待状态,一直等到一个新的作业的进入。 计算机算法分析与设计(共33张PPT)全文共33页,当前为第10页。 算法学习的五个内容 如何设计算法 运用一些基本设计策略规划算法 如何表示算法 用恰当的方式表示算法 如何确认算法 算法正确性的证明(算法确认algorithm validation) 如何分析算法 通过时间和空间复杂度的分析,确定算法的优劣 如何测试程序 测试程序是否会产生错误的结果 计算机算法分析与设计(共33张PPT)全文共33页,当前为第11页。 2.如何分析算法 算法分析是对一个算法需要多少计算时间和存储空间作定量的分析。 算法分析步骤: 首先确定使用那些运算以及执行这些运算所用的时间。(运算包括基本数值运算和一些更基本的任意长序列的运算) 其次是要确定出能反映算法在各种情况下工作的数据集。(即要求我们编造出能产生最好、最坏和有代表性情况的数据配置,通过使用这些数据来运行算法,以更了解算法的性能) 计算机算法分析与设计(共33张PPT)全文共33页,当前为第12页。 全面分析一个算法的两个阶段 事前分析(a priori analysis) 求出该算法的一个时间限界函数(一些关于参数的函数) 事前分析只限于每条语句的频率计数(frequency count,该语句的执行次数,与所用的机器无关,且独
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值