【计算机图形学】小白谈计算机图形学(二)画圆篇之中点画圆法,Bresenham画圆算法,椭圆实操,线型处理详解

引言

与直线不同,圆上每点的斜率都是变化的,这一讲我们来介绍圆的画法,首先注意到圆具有八对称性,即只需研究 1 8 \frac{1}{8} 81圆周即可。
在这里插入图片描述

如何画圆

基本思想

  • 隐函数方程: ( x i , y i = r 2 − x i 2 ) (x_i,y_i=\sqrt{r^2-x_i^2} ) (xi,yi=r2xi2 )
  • 参数方程:
    { x = r cos ⁡ θ y = r sin ⁡ θ \left\{ \begin {aligned} x = r\cos\theta\\ y=r\sin\theta\\ \end {aligned} \right. {x=rcosθy=rsinθ
    (But计算量大,不可取)

中点画圆法

中点画圆基本思路

高效的画圆法必须避免三角函数计算和开方乘方计算,用构造函数 F ( x , y ) = x 2 + y 2 − r 2 F(x,y)=x^2+y^2-r^2 F(x,y)=x2+y2r2
{ F ( x , y ) = 0 ( 圆 上 的 点 ) F ( x , y ) > 0 ( 圆 外 的 点 ) F ( x , y ) < 0 ( 圆 内 的 点 ) \left\{ \begin {aligned} F(x,y)=0(圆上的点)\\ F(x,y)>0(圆外的点)\\ F(x,y)<0(圆内的点)\\ \end {aligned} \right. F(x,y)=0()F(x,y)>0()F(x,y)<0()
选取衡量标准,判断下一点是在 ( x i + 1 , y i ) (x_i+1,y_i) (xi+1,yi)还是 ( x i + 1 , y i − 1 ) (x_i+1,y_i-1) (xi+1,yi1),用 m ( x i + 1 , y i − 0.5 ) m(x_i+1,y_i-0.5) m(xi+1,yi0.5)代入得判别式:
d = F ( x m , y m ) = F ( x i + 1 , y i − 0.5 ) = ( x i + 1 ) 2 + ( y i − 0.5 ) 2 − R 2 \begin{aligned} d&=F(x_m,y_m)\\ &=F(x_i+1,y_i-0.5) \\ &=(x_i+1)^2+(y_i-0.5)^2-R^2 \end{aligned} d=F(xm,ym)=F(xi+1,yi0.5)=(xi+1)2+(yi0.5)2R2

  • d ≤ 0 d\leq0 d0时,下一点为 P u ( x i + 1 , y i ) P_u(x_i+1,y_i) Pu(xi+1,yi),而我们真正关心的是求出误差项的递推公式,下面来推导:
    d n e w = F ( x i + 2 , y i − 0.5 ) = ( x i + 2 ) 2 + ( y i − 0.5 ) 2 − R 2 = ( x i + 1 ) 2 + ( y i − 0.5 ) 2 − R 2 + 2 x i + 3 = d o l d + 2 x i + 3 \begin{aligned} d_{new}&=F(x_i+2,y_i-0.5)\\ &=(x_i+2)^2+(y_i-0.5)^2-R^2\\ &=(x_i+1)^2+(y_i-0.5)^2-R^2+2x_i+3\\ &=d_{old}+2x_i+3 \end{aligned} dnew=F(xi+2,yi0.5)=(xi+2)2+(yi0.5)2R2=(xi+1)2+(yi0.5)2R2+2xi+3=dold+2xi+3

  • 同理, d > 0 d>0 d>0时:
    d n e w = F ( x i + 2 , y i − 1.5 ) = ( x i + 2 ) 2 + ( y i − 1.5 ) 2 − R 2 = ( x i + 1 ) 2 + ( y i − 0.5 ) 2 − R 2 + ( 2 x i + 3 ) + ( 2 − 2 y i ) = d o l d + 2 ( x i − y i ) + 5 \begin{aligned} d_{new}&=F(x_i+2,y_i-1.5)\\ &=(x_i+2)^2+(y_i-1.5)^2-R^2\\ &=(x_i+1)^2+(y_i-0.5)^2-R^2+(2x_i+3)+(2-2y_i)\\ &=d_{old}+2(x_i-y_i)+5 \end{aligned} dnew=F(xi+2,yi1.5)=(xi+2)2+(yi1.5)2R2=(xi+1)2+(yi0.5)2R2+(2xi+3)+(22yi)=dold+2(xiyi)+5

  • 这里讨论的是按顺时针方向生成第一个八分圆。则第一个象素是: ( 0 , r ) (0,r) (0,r),故得 d 0 d_0 d0
    d 0 = F ( 1 , R − 0.5 ) = 1 + ( R − 0.5 ) 2 − R 2 = 1.25 − R \begin{aligned} d_0&=F(1,R-0.5)\\&=1+(R-0.5)^2-R^2\\&=1.25-R \end{aligned} d0=F(1,R0.5)=1+(R0.5)2R2=1.25R
    在这里插入图片描述

中点画圆改进

  • 由于只用 d d d的正负,因此用 d − 0.25 d-0.25 d0.25代替 d d d 以摆脱小数,更新后的公式为:
    { d 0 = 1 − R d n e w = d o l d + 2 x i + 3 ( d ≤ 0 ) d n e w = d o l d + 2 ( x i − y i ) + 5 ( d > 0 ) \left\{ \begin{aligned} &d_0= 1-R\\ &d_{new}=d_{old}+2x_i+3(d\leq0) \\ &d_{new}=d_{old}+2(x_i-y_i)+5(d > 0) \end{aligned} \right. d0=1Rdnew=dold+2xi+3(d0)dnew=dold+2(xiyi)+5(d>0)
  • 这里研究的圆心都在 ( 0 , 0 ) (0,0) (0,0)点,画任一 ( x c , y c ) (x_c,y_c) (xc,yc)点即是分别向 x , y x,y x,y方向进行了平移。
    缺点:有一点走样

Bresenham画圆算法

Bresenham基本思路

考虑 1 4 \frac{1}{4} 41 象限的四分圆,此处以第一象限为例,每一点的下一个象素有三种选择,正右方 ( H ) (H) (H),右下方 ( D ) (D) (D),正下方 ( V ) (V) (V)。观察发现以 D D D的位置作为讨论依据最为科学。
在这里插入图片描述

Bresenham上手计算

判断 D D D点(注意是与圆上的距离不是圆心的距离)的位置:
Δ D = ( x + 1 ) 2 + ( y + 1 ) 2 − r 2 \Delta D=(x+1)^2+(y+1)^2-r^2 ΔD=(x+1)2+(y+1)2r2
接着判断D与E,D与F和圆周的相对距离大小判断涂色:

  • Δ D < 0 \Delta D<0 ΔD<0, D D D在圆内, δ H D = ∣ Δ H ∣ − ∣ Δ D ∣ = 2 Δ D + 2 y − 1 \delta HD=|\Delta H|-|\Delta D|=2\Delta D+2y-1 δHD=ΔHΔD=2ΔD+2y1,若小于等于 0 0 0则选 H H H,大于 0 0 0则选 D D D
  • Δ D > 0 \Delta D>0 ΔD>0, D D D在圆外, δ D V = ∣ Δ D ∣ − ∣ Δ V ∣ = 2 ( Δ D − x ) − 1 \delta DV=|\Delta D|-|\Delta V|=2(\Delta D-x)-1 δDV=ΔDΔV=2(ΔDx)1,若小于等于 0 0 0则选 D D D,大于 0 0 0则选 V V V
  • Δ D ( x p + 1 , y p − 1 ) \Delta D(x_p+1,y_p-1) ΔD(xp+1,yp1)的初值为 Δ D = 1 + ( 1 − r ) 2 − r 2 = 2 − 2 r \Delta D=1+(1-r)^2-r^2=2-2r ΔD=1+(1r)2r2=22r
    故公式为:
    { Δ D = 2 − 2 r δ H D = 2 Δ D + 2 y − 1 δ D V = 2 Δ D − 2 x − 1 Δ D < 0 { δ H D ≤ 0 ⇒ H 点 : Δ D n e w = Δ D o l d + 2 ( x + 1 ) + 1 δ H D > 0 ⇒ D 点 : Δ D n e w = Δ D o l d + 2 ( x + 1 ) − 2 ( y − 1 ) + 2 Δ D > 0 { δ H D ≤ 0 ⇒ D 点 : Δ D n e w = Δ D o l d + 2 ( x + 1 ) − 2 ( y − 1 ) + 2 δ H D > 0 ⇒ V 点 : Δ D n e w = Δ D o l d + 2 ( y − 1 ) + 1 Δ D = 0 ⇒ D 点 : Δ D n e w = Δ D o l d + 2 ( x + 1 ) − 2 ( y − 1 ) + 2 \left\{ \begin{aligned} &\Delta D=2-2r\\ &\delta HD=2\Delta D+2y-1 \\&\delta DV=2\Delta D-2x-1\\ &\Delta D<0 \left\{ \begin{aligned} &\delta HD\leq0\Rightarrow H点:\Delta D_{new}=\Delta D_{old}+2(x+1)+1 \\ &\delta HD>0\Rightarrow D点:\Delta D_{new}=\Delta D_{old}+2(x+1)-2(y-1)+2 \end{aligned} \right.\\ &\Delta D>0 \left\{ \begin{aligned} &\delta HD\leq0 \Rightarrow D点:\Delta D_{new}=\Delta D_{old}+2(x+1)-2(y-1)+2 \\ &\delta HD>0 \Rightarrow V点:\Delta D_{new}=\Delta D_{old}+2(y-1)+1 \end{aligned} \right.\\ &\Delta D=0\Rightarrow D点:\Delta D_{new}=\Delta D_{old}+2(x+1)-2(y-1)+2 \\ \end{aligned} \right. ΔD=22rδHD=2ΔD+2y1δDV=2ΔD2x1ΔD<0{δHD0H:ΔDnew=ΔDold+2(x+1)+1δHD>0D:ΔDnew=ΔDold+2(x+1)2(y1)+2ΔD>0{δHD0D:ΔDnew=ΔDold+2(x+1)2(y1)+2δHD>0V:ΔDnew=ΔDold+2(y1)+1ΔD=0DΔDnew=ΔDold+2(x+1)2(y1)+2
  • 优点:每次在三个点中判断,走样较小,可以一次处理四分之一圆。
    缺点:算法复杂。

如何画椭圆

开动脑筋,进行类比~

类同于中点画圆法,区别是画第一象限的四分之一椭圆弧,关键是找到临界点。
在这里插入图片描述

椭圆实操

找到切线斜率为 1 1 1的点 p ( x p , y p ) p(x_p,y_p) p(xp,yp),利用中点画线法进行处理:
{ x p = a 2 a 2 + b 2 y p = b 2 a 2 + b 2 \left\{ \begin{aligned} &x_p= \frac{a^2}{\sqrt{a^2+b^2}}\\ &y_p= \frac{b^2}{\sqrt{a^2+b^2}} \end{aligned} \right. xp=a2+b2 a2yp=a2+b2 b2
1 4 \frac{1}{4} 41椭圆分成 ( 0 , b ) (0,b) (0,b) p p p点, ( a , 0 ) (a,0) (a,0) p p p点两块,故公式为:
{ ( 0 , b ) 到 p 点 : { d 0 = b 2 + ( − b + 0.25 ) a 2 d n e w = d o l d + ( 2 x + 3 ) b 2 ( d ≤ 0 ) d n e w = d o l d + ( 2 x + 3 ) b 2 + ( 2 − 2 y ) a 2 ( d > 0 ) ( a , 0 ) 到 p 点 : { d 0 = ( − a + 0.25 ) b 2 + a 2 d n e w = d o l d + ( 2 y + 3 ) a 2 ( d ≤ 0 ) d n e w = d o l d + ( 2 y + 3 ) a 2 + ( 2 − 2 x ) b 2 ( d > 0 ) \left\{ \begin{aligned} &(0,b)到p点: \left\{ \begin{aligned} &d_0=b^2+(-b+0.25)a^2\\ &d_{new}=d_{old}+(2x+3)b^2(d\leq0)\\ &d_{new}=d_{old}+(2x+3)b^2+(2-2y)a^2(d>0) \end{aligned} \right.\\ &(a,0)到p点: \left\{ \begin{aligned} &d_0=(-a+0.25)b^2+a^2\\ &d_{new}=d_{old}+(2y+3)a^2(d\leq0)\\ &d_{new}=d_{old}+(2y+3)a^2+(2-2x)b^2(d>0) \end{aligned} \right. \end{aligned} \right. (0,b)pd0=b2+(b+0.25)a2dnew=dold+(2x+3)b2(d0)dnew=dold+(2x+3)b2+(22y)a2(d>0)(a,0)pd0=(a+0.25)b2+a2dnew=dold+(2y+3)a2(d0)dnew=dold+(2y+3)a2+(22x)b2(d>0)

线型处理

线画图元的基本属性有线型、宽度和颜色

线宽处理

线刷子

  • 当斜率 k ∈ [ − 1 , 1 ] k∈[-1,1] k[1,1]之间,刷子置成垂直方向(水平方向刷),刷子的中点对准直线一端点,然后让刷子中心往直线的另一端移动,即可刷出具有一定宽度的线。
  • 同理,当斜率 k ∉ [ − 1 , 1 ] k\notin [-1,1] k/[1,1]之间时,把刷子置成水平方向(竖直方向刷)。
    -在这里插入图片描述
引起的问题:汇合外角缺口

在这里插入图片描述

改进

加圆帽,通过对每个方帽添加一个填充的半圆而得到。圆弧的圆心在线的端点其直径与线宽度相等。
在这里插入图片描述

方形刷子

把边宽为指定线宽的正方形的中心沿直线作平行移动,用方形刷子绘制的线条比用线刷子绘制的要粗一些(对角线的原因)。

线刷子与方形刷子的对比:

  • 线刷子在45°角附近线条在水平和垂直方向之间切换,最细
  • 方形刷子正相反由于线宽正好为对角线而显著变粗

超链接

如果你还想了解其他内容:
小白谈计算机图形学(一)如何画线
小白谈计算机图形学(二)如何画圆
小白谈计算机图形学(三)二维图形裁剪
小白谈计算机图形学(四)二维三维图形变换—1

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一拳Marx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值