Skip to content
Notes
GitHub

从贝塞尔曲线到概率模型

前情提要

在之前的视频中,我们讲到了动画是怎样构成的,其中最重要的一个函数就是 interpolate,能够对两个状态进行补间运算,运算式是这样写的

def interpolate(start, end, alpha):
return (1 - alpha) * start + alpha * end
def interpolate(start, end, alpha):
return (1 - alpha) * start + alpha * end

穿插一阶贝塞尔动画

其实在此处 interpolate 的含义变成了相对狭义的补间,即线性插值. 但对三个值,甚至更多的值进行插值,也能够算作是补间. 因此,在这里我们采用 unity 中的一个函数 lerp,即线性插值函数,用于相互区分.

## 这里的算式和上面其实是一样的,而且我还是更喜欢上面的一种写法
def lerp(p0, p1, t):
return p0 + (p1 - p0) * t
## 这里的算式和上面其实是一样的,而且我还是更喜欢上面的一种写法
def lerp(p0, p1, t):
return p0 + (p1 - p0) * t

而对于 3 个值 P0,P1,P2\displaystyle{ P _{ 0 } , P _{ 1 } , P _{ 2 } } 的补间,我们应该如何去思考呢?

首先,我们应该很容易想到,先对某一部分,即 P0\displaystyle{ P _{ 0 } }P1\displaystyle{ P _{ 1 } }P1\displaystyle{ P _{ 1 } }P2\displaystyle{ P _{ 2 } } 分别进行线性插值,并分别用 A,B\displaystyle{ A , B } 来标记它们,于是我们有

A=lerp(P0,P1,t)B=lerp(P1,P2,t)\begin{aligned} A&=\text{lerp}(P_0,P_1,t)\\ B&=\text{lerp}(P_1,P_2,t) \end{aligned}

穿插两个一阶贝塞尔动画
然后再加入它们的补间动画,即二阶贝塞尔

接着,我们再对 A\displaystyle{ A }B\displaystyle{ B } 进行线性插值,设最终结果为 R\displaystyle{ R },于是就有

R(t)=(1t)A+tB=(1t)[(1t)P0+tP1]+t[(1t)P1+tP2]=P0(1t)2+2P1(1t)t+P2t2\begin{aligned} R(t)&=(1-t)\cdot A + t\cdot B\\ &=(1-t)[(1-t)P_0+tP_1]+t[(1-t)P_1+tP_2]\\ &=P_0(1-t)^2+2P_1(1-t)t+P_2t^2 \end{aligned}

用代码来书写可以写成这样

def quadratic(p0, p1, p2, t):
A = lerp(p0, p1, t)
B = lerp(p1, p2, t)
return lerp(A, B, t)
def quadratic(p0, p1, p2, t):
A = lerp(p0, p1, t)
B = lerp(p1, p2, t)
return lerp(A, B, t)

而这其实就是贝塞尔曲线的方程了,这里的方程是二阶的,如果需要用三阶可以继续写下去.

穿插由二阶构造三阶的动画

def cubic(p0, p1, p2, p3, t):
A = quadratic(p0, p1, p2, t)
B = quadratic(p1, p2, p3, t)
return lerp(A, B, t)
def cubic(p0, p1, p2, p3, t):
A = quadratic(p0, p1, p2, t)
B = quadratic(p1, p2, p3, t)
return lerp(A, B, t)

经过归纳,我们可以得到 n\displaystyle{ n } 阶贝塞尔曲线的一般方程

Bn(t)=i=0nPi(ni)(1t)niti,(ni)=n!i!(ni)!B^n(t)=\sum_{i=0}^{n}P_i{n\choose i}(1-t)^{n-i}t^i, {n\choose i}={n!\over i!(n-i)!}

从贝塞尔曲线到概率模型

我知道这一部分很扯,但不知道为什么我就是能想到这一步

n\displaystyle{ n } 阶贝塞尔曲线的方程过于复杂,我们先看一个三阶贝塞尔

B3(t)=(30)P0(1t)3+(31)P1(1t)2t+(32)P2(1t)t2+(33)P3t3=P0(1t)3+3P1(1t)2t+3P2(1t)t2+P3t3=P0(t3+3t23t+1)+P1(3t36t2+3t)+P2(3t23t3)+P3t3\begin{aligned} B^3(t)=&{3\choose 0}P_0(1-t)^3+{3\choose 1}P_1(1-t)^2t+{3\choose 2}P_2(1-t)t^2+{3\choose 3}P_3t^3\\ =&P_0(1-t)^3+3P_1(1-t)^2t+3P_2(1-t)t^2+P_3t^3\\ =&P_0(-t^3+3t^2-3t+1)\\ +&P_1(3t^3-6t^2+3t)\\ +&P_2(3t^2-3t^3)\\ +&P_3t^3 \end{aligned}

可以发现,在最后一步把立方、平方等项拆开的时候,这些式子的和很像是一个加权平均数,或者说是一个数学期望. 而更巧合的事情发生了,我们分别设 Pi\displaystyle{ P _{ i } } 的系数是 ai(i=0,1,2,3)\displaystyle{ a _{ i } \left( i = 0 , 1 , 2 , 3 \right) },可以发现

a0+a1+a2+a3=(t3+3t23t+1)+(3t36t2+3t)+(3t23t3)+t3=1\displaystyle{ a _{ 0 } + a _{ 1 } + a _{ 2 } + a _{ 3 } = \left( - t ^{ 3 } + 3 t ^{ 2 } - 3 t + 1 \right) + \left( 3 t ^{ 3 } - 6 t ^{ 2 } + 3 t \right) + \left( 3 t ^{ 2 } - 3 t ^{ 3 } \right) + t ^{ 3 } = 1 }

也就是说,ai(i=0,1,2,3)\displaystyle{ a _{ i } \left( i = 0 , 1 , 2 , 3 \right) } 可以看作是一个随机事件中每个事件的概率,而 Pi(i=0,1,2,3)\displaystyle{ P _{ i } \left( i = 0 , 1 , 2 , 3 \right) } 可以看作是这些随机事件,B3(t)\displaystyle{ B ^{ 3 } \left( t \right) } 就意味着这些事件的数学期望.

这么说着抽象的事件似乎会让人摸不着头脑,我们不妨把 Pi\displaystyle{ P _{ i } } 看作是平面或空间内的点(为了方便我们在这里先只看平面),B3(t)\displaystyle{ B ^{ 3 } \left( t \right) } 意味着在 Pi(i=0,1,2,3)\displaystyle{ P _{ i } \left( i = 0 , 1 , 2 , 3 \right) } 所在平面的某一个区域随机取点,而得到的数学期望. 这个期望似乎会随着 t\displaystyle{ t } 的改变而改变.(这段好像有点怪,没有扯到一起去)

我们尝试写出这个分布列(随机变量 X\displaystyle{ X } 可以取 P0,P1,P2,P3\displaystyle{ P _{ 0 } , P _{ 1 } , P _{ 2 } , P _{ 3 } } 中的点)

X\displaystyle{ X }P0\displaystyle{ P _{ 0 } }P1\displaystyle{ P _{ 1 } }P2\displaystyle{ P _{ 2 } }P3\displaystyle{ P _{ 3 } }
p\displaystyle{ p }(1t)3\displaystyle{ \left( 1 - t \right) ^{ 3 } }3(1t)2t\displaystyle{ 3 \left( 1 - t \right) ^{ 2 } t }3(1t)t2\displaystyle{ 3 \left( 1 - t \right) t ^{ 2 } }t3\displaystyle{ t ^{ 3 } }

对于 t\displaystyle{ t }[0,1]\displaystyle{ \left[ 0 , 1 \right] } 内的不同值,这个分布列会有不同的结果,而将这个分布列画到坐标轴上,似乎暂时也看不出特别明显的规律.

但我们反过来思考一下,如果是一个随机变量 Y\displaystyle{ Y ^{\prime} },满足一个两点分布,即 Y(01qp)Y'\sim \left(\begin{array}{l} 0 & 1 \\ q & p\end{array} \right),对这个实验独立地进行 n\displaystyle{ n } 次,那么这个实验就变成了贝努利实验,即存在随机变量 YB(n,p)Y\sim B(n,p). 对于实验结果,我们有

P(Y=m)=(nm)(1t)nmtm(0mn,mN)P(Y=m)={n\choose m}(1-t)^{n-m}t^m\qquad(0\leqslant m \leqslant n,m\in\mathbb{N})

这是一个二项分布,而概率似乎与贝塞尔曲线方程的某些系数一模一样. 同时,这两者也有一些共通性. 在贝塞尔曲线中,t\displaystyle{ t } 表示所占的某一段直线或曲线的百分比,取值范围是 [0,1]\displaystyle{ \left[ 0 , 1 \right] }. 而一个事件发生的概率,同样是 [0,1]\displaystyle{ \left[ 0 , 1 \right] },两者是否有一些巧合呢?或许我们需要增大一下二项分布的样本容量,与此同时增大贝塞尔曲线的阶数,才能看的更加明显.

建立二项分布模型 增大样本容量

某人射击打靶,射中的概率为 p\displaystyle{ p },每次射击不会相互影响,那么他射 n\displaystyle{ n } 枪,求射中目标 m\displaystyle{ m } 次的概率.
在这个题目中,每次射击都是一次独立的贝努利实验,这样的实验做 n\displaystyle{ n } 次,击中目标的次数设为随机变量 X\displaystyle{ X },那么 X\displaystyle{ X } 服从一个二项分布,即 XB(n,p)X\sim B(n,p).

现在还没有代入具体数字,我们似乎没法给出一些明确的答案. 那么我们不妨就让 n=20,p=0.6\displaystyle{ n = 20 , p = 0.6 }. 在这里我们就不进行模拟了,我们直接用公式算出每一种可取的 m\displaystyle{ m } 的概率.

P(X=m)=(nm)(1p)nmpm=(20m)(25)20m(35)m\begin{aligned} P(X=m)&={n\choose m}(1-p)^{n-m}p^m\\ &={20\choose m}\left({2\over 5}\right)^{20-m}\left({3\over 5}\right)^m \end{aligned}

同时,我们用图像画出每个 m\displaystyle{ m } 所对应的图像. 在这里,每个方柱的面积(而不是高度)代表 X\displaystyle{ X } 取到 m\displaystyle{ m } 时的概率.

public/manim/doc_image_1.png

可以看到,整个图像呈现出中间高,两边低的样子.

(概率论经典题)有时我们可能会遇到这样的问题,假设击中次数为 m\displaystyle{ m },求 P(m1m<m2)P(m_1\leqslant m < m_2). 这个问题看上去也并不困难,由于射中次数 m\displaystyle{ m } 取不同的值时不会相互干扰,所以有

P(m1m<m2)=m=m1m21P(X=m)P(m_1\leqslant m<m_2)=\displaystyle\sum_{m=m_1}^{m_2-1}P(X=m)

也就是只需要将图中在范围内的矩形面积相加就可以了. 同样地,所有这些事件的概率之和为 1\displaystyle{ 1 },即

P(0mn)=m=0nP(X=m)=1P(0\leqslant m\leqslant n)=\displaystyle\sum_{m=0}^{n}P(X=m)=1

在这里,矩形数量并不多,如果所需要计算的量比较少,那么就可以直接手算计算机运算相加就可以了.

但如果样本很多,范围也很大呢?这样用手算一个一个相加肯定是相当耗费精力的.

进一步增大样本容量

现在,我们将试验次数增加. 之前提到了用面积来表示 X=m\displaystyle{ X = m } 的概率;但如果用高度来表示,那么这些方柱会越来越矮,最终缩到横轴为止. (3b1b 讲过这件事情)

这时我们发现,我们需要不断地拉长横轴,不妨给横轴除以 n\displaystyle{ n },此时横轴表示的,是射中次数与实验次数的商. 纵轴表示的,是 n\displaystyle{ n }X=m\displaystyle{ X = m } 的概率,即 nP(X=m)\displaystyle{ n P \left( X = m \right) }. 从概念上来看,我们所要求的射中 m\displaystyle{ m } 枪的概率,变成了射中概率为 mn{m\over n} 的概率,即“概率的概率”.

现在,横轴所表示的变量取值范围变成了 [0,1]\displaystyle{ \left[ 0 , 1 \right] },它所表达的含义似乎很像是概率 p\displaystyle{ p }. 但在我们平常的概念中,概率 p\displaystyle{ p } 可用取到的值应该是 [0,1]\displaystyle{ \left[ 0 , 1 \right] } 内连续的数. 在上面的例题中,实验次数和击中次数是离散的,只能说,当试验次数充分大时,这种离散的情况可以近似的看作是连续的. 也就是说,当二项分布的样本容量足够大时,它的概率分布可以近似地看作是一个连续型的分布.

原本打算在这里插入如何从二项分布推导正态分布,但是难度还是有一点的。然而,写到这里发现讨论的方向似乎错了,原因如下

到这里为止,这个“贝塞尔曲线的平滑”与“近似连续型的分布”本质上还有很大的区别,前者指的是通过一个 Bn(t)\displaystyle{ B ^{ n } \left( t \right) } 函数,使得曲线变得平滑,这里如果想要达到平滑,不是依靠对 n\displaystyle{ n } 的取样而平滑的,而是对 t\displaystyle{ t } 进行精细化取样才达到平滑的;而后者的平滑,是通过对 n\displaystyle{ n } 取极限来达到平滑的效果。所以讨论到这里,方向好像偏掉了