计算机图形学中的曲线问题——贝塞尔曲线的绘制

贝塞尔曲线的绘制

由于 CSDN 的博客修改字数的限制,我们不得不将这一部分放到一个新的博客中。原文详见:

GGN_2015
计算机图形学中的曲线问题

贝塞尔曲线的几何作图法

在上面介绍儿时的回忆中,我们介绍了对于抛物线绘制的一种方法。如下图所示,我们要先选定三个控制点 A , B , C A, B, C A,B,C,连接 A B AB AB B C BC BC。我们在 A B AB AB 上取一点 D D D,在 B C BC BC 上取一点 E E E 使得:
A D A B = B E B C = t \frac {AD}{AB}=\frac{BE}{BC}=t ABAD=BCBE=t

其中 t t t 是一个定义在 [ 0 , 1 ] [0, 1] [0,1] 区间上的数。之后我们再连接 D E DE DE 并在 D E DE DE 上取一点 F F F 使得:
D F D E = t \frac{DF}{DE}=t DEDF=t
静态图

t t t [ 0 , 1 ] [0, 1] [0,1] 之间变化时, F F F 点的轨迹就是一条抛物线(换言之,二次贝塞尔曲线)。当 t t t 变化时,点 F F F 的运动效果如下:

曲线绘制
对于三次贝塞尔曲线我们也可以使用同样的方法进行绘制,只不过这次控制点的个数要增加到四个。先取四个控制点 A , B , C , D A, B, C, D A,B,C,D,分别连接 A B AB AB B C BC BC C D CD CD,使用同样的比例 t t t 在这三个线段上各取一点,记为 E , F , G E, F, G E,F,G。连接 E F EF EF F G FG FG,再使用相同的比例 t t t 在这两条线段上分别取一点,记为 J , K J, K J,K。最后,连接 J K JK JK,在线段 J K JK JK 上按照比例 t t t 取一点 M M M。在 t t t 变化的过程中, M M M 点的运动轨迹就是一条三次贝塞尔曲线。

相同的比例指:
A E A B = B F B C = C G C D = E J E F = F K F G = J M J K = t \frac{AE}{AB}=\frac{BF}{BC}=\frac{CG}{CD}=\frac{EJ}{EF}=\frac{FK}{FG}=\frac{JM}{JK}=t ABAE=BCBF=CDCG=EFEJ=FGFK=JKJM=t

三次贝塞尔曲线

这个关系虽然看起来比较繁琐,但实际上并不复杂。可以看到在这个三次贝塞尔曲线的几何作图法表述中,点 J J J 和点 K K K 各自运动的轨迹就是一条二次的贝塞尔曲线,而点 M M M 的运动轨迹是一条三次贝塞尔曲线,因此,我们可以说三次贝塞尔曲线是对两条二次贝塞尔曲线的“合并”。运动效果如下:

三次贝塞尔曲线
J J J 点的运动方程为 f 1 ( t ) , t ∈ [ 0 , 1 ] f_1(t), t\in[0, 1] f1(t),t[0,1] K K K 点的运动方程为 f 2 ( t ) , t ∈ [ 0 , 1 ] f_2(t), t\in[0, 1] f2(t),t[0,1],则 M M M 点的运动方程为 f 3 ( t ) = ( 1 − t ) ⋅ f 1 ( t ) + t ⋅ f 2 ( t ) f_3(t)=(1-t)\cdot f_1(t)+t\cdot f_2(t) f3(t)=(1t)f1(t)+tf2(t) 。这种合并会使得曲线 f 3 f_3 f3 的前半段比较接近 f 1 f_1 f1,后半段比较接近 f 2 f_2 f2。下图中的绿线和蓝线分别是 f 1 f_1 f1 f 2 f_2 f2,红线是 f 3 f_3 f3

对比
为了表述方便,我们称:折线 A B C D ABCD ABCD 是红色曲线 f 3 f_3 f3 的控制多边形。

贝塞尔曲线的分裂法绘制

根据文章正文中的介绍我们已经得知,如果 A B C D ABCD ABCD 是曲线 f 3 f_3 f3 的控制多边形,那么有:
f 3 ( t ) = ( 1 − t ) 3 ⋅ A + 3 ( 1 − t ) 2 t ⋅ B + 3 ( 1 − t ) t 2 ⋅ C + t 3 ⋅ D , t ∈ [ 0 , 1 ] f_3(t)=(1-t)^3\cdot A+3(1-t)^2t\cdot B+3(1-t)t^2\cdot C+t^3 \cdot D, t\in[0, 1] f3(t)=(1t)3A+3(1t)2tB+3(1t)t2C+t3D,t[0,1]

t t t 变化的过程中,我们可以观察到,当 t → 0 t\to 0 t0 时, A E J M AEJM AEJM 四点几乎接近左半段曲线,当 t → 1 t\to 1 t1 时, M K G D MKGD MKGD 几乎接近右半段曲线,而这种性质中似乎暗含着一些不可告人的秘密。正如 A B C D ABCD ABCD 是整段曲线 f 3 f_3 f3 的控制多边形,我们有理由猜测: A E J M AEJM AEJM 是否是 f 3 f_3 f3 M M M 左侧部分的曲线的控制多边形而 M K G D MKGD MKGD f 3 f_3 f3 M M M 右侧部分的控制多边形呢?

t=1/2
假设当前 t = 1 2 t=\frac 1 2 t=21,那么我们可以算出 E , J , M E, J, M E,J,M 三点各自的坐标:
E = ( 1 − t ) ⋅ A + t ⋅ B = A + B 2 F = ( 1 − t ) ⋅ B + t ⋅ C = B + C 2 G = ( 1 − t ) ⋅ C + t ⋅ D = C + D 2 J = ( 1 − t ) ⋅ E + t ⋅ F = A + 2 B + C 4 K = ( 1 − t ) ⋅ F + t ⋅ G = B + 2 C + D 4 M = A + 3 B + 3 C + D 8 \begin{aligned} E&=(1-t)\cdot A+t\cdot B=\frac{A+B}{2}\\ F&=(1-t)\cdot B+t\cdot C=\frac{B+C}{2}\\ G&=(1-t)\cdot C+t\cdot D=\frac{C+D}{2}\\ J&=(1-t)\cdot E+t\cdot F=\frac{A+2B+C}{4}\\ K&=(1-t)\cdot F+t\cdot G=\frac{B+2C+D}{4}\\ M&=\frac{A+3B+3C+D}{8} \end{aligned} EFGJKM=(1t)A+tB=2A+B=(1t)B+tC=2B+C=(1t)C+tD=2C+D=(1t)E+tF=4A+2B+C=(1t)F+tG=4B+2C+D=8A+3B+3C+D

我们定义 A E J M AEJM AEJM 四个点确定的三次贝塞尔曲线为 f ( t ) f(t) f(t),则有:
f ( t ) = ( 1 − t ) 3 ⋅ A + 3 ( 1 − t ) 2 t ⋅ E + 3 ( 1 − t ) t 2 ⋅ J + t 3 ⋅ M , t ∈ [ 0 , 1 ] f(t)=(1-t)^3\cdot A+3(1-t)^2t\cdot E+3(1-t)t^2\cdot J+t^3 \cdot M, t\in[0, 1] f(t)=(1t)3A+3(1t)2tE+3(1t)t2J+t3M,t[0,1]

我们不妨把上式整理成只含有 A B C D ABCD ABCD 四个点的形式:
f ( t ) = ( 1 − t ) 3 ⋅ A + 3 ( 1 − t ) 2 t ⋅ A + B 2 + 3 ( 1 − t ) t 2 ⋅ A + 2 B + C 4 + t 3 ⋅ A + 3 B + 3 C + D 8 , t ∈ [ 0 , 1 ] = ( A B C D ) × [ 1 1 2 1 4 1 8 0 1 2 2 4 3 8 0 0 1 4 3 8 0 0 0 1 8 ] × ( ( 1 − t ) 3 3 ( 1 − t ) 2 t 3 ( 1 − t ) t 2 t 3 ) , t ∈ [ 0 , 1 ] \begin{aligned} f(t)&=(1-t)^3\cdot A+3(1-t)^2t\cdot \frac{A+B}{2}+3(1-t)t^2\cdot \frac{A+2B+C}{4}+t^3 \cdot \frac{A+3B+3C+D}{8}, t\in[0, 1]\\ &=\left(\begin{matrix}A&B&C&D \end{matrix}\right)\times\left[\begin{matrix}1&\frac 1 2 & \frac 1 4 & \frac 1 8\\ 0&\frac 1 2&\frac 2 4& \frac 3 8\\ 0&0&\frac 1 4 & \frac 3 8\\ 0&0&0&\frac 1 8 \end{matrix}\right]\times\left(\begin{matrix}(1-t)^3\\3(1-t)^2t\\3(1-t)t^2\\t^3\end{matrix}\right),t\in[0, 1] \end{aligned} f(t)=(1t)3A+3(1t)2t2A+B+3(1t)t24A+2B+C+t38A+3B+3C+D,t[0,1]=(ABCD)×1000212100414241081838381×(1t)33(1t)2t3(1t)t2t3,t[0,1]

接下来这一步需要比较复杂的整理,具体的步骤我们就不做了,简单而言,我们要将上面的三个矩阵中的后两个乘起来:
f ( t ) = ( A B C D ) × ( ( 1 − t 2 ) 3 3 ( 1 − t 2 ) 2 t 2 3 ( 1 − t 2 ) ( t 2 ) 2 ( t 2 ) 3 ) = f 3 ( t 2 ) , t ∈ [ 0 , 1 ] f(t)=\left(\begin{matrix}A&B&C&D \end{matrix}\right)\times \left(\begin{matrix}(1-\frac t 2)^3\\3(1-\frac t 2)^2 \frac t 2\\3(1- \frac t 2)\left(\frac t 2\right)^2\\(\frac t 2)^3\end{matrix}\right)=f_3(\frac t 2), t\in [0, 1] f(t)=(ABCD)×(12t)33(12t)22t3(12t)(2t)2(2t)3=f3(2t),t[0,1]

这也就说明了,当 t t t 0 0 0 取到 1 1 1 时, f ( t ) f(t) f(t) 恰好取遍曲线 f 3 f_3 f3 的前一半。因此以 A E J M AEJM AEJM 为控制多边形的贝塞尔曲线恰好为以 A B C D ABCD ABCD 为控制多边形的贝塞尔曲线的前一半;同理,以 M K G D MKGD MKGD 为控制多边形的贝塞尔曲线恰好为以 A B C D ABCD ABCD 为控制多边形的贝塞尔曲线的后一半。

按照这一原理,我们可以设计一个递归算法来绘制一条贝塞尔曲线:当我们要绘制以 A B C D ABCD ABCD 为控制多边形的贝塞尔曲线时,我们先要计算 B B B 点和 C C C 点到 A D AD AD 的距离,如果 B B B 点和 C C C 点到 A D AD AD 的距离都很近,换言之, A B C D ABCD ABCD 近似共线,我们就不再递归直接将线段 A D AD AD 视为对贝塞尔曲线的近似。如果 B B B C C C 中有一者离线段 A D AD AD 很远,将这个贝塞尔曲线按照上述方法分成 A E J M AEJM AEJM M K G D MKGD MKGD 两部分,并分别递归地进行绘制。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值