BasicBSpline.jl - Basic mathematical operations for B-spline

Hi all,
I’m pleased to announce my package BasicBSpline.jl v0.9.4 (repo, docs).

Introduction

This package provides basic mathematical operations for B-spline.

  • B-spline basis function
  • Some operations for knot vector
  • Some operations for B-spline space (piecewise polynomial space)
  • B-spline manifold (includes curve, surface, and solid)
  • Refinement algorithm for B-spline manifold
  • Interpolations (not fully supported. see documentation)
  • Fitting control points for a given function (in BasicBSplineFitting.jl)
  • Export graphics (in BasicBSplineExporter.jl)

Basic usage

Evaluating B-spline function

julia> using BascBSpline

julia> using Plots

julia> k = KnotVector([0.0, 1.5, 2.5, 5.5, 8.0, 9.0, 9.5, 10.0])
KnotVector([0.0, 1.5, 2.5, 5.5, 8.0, 9.0, 9.5, 10.0])

julia> P = BSplineSpace{2}(k) # 2nd degree piecewise polynomial space
BSplineSpace{2, Float64, KnotVector{Float64}}(KnotVector([0.0, 1.5, 2.5, 5.5, 8.0, 9.0, 9.5, 10.0]))

julia> b = bsplinebasis(P,1,1.2)
0.38399999999999995

julia> plot(P)

julia> scatter!([1.2], [b])

bsb

Creating NURBS surface

The following example creates a torus.

using BasicBSpline
using StaticArrays
using Plots
plotly()

p = 2
k = KnotVector([0,0,0,1,1,2,2,3,3,4,4,4])
P = BSplineSpace{p}(k)

R = 3
r = 1

a0 = [
    SVector( 1, 0, 0),
    SVector( 1, 1, 0),
    SVector( 0, 1, 0),
    SVector(-1, 1, 0),
    SVector(-1, 0, 0),
    SVector(-1,-1, 0),
    SVector( 0,-1, 0),
    SVector( 1,-1, 0),
    SVector( 1, 0, 0)
]

a1 = (R+r)*a0
a5 = (R-r)*a0
a2 = [p+r*SVector(0,0,1) for p in a1]
a3 = [p+r*SVector(0,0,1) for p in R*a0]
a4 = [p+r*SVector(0,0,1) for p in a5]
a6 = [p-r*SVector(0,0,1) for p in a5]
a7 = [p-r*SVector(0,0,1) for p in R*a0]
a8 = [p-r*SVector(0,0,1) for p in a1]
a9 = a1

a = hcat(a1,a2,a3,a4,a5,a6,a7,a8,a9)
w = [1,1/√2,1,1/√2,1,1/√2,1,1/√2,1]
M = RationalBSplineManifold(a,w*w',P,P)
plot(M)

image

A function refinement can be used to insert knot vectors without changing its shape.

N = refinement(M, (KnotVector([0.5, 0.8]), KnotVector([0.2,3.4])))
plot(N)

image

Interpolations

Currently, BasicBSpline.jl doesn’t have API for interpolations, but it is not hard to implement some basic interpolation algorithms with this package. (more docs about interpolations)

using BasicBSpline
using Plots

function interpolate(xs::AbstractVector, fs::AbstractVector{T}) where T
    # Cubic open B-spline space
    p = 3
    k = KnotVector(xs) + KnotVector([xs[1],xs[end]]) * p
    P = BSplineSpace{p}(k)

    # dimensions
    m = length(xs)
    n = dim(P)

    # The interpolant function has a f''=0 property at bounds.
    ddP = BSplineDerivativeSpace{2}(P)
    dda = [bsplinebasis(ddP,j,xs[1]) for j in 1:n]
    ddb = [bsplinebasis(ddP,j,xs[m]) for j in 1:n]

    # Compute the interpolant function (1-dim B-spline manifold)
    M = [bsplinebasis(P,j,xs[i]) for i in 1:m, j in 1:n]
    M = vcat(dda', M, ddb')
    y = vcat(zero(T), fs, zero(T))
    return BSplineManifold(M\y, P)
end

# Example inputs
xs = [1, 2, 3, 4, 6, 7]
fs = [1.3, 1.5, 2, 2.1, 1.9, 1.3]
f = interpolate(xs,fs)

# Plot
scatter(xs, fs)
plot!(t->f(t))

int

Comparison to other packages

Of course, there are other packages that provide B-spline functions.

These packages are excellent, but they have different focus and functionality from BasicBSpline.jl.
BasicBSpline.jl was developed with the following motivations.

  • Mathematical oriented
    • Knot vector operations
      • We use + for addition of knot vectors because commutative and not just a union of sets. (docs)
      • e.g. KnotVector([1,2]) + KnotVector([1,2,3]) == KnotVector([1,1,2,2,3])
    • BSplineSpace type as a linear space
      • e.g. P1 = BSplineSpace{2}(KnotVector) is treated as a linear space. (docs)
      • ⊆(::BSplineSpace, ::BSplineSpace) can be used to check lhs is a linear subspace of rhs.
    • See BasicBSpline.jl#172 for a comment by @empet.
  • Focus on basic B-splline functionalities
    • B-spline has many applications. We aimed to create a basic package that can be applied to geometric shape representation, interpolation, and more!
    • In contrast, BSplineKit.jl provides more functionality such as banded Galerkin and collocation matrices.
    • Interpolations.jl also supports B-spline, but it seems no functionality for shape representation.
  • Less dependency
  • High performance
    • We are trying to create the fastest B-spline Julia package.:smile:

Any feedback is welcome, one of my dreams in Julia is that BasicBSpline.jl will be so basic that it will be depended on by other packages.

Thank you for reading!

6 Likes