首页 > 其他分享 >B-spline (1)

B-spline (1)

时间:2024-01-27 15:45:19浏览次数:22  
标签:space Bezier Curve 控制点 knot spline

1.什么是B-spline

Bezier Curve的缺点主要是:

  • nonlocality,移动一个控制点会影响整条曲线
  • 高阶曲线,曲线离控制点很远

对此,可以把N条Bezier Curve组合起来。如下图所示,是两条3次Bezier Curve在D点连接而得。

此时,该曲线是一条$C^0$曲线,共有7个控制点。若想得到一条$C^1$曲线,则需要两条Bezier Curve在D点的导数相同。通过Bezier Curve的导数表达式,可知需要C,D,E点共线并且$|CD|=|DE|$。此时D点失去了控制作用,共用6个控制点,如下图所示。

进一步地,若想得到一条$C^2$曲线,则需要D点的二阶导数相同。那么此时需要又一个控制点失去作用,例如E点,如下图所示。

可见,N条3阶Bezier Curve拼接成一条$C^0$曲线,需要$4N-(N-1)=3N+1$个控制点;一条$C^1$曲线需要$3N+1-(N-1)=2N+2$个控制点;一条$C^2$曲线需要$2N+2-(N-1)=N+3$个控制点。

进而,N条k阶的Bezier Curve拼接成一条$C^{k-1}$连续的B-spline曲线需要N+k个控制点。

但值得注意的是,在上图中,A,B,C,F,G并不是B-spline的控制点,控制点应该是下图的S0-S4

B-spline具有局部性,例如移动S0,并不会对第二段Bezier Curve产生影响。同样地,移动S4,也不会对第一段Bezier Curve产生影响。B-spline的性质可总结为

  • The curve starts and ends at the first and last control vertices. 
  • The curve is tangent to the first and last edges of its control polygon. 
  • The B-spline curve is contained in the convex hull of its control polygon. 如下图所示。
  • If the B-spline curve is of degree n, it is contained in the union of the convex hulls of every n+1 consecutive vertices. 如下图所示。

 

  • The shape of the B-spline curve is roughly the same as the shape of its control polygon.
  • The B-spline curve twists less than its control polygon. 如下图所示。

  • Moving a vertex of the control polygon affects only a part of the curve close to the vertex moved.
  • The B-spline curve can be translated, rotated or reflected, by translating, rotating, or reflecting the vertices of its control polygon.

2.B-spline表达式

由N条k阶的Bezier Curve组成k阶B-spline曲线有N+k个控制点。B-spline的表达式可以写为:

$$ BS(t)=\sum_{i=0}^{N+k-1}P_iB_{i,k}(t)\space\space\space t\in[0,N]\space\space\space (1) $$

当N=3,k=3时,对应的6个基函数如下图所示。

可见,基函数$B_{0,3}$的有效区间,即值不为零的区间是[0,1],基函数$B_{1,3}$的有效区间是[0,2]。

The knots of a B-spline curve are the endpoints of the supports of the basis functions that define the curve. 这6个基函数的knots为: $$ \begin{array}{l} supp B_{0,3}=[0,1]\\ supp B_{1,3}=[0,2] \\ supp B_{2,3}=[0,3]\\ supp B_{3,3}=[0,3]\\ supp B_{4,3}=[1,3]\\ supp B_{5,3}=[2,3] \end{array} $$

The knot vector comprises the knots of the basis functions that define a S-spline curve, listed from smallest to largest. 上方B-spline对应的knot vector为$V=\left \{0,0,0,0,1,2,3,3,3,3\right \}$。

N条k阶Bezier Curve组成的k阶B-spline曲线对应的knot vector为:

3.Cox-de boor formula or De Boor's Algorithm

要想根据控制点生成B-spline,需要计算出相应的基函数。De Boor's Algorithm就是一种用knot vector递归计算出基函数的算法。以上方的3阶B-spline为例,他的思想就是通过$B_{0,0}$和$B_{1,0}$得到$B_{0,1}$,以及通过$B_{1,0}$和$B_{2,0}$得到$B_{1,1}$,进而通过$B_{0,1}$和$B_{1,1}$得到$B_{0,2}$,如此递归地得到$B_{0,3}-B_{5,3}$。

De Boor's Algorithm计算公式如下: $$ B_{i,k}(t)=\frac{t-V[i]}{V[i+k]-V[i]}B_{i,k-1}(t)+\frac{V[i+k+1]-t}{V[i+k+1]-V[i+1]}B_{i+1,k-1}(t)\space\space\space(2) $$ 并且 $$ B_{i,0}(t)=\begin{cases} 1,\space\space\space t\in[V[i],V[i+1]) \\ 0,\space\space\space otherwise \end{cases}\space\space\space(3) $$ 以及$B_{i,0}=0\space\space if\space V[i]=V[i+1]$,以及分母为0,则为0。

python代码如下:

import numpy as np
import matplotlib.pyplot as plt

def generateBspline(controlPoints,k,num=100):
    n=len(controlPoints)
    # knot vector
    v0=np.linspace(0,0,k+1)
    v1=np.linspace(1,n-k-1,n-k-1)
    v2=np.linspace(n-k,n-k,k+1)
    knot=np.concatenate((v0,v1,v2))
    
    t=np.linspace(0,n-k,num)

    # order 0
    BF=np.zeros((knot.size-1,num))
    for i in range(knot.size-1):
        if knot[i]!=knot[i+1]:
            for j in range(num):
                time=t[j]
                if i==knot.size-k-2:
                    if knot[i]<=time<=knot[i+1]:BF[i][j]=1
                else:
                    if knot[i]<=time<knot[i+1]:BF[i][j]=1
    
    # recurison
    for order in range(1,k+1):
        tmp=np.zeros((knot.size-1-order,num))
        for i in range(knot.size-1-order):
            for j in range(num):
                time=t[j]
                if knot[i+order]!=knot[i]:
                    tmp[i][j]+=(time-knot[i])*BF[i][j]/(knot[i+order]-knot[i])
                if knot[i+order+1]!=knot[i+1]:
                    tmp[i][j]+=(knot[i+order+1]-time)*BF[i+1][j]/(knot[i+order+1]-knot[i+1])
        BF=tmp
    
    points=np.zeros((num,2))
    for i in range(num):
        for p in range(n):
            point=controlPoints[p]
            points[i]+=BF[p][i]*point
    return points
    
def drawBspline(points,controlPoints):
    fig,ax=plt.subplots()
    ax.plot(points[:,0],points[:,1])
    ax.plot(controlPoints[:,0],controlPoints[:,1],'o--')
    plt.show()

# control points S0-S4
controlPoints=np.array([[0, 0], [2, 3], [6, 3], [9, 0],[10,3]])
points=generateBspline(controlPoints,3)
drawBspline(points,controlPoints)

 

标签:space,Bezier,Curve,控制点,knot,spline
From: https://www.cnblogs.com/larissa-0464/p/17990852

相关文章

  • 样条曲线 spline curves
        所谓样条曲线是指给定一组控制点而得到一条曲线,曲线的大致形状由这些点予以控制,一般可分为插值样条和逼近样条两种,插值样条通常用于数字化绘图或动画的设计,逼近样条一般用来构造物体的表面。    样条曲线是经过一系列给定点的光滑曲线。最初,样条曲线都是借助于物理样......
  • 安装torch_scatter,torch-sparse,torch-cluster,torch-spline-conv,torch-geometric
    1.查询torch版本号进入https://pytorch-geometric.com/whl/找到对应的torch版本>>点击进入   2.找到匹配的包  点击下载即可 3.使用pip离线安装pip......
  • cube spline---三次样条插值
    插值是离散函数逼近的重要方法,利用它可通过函数在有限个点处的取值状况,估算出函数在其他点处的近似值。与拟合不用经过每个已知点不同,插值需要经过每个已知点,另外并不是阶......
  • spline-spark-agent收集Iceberg(Spark程序)血缘
    一、背景使用Spark操作Iceberg(HiveCataLog的方式),使用Spline-Agent收集Spark作业的血缘。二、编译1、下载源码包:https://github.com/AbsaOSS/spline-spark-agent.git......
  • 【OpenGL】自己实现B-Spline曲线
    【OpenGL】自己实现B-Spline曲线​​1.绘制目标​​​​2.核心代码​​​​3.运行结果​​1.绘制目标自己实现B-Spline曲线。2.核心代码/TODO//////基于CdM公式计算B-Splin......
  • IfcBSplineSurfaceForm
    IfcBSplineSurfaceForm类型定义IfcBSplineSurfaceForm表示某个特定形状的曲面的一部分。 注:定义符合ISO/CD10303-42:1992此类型用于指示B样条曲线曲面表示某种特定......
  • IfcBSplineCurveForm
    IfcBSplineCurveForm类型定义IfcBSplineCurveForm表示某些特定形式的曲线的一部分。 注:定义符合ISO/CD10303-42:1992此类型用于指示B样条曲线代表某种特定形式的曲......