二阶贝塞尔曲线SDF推导

225 阅读6分钟

image.png

theme: fancy

大家好,间隔快一个月没有发文章了,主要是这一篇推导实在是超出我能力范围太多了,同时缺乏相关的资料,啃下来非常不容易。 本文的亮点有

  • 小白也能读懂: 笔者十余年没用过数学,就是一个初中生数学水平,在理解过程中,看到资料中的有很多因为所以,完全不明白为什么可以因为所以: ( 原因是很多公式定理我都忘了,或者不知道。通过不断的查阅资料,终于写出来整个推导过程,这篇文章补充了很多这种基础知识,我相信这篇文章也会适合小白阅读,因为我自己就是小白
  • 图例标记,证明符号,代码变量一致: 在初次看贝塞尔曲线的距离场代码,完全搞不明白这个代码是怎么写出来的。再后来找到一些资料里面有整个证明过程,也看不懂。很大一部份原因是代码和数学公式中的符号完全不一样,本文图例,证明,代码 所有符号都是一样
  • 用棣莫弗定理和费马引理带图证明了第三个根不可能为最小值
  • 关于贝塞尔曲线的SD推导,没有发现很完整的英文资料,更别说中文资料了...

基础

以下公式作为索引,会在推导过程中用到。如果这里讲的不明白,可以wiki查看。 嫌麻烦可以直接跳转到 推导

链式法则求导

链式法则是一种在微积分中求导复合函数的基本规则。

ddxf(g(x))=f(g(x))g(x)\frac{d}{dx}f(g(x)) = f'(g(x)) \cdot g'(x)

多项式求导

多项式求导是微积分中的一个基本概念,

P(x)=anxn+an1xn1++a2x2+a1x+a0P(x) = a_n x^n + a_{n-1} x^{n-1} + \cdots + a_2 x^2 + a_1 x + a_0

其中, an,an1,,a1,a0a_n, a_{n-1}, \ldots, a_1, a_0 是常数系数, nn 是最高次幂且是一个非负整数。 多项式函数的导数 P(x)P'(x) 可以通过下列规则来计算:

  • 幂规则:如果 f(x)=xnf(x) = x^n ,其中 nn 是任意实数,则 f(x)=nxn1f'(x) = n \cdot x^{n-1}
  • 常数规则:如果 CC 是一个常数, f(x)=Cf(x) = C 的导数是 0。即 C=0C' = 0

三次单位根

三次单位根,又被称为立方根的单位根,是复数中的一种特殊类型的数,它们是方程 x3=1x^3 = 1 的解。

x1=1x2=ei2π3=cos2π3+isin2π3=12+i32x3=ei2π23=cos4π3+isin4π3=12i32\begin{aligned} x_1 &= 1 \\ x_2 &= e^{\frac{i2\pi}{3}} = \cos{\frac{2\pi}{3}} + i\sin{\frac{2\pi}{3}} = -\frac{1}{2} + i\frac{\sqrt{3}}{2} \\ x_3 &= e^{\frac{i2\pi \cdot 2}{3}} = \cos{\frac{4\pi}{3}} + i\sin{\frac{4\pi}{3}} = -\frac{1}{2} - i\frac{\sqrt{3}}{2} \\ \end{aligned}

三倍角公式

三倍角公式是三角函数中的一个重要公式,它将三倍角的三角函数值与单角的三角函数值联系起来。

cos(3A)=4cos3A3cosA\cos(3A) = 4\cos^3 A - 3\cos A

欧拉公式

这个关系式在复分析中非常关键,它将复数的指数运算和三角函数联系起来。

eiθ=cosθ+isinθe^{i\theta} = \cos{\theta} + i\sin{\theta}

棣莫弗定理

当我们求一个复数 zznn 次根时,结果可以表示为

z1/n=r1/n(cos(θ+2kπn)+isin(θ+2kπn)),k=0,1,,n1z^{1/n} = r^{1/n} \left( \cos \left( \frac{\theta + 2k\pi}{n} \right) + i\sin \left( \frac{\theta + 2k\pi}{n} \right) \right), \quad k = 0, 1, \ldots, n-1

卡丹方程

方程形如 x3+px+q=0x^3 + px + q = 0,它没有二次项,该形式的方程称为“折减形式”(Depressed form)或“卡丹形式” 其根由以下公式给出:

x=q2+(q2)2+(p3)33+q2(q2)2+(p3)33x = \sqrt[3]{-\frac{q}{2} + \sqrt{\left(\frac{q}{2}\right)^2 + \left(\frac{p}{3}\right)^3}} + \sqrt[3]{-\frac{q}{2} - \sqrt{\left(\frac{q}{2}\right)^2 + \left(\frac{p}{3}\right)^3}}

为了应用卡丹方程,任意形式的三次方程 ax3+bx2+cx+d=0ax^3 + bx^2 + cx + d = 0 需要首先通过代换转化为折减形式。这通常是通过对 x 进行替换,使原方程中的二次项消失,即设

x=yb3ax = y - \frac{b}{3a}

使用卡丹方法时,我们通常会碰到一个名为“卡丹判别式”的量

Δ=(q2)2+(p3)3\Delta = \left(\frac{q}{2}\right)^2 + \left(\frac{p}{3}\right)^3

这个量告诉我们方程的根的性质:

  • 如果 Δ>0\Delta > 0,则方程有一个实根和两个复数根。
  • 如果 Δ=0\Delta = 0,则所有根都是实数,并且至少有两个根相等。
  • 如果 Δ<0\Delta < 0,则方程有三个不同的实数根。

韦达定理

韦达定理(Viète's formulas),是关于多项式方程根与其系数之间关系的一组定理。这些定理对于任何实数或复数系数的多项式方程都成立。

anxn+an1xn1++a1x+a0=0x1+x2++xn=an1anx1x2+x1x3++xn1xn=an2anx1x2xn=(1)na0ana_nx^n + a_{n-1}x^{n-1} + \dots + a_1x + a_0 = 0 \\ \Downarrow \\ x_1 + x_2 + \dots + x_n = -\frac{a_{n-1}}{a_n} \\ x_1x_2 + x_1x_3 + \dots + x_{n-1}x_n = \frac{a_{n-2}}{a_n} \\ x_1x_2 \dots x_n = (-1)^n \frac{a_0}{a_n}

费马引理

费马引理(Fermat's Lemma)是微积分学中的一个基本结果,引理表述如下:

如果函数 ff 在点 x=cx = c 取得局部极大值或局部极小值,并且如果 ffx=cx = c 可导,那么 f(c)=0f'(c) = 0

费马引理仅仅给出了可导函数在某个点为极值的必要条件。也就是说,有些驻点可以不是极值点,它们是拐点。要想知道一个驻点是不是极值点,并进一步区分极大值点和极小值点,我们需要分析二阶导数(如果它存在)。当该点的二阶导数大于零时,该点为极小值点;当该点的二阶导数小于零时,该点为极大值点。若二阶导数为零,则无法用该法判断,需列表判断。

推导

二阶贝塞尔曲线函数

a (2).gif 贝塞尔曲线是线性插值的结果。如果我们知道两点之间的距离,并想找出离第一个点20%间距的一个新的点(也就是离第二个点80%的间距),我们可以通过简单的计算来得到:

Given(p1=somepointp2=otherpointdistance=(p2p1)ratio=percentage100),our new point =p1+distanceratioGiven \begin{pmatrix} p1 = some point \\ p2 = other point \\ distance = (p2 - p1) \\ ratio = \cfrac{percentage}{100} \end{pmatrix}, \text{our new point =} p_1 + distance \cdot ratio

2D坐标系中有A,B,C 三个点, 有变量t, t的取值[0,1][0, 1]。 以此绘制一条2阶贝塞尔曲线, 对坐标中任意点p, 求p到该曲线的最短距离

vec2 Bezier(vec2 a, vec2 b, vec2 c, float t) {
    return mix(mix(a, b, t), mix(b,c,t), t);
}

又有

mix(a,b,t)=a(1t)+btmix(a, b, t) = a\cdot(1-t) + b\cdot t

用数学公式表达,可以获取

P(t)=(1t)2A+2(1t)tB+t2C=(12t+t2)A+(2t2t2)B+t2C letf(t)=P(t)p f(t)=(A2B+C)t2+2(BA)t+Ap let{a=BAb=A2B+Cc=2(BA)=2ad=Ap    f(t)=bt2+ct+dP(t) = (1 - t)^2 \cdot A + 2 \cdot (1 - t) \cdot t \cdot B + t^2 \cdot C =(1-2t+t^2) \cdot A + (2t - 2t^2) \cdot B + t^2 \cdot C \\ \ \\ let \quad f(t) = P(t) - p \\ \ \\ f(t) = (A-2B+C) \cdot t^2 + 2 \cdot (B-A) \cdot t + A-p \\ \ \\ let \quad \begin{cases} a=B-A \\ b=A-2*B+C \\ c=2*(B-A) = 2a \\ d=A-p \end{cases} \implies f(t) = b \cdot t^2 + c \cdot t + d

最小距离就是求极值

于是贝塞尔曲线距离场问题变成了

what value t,the minimum value of f(t)what \ value \ t, the \ minimum \ value \ of \ |f(t)|

这个问题等于

what value t,the minimum value of f(t)2what \ value \ t, the \ minimum \ value \ of \ f(t)^2

于是这就变成了一个求极值的问题,极值点一定是导数为0的点 根据链式法则求导,可以计算如下:

ddt[f(t)]2=2f(t)f(t)\frac{d}{dt}[f(t)]^2 = 2f(t) \cdot f'(t)

应用基本的多项式求导

0=2f(t)f(t)=2(bt2+ct+d)(2bt+c)=bt2(2bt+c)+ct(2bt+c)+d(2bt+c)=(bt22bt)+(bt2c)+(ct2bt)+(ctc)+(d2bt)+(dc)=2b2t3+bct2+2bct2+c2t+2bdt+dc=2b2t3+3bct2+(c2+2bd)t+dc\begin{aligned} 0 &= 2f(t) \cdot f'(t) \\ &= 2 \cdot (b \cdot t^2 + c \cdot t + d) \cdot (2b \cdot t + c) \\ &= b \cdot t^2 \cdot (2b \cdot t + c) + c \cdot t \cdot (2b \cdot t + c) + d \cdot (2b \cdot t + c) \\ &= (b \cdot t^2 \cdot 2b \cdot t) + (b \cdot t^2 \cdot c) + (c \cdot t \cdot 2b \cdot t) + (c \cdot t \cdot c) + (d \cdot 2b \cdot t) + (d \cdot c) \\ &= 2b^2 \cdot t^3 + bc \cdot t^2 + 2bc \cdot t^2 + c^2 \cdot t + 2bd \cdot t + dc \\ &= 2b^2 \cdot t^3 + 3bc \cdot t^2 + (c^2 + 2bd) \cdot t + dc \\ \end{aligned}

最后的问题变成了一个3次多项式求解的问题......

g(t)=2b2t3+3bct2+(c2+2bd)t+dcg(t)=2b^2 \cdot t^3 + 3bc \cdot t^2 + (c^2 + 2bd) \cdot t + dc

卡丹方程解三次多项式

0=2b2t3+3bct2+(c2+2bd)t+dc=t3+3abb2t2+2a2+bdb2t+dab2\begin{aligned} 0 &= 2b^2 \cdot t^3 + 3bc \cdot t^2 + (c^2 + 2bd) \cdot t + dc \\ &=t^3 + \frac{3ab}{b^2} \cdot t^2 + \frac{2a^2 + bd}{b^2} \cdot t + \frac{da}{b^2} \end{aligned}
let  (a2=3abb2a1=2a2+bdb2a0=dab2)    x3+a2x2+a1x+a0=0let \ \ \begin{pmatrix} a_2 = \frac{3ab}{b^2} \\ a_1 = \frac{2a^2 + bd}{b^2} \\ a_0 = \frac{da}{b^2} \end{pmatrix} \implies x^3 + a_2x^2 + a_1x + a_0 = 0

求二阶导找出拐点,平移导0处(换元) 可以消除掉2次项

f(x)=x3+a2x2+a1x+a0    f(x)=6x+2a2=0xxa23    x3+a1x+a0=0\begin{aligned} f(x)=x^3 + a_2x^2 + a_1x + a_0 &\implies f''(x) = 6x + 2a_2 =0 \\ x\to x - \frac{a_2}{3} &\implies x^3 + a_1x + a_0 = 0 \end{aligned}

在掏出卡丹公式中的pp qq

let{p=a13q=a02    x3=3px+2qlet \begin{cases} p=-\frac{a_1}{3} \\ q=-\frac{a_0}{2} \\ \end{cases} \implies x^3 = 3px + 2q \\
let xs+t    x3=3st(s+t)+s3+t3    x3=3stx+s3+t3 \begin{aligned} let \ x\to s+t &\implies x^3 = 3st(s+t) + s^3 + t^3 \\ &\implies x^3 = 3st\cdot x + s^3 + t^3 \end{aligned}

将上述方程写成以下形式将等式12对比系数可得

{s3t3=p3s3+t3=2q\begin{cases} s^3 \cdot t^3 = p^3 \\ s^3 + t^3 = 2q \end{cases}

根据韦达定理, s3s^3 t3t^3 为等式 x22qx+p3=0x^2 - 2qx + p^3 = 0的解,于是有

{s3=q+q2p3t3=qq2p3\begin{cases} s^3 = q + \sqrt{q^2-p^3} \\ t^3 = q - \sqrt{q^2-p^3} \end{cases}

将等式完全展开,可以得到

x=s+t=q+q2p33+qq2p33x = s+t = \sqrt[3]{ q + \sqrt{q^2-p^3}} + \sqrt[3]{q - \sqrt{q^2-p^3}}

这套用三次单位根便可以完全展开

    x={q+q2p33+qq2p33ωq+q2p33+ω2qq2p33ω2q+q2p33+ωqq2p33ω=e2π3i=12+32i\implies x= \begin{cases} \sqrt[3]{ q + \sqrt{q^2-p^3}} + \sqrt[3]{q - \sqrt{q^2-p^3}} \\ \omega \sqrt[3]{ q + \sqrt{q^2-p^3}} + \omega^2\sqrt[3]{q - \sqrt{q^2-p^3}} \\ \omega^2\sqrt[3]{ q + \sqrt{q^2-p^3}} + \omega \sqrt[3]{q - \sqrt{q^2-p^3}} \\ \end{cases} \\ \omega = e^{\frac{2\pi}{3}i} = -\frac12 + \frac{\sqrt{3}}{2}i

这个解法存在的问题是,只有依次计算每一个公式才能知道那些根实根

三角换元解三次多项式

采用这种方法能够规避上面的根号,以及实根不确定的问题

依三倍角公式有

cos(3θ)=4cos3θ3cosθ\cos(3\theta) = 4\cos^3 \theta - 3\cos \theta

同样**这是一个三次方程,**所以如果存在以下的三次方程,可以得出

4x33xcos3θ=0    x=cosθ4x^3 - 3x - cos3\theta = 0 \implies x = cos\theta

还记得我们上一节等式1

x3=3px+2qx^3 = 3px + 2q

如果使用换元,让等式1能够满足三倍角公式,可以直接得出答案

x=2p C    4C33C=qpp=cos3θ    x=2pcos(ϕ+2kπ3),ϕ=arccos(qpp),k=0,1,2\begin{aligned} x = 2\sqrt{p} \ C &\implies 4C^3 - 3C = \frac{q}{p\sqrt{p}} = cos3\theta \\ &\implies x = 2\sqrt{p} cos(\frac{\phi +2k\pi}{3}), \phi = arccos(\frac{q}{p\sqrt{p}}) , \quad k = 0, 1, 2 \end{aligned}

这个解是代码中使用的方法

复平面极坐标解三次多项式

回到我们的等式

{s3=q+q2p3t3=qq2p3 \begin{cases} s^3 = q + \sqrt{q^2-p^3} \\ t^3 = q - \sqrt{q^2-p^3} \end{cases}

考虑三个实数根的情况q2<p3q^2 < p^3,如果q2<p3q^2 < p^3, s3s^3t3t^3为一对共轭复数

s3=q+p3q2is^3 = q + \sqrt{p^3 - q^2}i

s3s^3的magnitude rr

q2+p3q2=pp\sqrt{q^2 + p^3 - q^2} = p\sqrt[]{p}

s^3$$t^3放到极坐标可以得到下面这个图

image.png

s3s^3开立方根,利用棣莫弗定理公式可得

z1/3=r1/3(cos(ϕ+2kπ3)+isin(ϕ+2kπ3)),k=0,1,,n1z^{1/3} = r^{1/3} \left( \cos \left( \frac{\phi + 2k\pi}{3} \right) + i\sin \left( \frac{\phi + 2k\pi}{3} \right) \right), \quad k = 0, 1, \ldots, n-1

直接就得到了三个解

image.png

对于解0

x=s0+t0=2RealPart(s0)=2p  cos(ϕ/3)x = s_0 + t_0 = 2RealPart(s_0) = 2\sqrt{p} \ \ cos(\phi/3)

image.png

将s+t在极坐标复平台进行向量求和,于是我们得到与上一节一模一样的答案!!!而着背后其实就是欧拉公式

x=2pcos(ϕ+2kπ3),ϕ=arccos(qpp)k=0,1,2x= 2\sqrt{p} \cos \left( \frac{\phi + 2k\pi}{3} \right) , \phi = arccos(\frac{q}{p\sqrt{p}}) \quad k = 0, 1, 2

证明极小值只能在t0t_0t1t_1

我们这里回到用tt表示最终根的结果

ϕ[0,π]    ϕ3=θ[0,π3]\phi \in [0, \pi] \implies \frac{\phi}{3} = \theta \in [0, \frac{\pi}3]

geogebra: www.geogebra.org/classic/u8u…

image.png

对于任意θ[0,π3]\theta \in [0, \frac{\pi}3], 都有

cos(θ+21π3)<cos(ϕ+22π3)<cos(20π3)    t1<t2<t0cos(\theta+\frac{2*1\pi}{3}) < cos(\frac{\phi + 2*2\pi}{3})< cos(\frac{2*0\pi}{3}) \implies t_1 < t_2 < t_0

回到二阶贝塞尔曲线的函数,有

f(t)=bt2+ct+dddt[f(t)]2=g(t)=2b2t3+3bct2+(c2+2bd)t+dcg(t)=6b2t2+6bct+c2+2bd\begin{aligned} f(t) &= b \cdot t^2 + c \cdot t + d \\ \frac{d}{dt}[f(t)]^2 = g(t) &= 2b^2 \cdot t^3 + 3bc \cdot t^2 + (c^2 + 2bd) \cdot t + dc \\ g'(t) &= 6b^2*t^2 + 6bc*t + c^2 +2bd \end{aligned}

f(t)2f(t)^2的极值点一定是在一阶导数g(t)=0g(t)=0的3个根,即t_1$$t_2$$t_0。 如果有三个实根的只有以下两种图像 image.png

image.png

geogebra: www.geogebra.org/classic/qdr…

  1. t0t_0t1t_1有极大值,同时t2t_2为极小值
  2. t0t_0t1t_1有极小值,同时t2t_2为极大值

以上两个函数的二阶导数g(t)g'(t)的图像分别为以下两种,分别开口朝上和开口朝下

由于 g(t)=6b2t2+6bct+c2+2bdg'(t) = 6b^2*t^2 + 6bc*t + c^2 +2bd6t2>06t^2 > 0, 所以函数图像开口朝上,且有 t1<t2<t0t_1 < t_2 < t_0 从图像观察可以得出

g(t2)<max(g(t0),g(t1))(1)g'(t_2) < max(g'(t_0), g'(t_1)) \tag{1}

假设现在处于情况1 在t0t_0t1t_1有极大值,同时t2t_2为极小值。 那么根据费马引理有 极大值的二阶导数<0有

g(t0)<0  and  g(t1)<0(2)g'(t_0) < 0 \ \ and \ \ g'(t_1) < 0 \tag{2}

极小值的二阶导数>0 有

g(t2)>0(3)g'(t_2) > 0 \tag{3}

由不等式1,2可以推出

g(t2)<max(g(t0),g(t1))<0(4)g'(t_2) < max(g'(t_0), g'(t_1)) < 0 \tag{4}

不等式3,4矛盾,故情况1不存在。 贝塞尔曲线的最近距离一定是在根t0t0 t1t1

Q.E.D.Q.E.D.