从零开始构建计算机系统——二维图形库(圆边)

来源:互联网 发布:大数据学的是什么 编辑:程序博客网 时间:2024/06/05 09:52

三、绘制圆

圆的方程可以描述为( x - x0 )2 + ( y - y0 )2= r2 ,其中 ( x0, y0) 为圆心,r为圆的半径。为了简化问题,我们假设圆心就在坐标中心(0, 0),那么

( x0, y0 )= ( 0, 0 ),那么圆的方程为:x2 + y2= r2

圆心不在坐标原点时,只需要做简单的平移即可。


如上图所示,圆心处于坐标原点处,此时圆具有四条对称轴:

①x = 0、②y = 0、③x = y、④x = -y

这四条对称轴将整个圆分成了八段圆弧,设圆上一点( x, y ),其对称点分别为:

( x, -y )、( -x, y )、( -x, -y ) 、( y, x )、( y, -x )、( -y, x )、( -y, -x )

这叫做圆的八分对称性。只要我们画出八段圆弧中的一段,其余七段可利用八分对称性进行变化得到。

(一)中点画圆法

我们首先画第一段圆弧,草图如下所示,从点( 0, 0 )到( ri, ri )圆弧与线段P1P2相交于一点,M点为线段P1P2中点,假设当前点为Pi( xi, yi),由于每次步进一个像素,因此,

M点坐标为( xi + 1, yi– 0.5 ),P1点坐标为( xi + 1, yi),P2点坐标为( xi+ 1, yi+ 1 )。

从图上我们可以知道,下一个坐标点要么是P1,要么是P2,到底哪个点离圆弧最近,线段中点M点在圆弧与线段交点的Y坐标情况。

设圆的判别函数为:

    F( x, y ) = x2 + y2 -r

我们知道,对于圆上任何一点F( x, y ) = 0,圆外的一点F( x, y ) > 0,圆内的一点F( x, y ) < 0。

我们将M点的坐标代入,如果F( xi + 1, yi –0.5 ) < 0,说明M点在圆内,下一个点为P2,因为它离圆弧最近。如果F(xi + 1, yi –0.5 ) > 0,说明M点在圆外,下一个点为P1,因为它离圆弧最近。设

    di= F(xi +1, yi – 0.5)= (xi +1)2 + (yi – 0.5)2 – r2

di < 0,则取P1为下一个点,即

    xi+1 = xi + 1

    yi+1 = yi

此时P1的下一个点的判别式为: 

    di+1= F(xi + 2, yi – 0.5)= (xi + 2)2 + (yi –0.5)2 – r2

 展开后将di带入可得到判别式的递推关系: 

    di+1 = di + 2xi + 3

di > 0,则取P2为下一个点,即

    xi+1 = xi + 1

    yi+1 = yi – 1

此时P2的下一个点的判别式为:

    di+1 = F(xi + 2, yi – 1.5)= (xi + 2)2 + (yi –1.5)2 – r2

 展开后将di带入可得到判别式的递推关系:

    di+1 = di + 2(xi - yi) + 5

在第一个象限的第一个点(0, R)时,即当i=0,x0=0,y0=r,判别式d的初始值d0

    d0 = F(1, r – 0.5) = 1 – (r– 0.5)2 – r2 = 1.25 - r

我们对上面的推导加以整理,可以得出:对于(0, R)至( ri, ri)的圆弧,

x0 = 0,y0=r,d0 = 1.25 - r

di < 0,

    xi+1= xi + 1

    yi+1= yi

    di+1 = di + 2xi + 3

否则,di > 0

    xi+1= xi + 1

    yi+1= yi – 1

    di+1 = di + 2(xi - yi)+ 5

设圆心坐标为( ∆x, ∆y ),那么相当于对圆心在坐标原点的圆进行平移( ∆x, ∆y ),设原坐标为( x, y ),与偏移后的坐标( X, Y )满足如下关系:

X = x +∆x,Y = y + ∆y

同时,其它七段圆弧满足对称关系,也可以很容易得出:

( X, -Y )、( -X, Y)、( -X, -Y ) 、( Y, X )、( Y, -X )、( -Y, X )、( -Y, -X )

上面计算判别时使用了浮点数,即d0 = 1.25 – r,因此我们需要做进一步优化。

(二)Bresenham画圆法

Bresenham画圆法主要针对中点画圆法进行了改进,将d的计算放大两倍,同时将初始值改成3–2r,这样避免了浮点运算,乘二运算也可以用移位快速代替,采用3–2r为初始值的改进算法。还有一种方法是将d的初始值由1.25–r改成1–r,考虑到圆的半径r总是大于2(像素的最小单位是1),因此这个修改不会影响d的初始值的符号,同时可以避免浮点运算。

根据Bresenham算法,将d放大两倍,可得到:

x0 = 0,y0=r,d0 = 3 - 2r

di < 0,

    xi+1= xi + 1

    yi+1= yi

    di+1 = di + 4xi + 6

否则,di > 0

    xi+1= xi + 1

    yi+1= yi – 1

    di+1 = di + 4(xi - yi)+ 10

(三)正负判定画圆法

在上述画法中,主要的判断依据是哪个点距离圆弧近。在像素的世界里,一个一个点将整个平面切分成了离散的网格,这些像素点要么在圆弧内,要么在圆弧外,要么在圆弧上。无论在哪,始终都是聚集在圆弧的附近,而且尽可能的近。之前的分析中我们知道,已知当前一点Pi( xi, yi),那么下一个点可选位置有两个:P1 ( xi+1, yi)或者P2 (xi+1, yi+1)。为了确保每个点“始终都是聚集在圆弧的附近”,我们采用一种修正的方式,即:如果当前点Pi在圆内,说明当前向着圆心的方向远离了圆弧,为了修正,那么下一个点就应该选取背离圆心方向的点;如果当前点Pi在圆外,说明当前背离圆心的方向远离了圆弧,为了修正,那么下一个点就应该选取向着圆心方向的点。因此,我们可以看出,每次在选取点的时候,都是对当前点的一种修正,修正量为1个单位,要么在Y方向,要么在X方向。如下图所示:

具体的实现方式,将当前点Pi( xi, yi)代入判别式,

①当F(xi, yi)≤ 0,

取xi+1 = xi+1,yi+1 = yi。即向右走一步,从圆内走向圆外。对应图(a)中的从Pi到Pi+1

F(xi+1, yi+1)= F(xi+1,yi) = (xi+1)2+yi2-R= (xi2+yi2-R2)+2xi+1 = F(xi,yi)+2xi+1

②当F(xi, yi)> 0,

取xi+1 = xi,yi+1 = yi - 1。即向下走一步,从圆外走向圆内。对应图(b)中的从Pi到Pi+1

F(xi+1, yi+1)= F(xi,yi-1) = xi2+(yi-1)- R= (xi2+yi2-R2) - 2y+ 1 = F(xi,yi) - 2yi+1

对上面分析进行整理,得到

x0 = 0,y0=r,d0 = 0

di ≤ 0,

    xi+1= xi + 1

    yi+1= yi

    di+1 = di + 2xi + 1

否则,di > 0

    xi+1= xi

    yi+1= yi – 1

    di+1 = di - 2yi + 1

需要注意的是:改进的中点划线算法和正负法虽然都避免了浮点运算,并且计算判别式时用到的乘法都是乘2运算,可以用移位代替,但是实际效率缺有很大差别。因为正负法并不是严格按照x方向步进的,因此就会出现在某个点的下一个点在两个位置上重复画点的问题,增加了不必要的计算,可见下图。此外,从生成圆的质量看,中点画圆法和改进的中点画圆法都比正负法效果好。

防止格式错误,下面是排好版的图片:







阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 狩魔手记 狐颜乱语 绝品神医 特鲁多竞选中呼吁 爱因斯坦 达芬奇 model 2019年诺贝尔物理学奖公布时间 片仔癀的功效 父与子 汽车用品 爱游福利 奶爸的爱情生活 爱是欢乐的源泉 与神同行罪与罚 不期而爱 薰衣草 焦裕禄 烟酰胺对皮肤的作用 炒饼丝的家常做法 炒西兰花 御炎 东汉末年枭雄志 灵隐寺 灭火器 红心火龙果的功效与作用 为什么火龙果不宜晚上吃 火字旁的字有哪些 潘晓婷 潘多拉 英语演讲稿 满洲里 满天星图片 滑膜炎的症状 成人在线 消防车简笔画 蒲公英根的功效与作用 https浏览器 私密浏览器 试孕纸 流鼻血是什么原因 猎户座流星雨将至