由于工作需求,需要用三次贝塞尔曲线拟合圆弧,所以查阅了一些资料,主要参考如下文章:
但是文章写的过于简单,也没有推演步骤,而我需要知道任意圆弧如何求出贝塞尔曲线的两个控制点,所以自己进行了推算,如有疏漏望指正。
一、绘图
最开始解这个的时候其实我是用代数去解的,但是后面发现代数运算过于复杂,很难写出解,于是想到通过几何的方式来解这个,比较参考文章里也用了半角的特殊值。于是我尝试从几何的角度来解。先贴我画的几何图,如下,其中实线部分是很容易就想到要连起来的,虚线部分是作的辅助线:
简单解释下上面的图,其中点 O 是圆心,P0、P3 分别是圆弧的起点和终点,P1 和 P2 分别是贝塞尔曲线的两个控制点。 M2 是 线段 P1-P2 的中点,M0 是线段 O-M2 和 P0-P3 的交点。 M1 是贝塞尔曲线 t = 0.5 时的点,也就是圆弧的中点,同时很容易就可以证明 M1 在线段 O-M2 上(根据几个垂直可以推出)。
其中有几个中点没有标,根据三次贝塞尔曲线的几何性质可以知道:M1 是一个很特殊的中点,它可以这样取得:取 P0-P1、P1-P2、P2-P3的中点 C0、M2、C2,连接 C0-M2 和 M2-C2,取 C0-M2 和 M2-C2 的中点 D1、D2,连接 D1-D2,取 D1-D2 的中点就是 M1,M1 是在贝塞尔曲线上的,也就是在圆弧上的。
接下来我们做两条辅助线,过 P1 作 P0-P2 的垂线,垂足为 F0,延长 0-M2 和 P0-P1 交于 F1。
二、推算
其实我觉得把图画好就成功一半了,所以画图真的很重要:)
接下来给出已知量,已知圆的半径 r , P0 和 P2 的坐标。求 P1 和 P2 的坐标。
2.1 推算 P0-P1 的长度
1. 假设 P0-P1 的长度为 l(小写的L 不是 1),M0-M2 的长度为 d,∠P0-O-P1 的角度为 θ。
2.首先可以证明出 ∠O-P0-P1 和 ∠O-P3-P2 是直角,这里省略。(大致过程应该可以通过求出贝塞尔曲线的切线,然后得出在 t = 0 和 t = 1 是两个控制点 P1、P2 是在切线上的,结合圆的切线垂直于圆点到圆心的连线)
3. 推算出线段 M2-M1 的长度是 M1-M0 的 1/4,同时 M1-M0 是 M2-M0 的 3/4。(这个步骤相对简单,根据贝塞尔曲线的 M1 点由来(多次取中点)可以证明)
5. (线段长度M0-M1) = r - (线段长度O-M0),O-M0的长度 = r*cos(θ/2),θ为 ∠P0-O-P1 的角度。结合 M0-M1 是 M0-M2 的 3/4,如果 M0-M2 的长度为 d。那么
d*3/4 = r - r*cos(θ/2) (方程 1)
6. 由于 ∠P0-M0-O 和 ∠P1-P0-O 都是直接,那么可以很快证明出 ∠P1-P0-F0 = ∠P0-O-M0 = θ/2,进而得出 P1-F0 的长度等于 l*sin(θ/2),l 的长度是 P0-P1 的长度。之后可以得出 M0-M2 的长度是等于 P1-F0 的长度的,也就是
d = l*sin((θ/2)) (方程 2)
7. 联合 方程1 和 方程2 ,可以求出 l ,也就是 P0-P1 的长度
l = (4/3)*((1-cos(θ/2))/sin(θ/2))*r

本文详细介绍了如何利用三次贝塞尔曲线精确拟合圆弧,并提供了完整的数学推导过程,包括求解贝塞尔曲线控制点的具体公式及JavaScript实现代码。
最低0.47元/天 解锁文章
2944





