Hi all,
I’m pleased to announce my package BasicBSpline.jl v0.9.4 (repo, docs).
Introduction
This package provides basic mathematical operations for Bspline.
 Bspline basis function
 Some operations for knot vector
 Some operations for Bspline space (piecewise polynomial space)
 Bspline manifold (includes curve, surface, and solid)
 Refinement algorithm for Bspline 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 Bspline 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 = (Rr)*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 = [pr*SVector(0,0,1) for p in a5]
a7 = [pr*SVector(0,0,1) for p in R*a0]
a8 = [pr*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 Bspline 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 (1dim Bspline 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 Bspline 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])
 We use

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.
 e.g.
 See BasicBSpline.jl#172 for a comment by @empet.
 Knot vector operations
 Focus on basic Bsplline functionalities
 Bspline 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 Bspline, but it seems no functionality for shape representation.
 Less dependency
 BasicBSpline.jl depends on StaticArrays.jl, so it is hardly lightweight, but we are trying to make it as little dependent as possible. While, on the other hand, BSplineKit.jl depends on more packages.
 High performance
 We are trying to create the fastest Bspline 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.
Thank you for reading!