# 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])
``````

## 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)
``````

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)
``````

## 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))
``````

# 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.

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.