计算机图形学:贝塞尔曲线和B样条

贝塞尔曲线和B样条

1.Bézier curve贝塞尔曲线

一个连续函数都可以用一个多项式无限逼近

贝塞尔曲线于 1962 年,由法国工程师皮埃尔·贝济埃(Pierre Bézier)所广泛发表,他运用贝塞尔曲线来为汽车的主体进行设计。

1.1 一阶贝塞尔曲线

image

B 1 ( t ) = ( 1 − t ) P 0 + t P 1 , t ∈ [ 0 , 1 ] \mathbf{B_1(t)= (1-t)P_0 + tP_1, t\in[0, 1]} B1(t)=(1t)P0+tP1,t[0,1]

1.2 二阶贝塞尔曲线

image

P 0 ′ = ( 1 − t ) P 0 + t P 1   P 1 ′ = ( 1 − t ) P 1 + t P 2   B 2 ( t ) = ( 1 − t ) P 0 ′ + t P 1 ′ = ( 1 − t ) 2 P 0 + 2 t ( 1 − t ) P 1 + t 2 P 2 \mathbf{P_0'= (1-t)P_0 + tP_1} \\ \ \\ \mathbf{P_1'= (1-t)P_1 + tP_2} \\ \ \\ \mathbf{B_2(t)= (1-t)P_0' + tP_1'=(1-t)^2P_0+2t(1-t)P_1+t^2P_2} \\ P0=(1t)P0+tP1 P1=(1t)P1+tP2 B2(t)=(1t)P0+tP1=(1t)2P0+2t(1t)P1+t2P2

1.3 三阶贝塞尔曲线

image

B 3 ( t ) = ( 1 − t ) 3 P 0 + 3 t ( 1 − t ) 2 P 1 + 3 t 2 ( 1 − t ) 2 P 1 + t 3 P 3 \mathbf{B_3(t)= (1-t)^3P_0 + 3t(1-t)^2P_1 + 3t^2(1-t)^2P_1 + t^3P_3} B3(t)=(1t)3P0+3t(1t)2P1+3t2(1t)2P1+t3P3

1.4 多阶贝塞尔曲线

Bernstein polynomial(伯恩斯坦多项式)

B n ( t ) = ∑ i = 0 n C n i P i ( 1 − t ) n − i t i = ∑ i = 0 n B i , n P i   C n i = n ! ( n − i ) ! ⋅ i !   B i , n = n ! ( n − i ) ! ⋅ i ! ( 1 − t ) n − i t i \mathbf{B_n(t)= \sum_{i=0}^{n} C_{n}^{i} P_i (1-t)^{n-i}t^i = \sum_{i=0}^{n} B_{i,n} P_i } \\ \ \\ \mathbf{C_{n}^{i} = \frac{n!}{(n-i)!\cdot i!}}\\ \ \\ \mathbf{B_{i,n} = \frac{n!}{(n-i)!\cdot i!}(1 - t)^{n-i}t^i}\\ Bn(t)=i=0nCniPi(1t)niti=i=0nBi,nPi Cni=(ni)!i!n! Bi,n=(ni)!i!n!(1t)niti

1.5 de Casteljau

计算机图形学:贝塞尔曲线和B样条_第1张图片

P i , j \bm{P_{i,j}} Pi,j表示第i列的第j个点
P i , j = ( 1 − t ) P i − 1 , j + t P i − 1 , j + 1   i ∈ [ 1 , n ] , j ∈ [ 1 , n − i + 1 ] \mathbf{P_{i, j} = (1 - t)P_{i - 1, j} + tP_{i - 1, j + 1}}\\ \ \\ \mathbf{i \in [1, n], j \in [1, n - i + 1]}\\ Pi,j=(1t)Pi1,j+tPi1,j+1 i[1,n],j[1,ni+1]

de Casteljau算法在Bézier曲线的光栅化阶段特别有用。

Vector2 Render::CalculateBezierPoint(const std::vector<Vector2>& ctl_vecs, float t){
    std::vector<Vector2> points(ctl_vecs);
    for (int i = 0; i < points.size() - 1; ++i) {
        for (int j = 0; j < points.size() - i - 1; ++j) {
            points[j] = interp(points[j], points[j + 1], t);
        }
    }
    return points[0];
}

1.6 升阶

增加控制点却不改变原先曲线的表现

Degree raising means that adding control points to raise the degree of the Bézier curves, but the shape and direction of the curve remain unchanged.

推导过程:

已知:
B n ( t ) = ∑ i = 0 n B i , n P i \mathbf{B_n(t)= \sum_{i=0}^{n} B_{i,n} P_i } Bn(t)=i=0nBi,nPi
则:
B n ( t ) = ∑ i = 0 n B i , n P i = ∑ i = 0 n ( 1 − t + t ) B i , n P i \mathbf{B_n(t)= \sum_{i=0}^{n} B_{i,n} P_i = \sum_{i=0}^{n} (1-t + t) B_{i,n} P_i} Bn(t)=i=0nBi,nPi=i=0n(1t+t)Bi,nPi

接下来看下相乘的两个式子

式子1:

( 1 − t ) B i , n P i = n ! ( n − i ) ! ⋅ i ! ( 1 − t ) n + 1 − i t i P i   = n + 1 − i n + 1 ( n + 1 ) ! ( n + 1 − i ) ! ⋅ i ! ( 1 − t ) n + 1 − i t i P i = n + 1 − i n + 1 B i , n + 1 P i   ( 1 − t ) B i , n P i = n + 1 − i n + 1 B i , n + 1 P i \mathbf{(1 - t)B_{i, n}P_i = \frac{n!}{(n-i)!\cdot i!}(1 - t)^{n + 1 - i}t^i P_i }\\ \ \\ \mathbf{= \frac{n + 1 - i}{n + 1}\frac{(n+1)!}{(n + 1 - i)!\cdot i!}(1 - t)^{n + 1 - i}t^i P_i = \frac{n + 1 - i}{n + 1}B_{i, n + 1}P_i}\\ \ \\ \mathbf{(1 - t)B_{i, n} P_i = \frac{n + 1 - i}{n + 1}B_{i, n + 1}P_i }\\ (1t)Bi,nPi=(ni)!i!n!(1t)n+1itiPi =n+1n+1i(n+1i)!i!(n+1)!(1t)n+1itiPi=n+1n+1iBi,n+1Pi (1t)Bi,nPi=n+1n+1iBi,n+1Pi

式子2:

t B i , n P i = n ! ( n − i ) ! ⋅ i ! ( 1 − t ) n − i t i + 1 P i   = i + 1 n + 1 ( n + 1 ) ! ( n + 1 − i − 1 ) ! ⋅ ( i + 1 ) ! ( 1 − t ) n + 1 − i − 1 t i + 1 P i = i + 1 n + 1 B i + 1 , n + 1 P i   t B i , n P i = i + 1 n + 1 B i + 1 , n + 1 P i \mathbf{tB_{i, n}P_i = \frac{n!}{(n-i)!\cdot i!}(1 - t)^{n - i}t^{i + 1} P_i }\\ \ \\ \mathbf{= \frac{i + 1}{n + 1}\frac{(n+1)!}{(n + 1 - i - 1)!\cdot (i + 1)!}(1 - t)^{n + 1 - i - 1}t^{i + 1} P_i = \frac{i + 1}{n + 1}B_{i + 1, n + 1}P_i}\\ \ \\ \mathbf{tB_{i, n}P_i = \frac{i + 1}{n + 1}B_{i + 1, n + 1}P_i}\\ tBi,nPi=(ni)!i!n!(1t)niti+1Pi =n+1i+1(n+1i1)!(i+1)!(n+1)!(1t)n+1i1ti+1Pi=n+1i+1Bi+1,n+1Pi tBi,nPi=n+1i+1Bi+1,n+1Pi

对于等式1,由于i = n + 1的时候等式为0,所以可以将等式变为

∑ i = 0 n n + 1 − i n + 1 B i , n + 1 P i = ∑ i = 0 n + 1 n + 1 − i n + 1 B i , n + 1 P i \mathbf{\sum_{i = 0}^{n}\frac{n + 1 - i}{n + 1}B_{i, n + 1}P_i = \sum_{i = 0}^{n + 1}\frac{n + 1 - i}{n + 1}B_{i, n + 1}P_i} i=0nn+1n+1iBi,n+1Pi=i=0n+1n+1n+1iBi,n+1Pi

对于等式2我们可以将i用i-1替代,因为i=-1时等式为0,所以成立,所以

∑ i = 0 n i + 1 n + 1 B i + 1 , n + 1 P i = ∑ i = 0 n + 1 i n + 1 B i , n + 1 P i − 1 \mathbf{\sum_{i = 0}^{n}\frac{i + 1}{n + 1}B_{i + 1, n + 1}P_i = \sum_{i = 0}^{n + 1}\frac{i}{n + 1}B_{i, n + 1}P_{i - 1}} i=0nn+1i+1Bi+1,n+1Pi=i=0n+1n+1iBi,n+1Pi1

将两式子合并最终结果为:

B n ( t ) = ∑ i = 0 n B i , n P i = ∑ i = 0 n + 1 ( n + 1 − i n + 1 P i + i n + 1 P i − 1 ) B i , n + 1 \mathbf{B_n(t)= \sum_{i=0}^{n} B_{i,n} P_i = \sum_{i = 0}^{n + 1}(\frac{n + 1 - i}{n + 1}P_i + \frac{i}{n + 1}P_{i - 1}) B_{i, n + 1}} Bn(t)=i=0nBi,nPi=i=0n+1(n+1n+1iPi+n+1iPi1)Bi,n+1

其中 P − 1 , P n + 1 \bm{P_{-1}},\bm{P_{n + 1}} P1,Pn+1值随意,毕竟最后乘以系数后均为0

新的节点推导公式为:
P i ∗ = ( n + 1 − i n + 1 P i + i n + 1 P i − 1 ) \mathbf{P_i^* = (\frac{n + 1 - i}{n + 1}P_i + \frac{i}{n + 1}P_{i - 1})} Pi=(n+1n+1iPi+n+1iPi1)

CODE:

std::vector<Vector2> Render::RaiseDegree(const std::vector<Vector2>& ctl_vecs){
    unsigned long new_degree = ctl_vecs.size();
    std::vector<Vector2> new_ctl_vecs(new_degree + 1);
    new_ctl_vecs[0] = ctl_vecs[0];
    new_ctl_vecs[new_degree] = ctl_vecs[new_degree - 1];
    for (int i = 1; i < new_degree; ++i) {
        float t = 1.0 - static_cast<float>(i) / new_degree;
        new_ctl_vecs[i] = interp(ctl_vecs[i - 1], ctl_vecs[i], t);
    }
    return new_ctl_vecs;
}

1.7 降阶

减少控制点去逼近原先曲线的表现

Degree reduction is the opposite of degree raising, is to find a curve defined by new control points with minimum error

根据升阶公式

P i ∗ = ( n − i n P i + i n P i − 1 ) \mathbf{P_i^* = (\frac{n - i}{n}P_i + \frac{i}{n}P_{i - 1})} Pi=(nniPi+niPi1)

可以得到如下两个递推式

P i ′ = n P i ∗ − i P i − 1 ′ n − i i = 0 , 1 , 2... n − 1   P i − 1 ′ ′ = n P i ∗ − ( n − i ) P i ′ ′ i i = n , n − 1 , . . . 1 \mathbf{P_i' = \frac{nP_i^* - iP_{i - 1}'}{n - i} \qquad i = 0, 1, 2...n-1}\\ \ \\ \mathbf{P_{i - 1}'' = \frac{nP_i^* - (n - i)P_{i}''}{i} \qquad i=n, n-1,...1}\\ Pi=ninPiiPi1i=0,1,2...n1 Pi1=inPi(ni)Pii=n,n1,...1

一个与起点重合,然后逐渐偏离;一个与终点重合,然后逐渐偏离

Then we have two kinds of degree reduction schemes

1.7.1 Forrest (1972)

P i ^ = { P i ′ , i = 0 , 1 , . . . , [ n − 1 2 ] P i ′ ′ , i = [ n − 1 2 ] + 1 , . . . n − 1 \mathbf{\hat{P_i} = \left\{\begin{matrix} P_i' , & i = 0,1,..., \left [ \frac{n - 1}{2} \right ] \\ P_i'', & i = \left[\frac{n - 1}{2} \right ] + 1,...n - 1 \end{matrix}\right.} Pi^={Pi,Pi,i=0,1,...,[2n1]i=[2n1]+1,...n1

1.7.2 Farin (1983)

P i ^ = ( 1 − i n − 1 ) P i ′ + i n − 1 P i ′ ′ \mathbf{\hat{P_i} = (1 - \frac{i}{n - 1})P_i' + \frac{i}{n - 1}P_i''} Pi^=(1n1i)Pi+n1iPi


2 B-Spline

P n ( t ) = ∑ i = 0 n P i N i , k ( t )   t ∈ [ 0 , 1 ] P_n(t) = \sum_{i=0}^{n}P_iN_{i, k}(t)\\ \ \\ t \in [0, 1]\\ Pn(t)=i=0nPiNi,k(t) t[0,1]

2.1 样条

样条(Spline)其实是一种在造船和工程制图时用来画出光滑形状的工具。样条是一根柔软但有弹性的长条物,有些像尺子。将两端和几个点用钉子固定之后,便可以产生顺滑的曲线。

计算机图形学:贝塞尔曲线和B样条_第2张图片

2.2 Cox-de Boor recursion formula

N i , 1 = { 1 t i < x < t i + 1 0 o t h e r w i s e   N i , k = t − t i t i + k − 1 − t i N i , k − 1 ( t ) + t i + k − t t i + k − t i + 1 N i + 1 , k − 1 ( t ) \mathbf{N_{i,1} = \left\{\begin{matrix} 1 & t_i < x < t_{i + 1}\\ 0 & otherwise \end{matrix}\right.}\\ \ \\ \mathbf{N_{i,k} = \frac{t - t_i}{t_{i+k-1} - t_i}N_{i, k-1}(t) + \frac{t_{i+k} - t}{t_{i+k} - t_{i+1}}N_{i+1, k-1}(t)}\\ Ni,1={10ti<x<ti+1otherwise Ni,k=ti+k1tittiNi,k1(t)+ti+kti+1ti+ktNi+1,k1(t)

我们让 t 0 = 0 , t 1 = 1 , t 2 = 2 , t 3 = 3 t_0 = 0,t_1 = 1,t_2 = 2, t_3 = 3 t0=0,t1=1,t2=2,t3=3,则 N 0 , 1 , N 1 , 1 , N 2 , 1 N_{0, 1}, N_{1, 1}, N_{2, 1} N0,1,N1,1,N2,1如下图所示:

在这里插入图片描述

递推关系如下(此图为wiki上的,用的是次-degree,而上面的公式用的是阶-order,degree=order-1):

计算机图形学:贝塞尔曲线和B样条_第3张图片

2.2.1 定义区间

[ t k − 1 , t n + 1 ] [t_{k-1},t_{n+1}] [tk1,tn+1]区间内有相应数量的基函数,该区间才有意义:

计算机图形学:贝塞尔曲线和B样条_第4张图片

2.3 分类

2.3.1 均匀B样条(Uniform B-Spline)

节点成等差数列均匀分布

计算机图形学:贝塞尔曲线和B样条_第5张图片

2.3.2 准均匀B样条(Quasi-Uniform B-Spline)

让起点和终点都具有K的重复度,使得曲线从起点开始,到终点结束

计算机图形学:贝塞尔曲线和B样条_第6张图片

2.3.3 分段Bezier曲线(Piecewise Bezier Curve)

  • 起点节点和终点节点都具有K的重复度
  • 所有其它节点都具有K-1的重复度
  • 这样所有的曲线段都是Bezier曲线,各自独立

计算机图形学:贝塞尔曲线和B样条_第7张图片

2.3.4 非均匀B样条(Non-uniform B-Spline)

  • 起始点重复度都≤K
  • 其它节点重复度≤K-1

De Boor’s Algorithm

你可能感兴趣的:(计算机图形学)