BasicBSpline.jl
Basic operations for Bspline functions and related things with julia
Summary
This package provides basic (mathematical) operations for Bspline.
 Bspline basis function
 Some operations for knot vector
 Bspline manifold (includes curve, surface and solid)
 Refinement for Bspline manifold
 Fitting control points for Bspline manifold
Comparison to other julia packages for Bspline
 Interpolations.jl

Currently this package's support is best for Bsplines and also supports irregular grids.
 But seems like no method for Bspline manifold.

 ApproXD.jl
 Its functions are similar to Interpolations.jl.
 Dierckx.jl
 Wrapper for the dierckx Fortran library.
 Only 1d or 2d Bspline manifold are supported.
 5 or less degree of polynomial are supported.
 BasicBSpline.jl (this package)
 Any degree of polynomial are supported.
 Any dimension are supported.
 Fast implementation for lower degree (≤ 5) and dimension (≤ 3).
 Refinement algorithm for Bspline manifold.
 Fitting algorithm by least squares.
Installation
Install this package
pkg> add BasicBSpline
To export graphics, use ExportNURBS.jl.
pkg> add https://github.com/hyrodium/ExportNURBS.jl
Example
Bspline function
using BasicBSpline
using Plots
gr()
k = Knots([0.00,1.50,2.50,5.50,8.00,9.00,9.50,10.0])
P0 = BSplineSpace(0,k) # 0th degree piecewise polynomial space
P1 = BSplineSpace(1,k) # 1st degree piecewise polynomial space
P2 = BSplineSpace(2,k) # 2nd degree piecewise polynomial space
P3 = BSplineSpace(3,k) # 3rd degree piecewise polynomial space
plot(
plot([t>bsplinebasis(P0,i,t) for i in 1:dim(P0)], 0, 10, ylims=(0,1), legend=false),
plot([t>bsplinebasis(P1,i,t) for i in 1:dim(P1)], 0, 10, ylims=(0,1), legend=false),
plot([t>bsplinebasis(P2,i,t) for i in 1:dim(P2)], 0, 10, ylims=(0,1), legend=false),
plot([t>bsplinebasis(P3,i,t) for i in 1:dim(P3)], 0, 10, ylims=(0,1), legend=false),
layout=(2,2),
)
Try interactive graph with Desmos graphing calculator!
Bspline manifold
using BasicBSpline
using ExportNURBS
p = 2 # degree of polynomial
k = Knots(1:8) # knot vector
P = BSplineSpace(p,k) # Bspline space
rand_a = [rand(2) for i in 1:dim(P), j in 1:dim(P)]
a = [[2*i6.5,2*j6.5] for i in 1:dim(P), j in 1:dim(P)] + rand_a # random generated control points
M = BSplineManifold([P,P],a) # Define Bspline manifold
save_png("2dim.png", M) # save image
Refinement
hrefinemnet
k₊=[Knots(3.3,4.2),Knots(3.8,3.2,5.3)] # additional knots
M′ = refinement(M,k₊=k₊) # refinement of Bspline manifold
save_png("2dim_hrefinement.png", M′) # save image
Note that this shape and the last shape are identical.
prefinemnet
p₊=[1,2] # additional degrees
M′ = refinement(M,p₊=p₊) # refinement of Bspline manifold
save_png("2dim_prefinement.png", M′) # save image
Note that this shape and the last shape are identical.
Fitting Bspline manifold
Try on Desmos graphing graphing calculator!
p1 = 2
p2 = 2
k1 = Knots(10:10)+p1*Knots(10,10)
k2 = Knots(10:10)+p2*Knots(10,10)
P1 = FastBSplineSpace(p1, k1)
P2 = FastBSplineSpace(p2, k2)
f(u1, u2) = [2u1 + sin(u1) + cos(u2) + u2 / 2, 3u2 + sin(u2) + sin(u1) / 2 + u1^2 / 6] / 5
a = fittingcontrolpoints(f, P1, P2)
M = BSplineManifold([P1,P2],a)
save_png("fitting.png", M, unitlength=50, up=10, down=10, left=10, right=10)
If the knots span is too coarse, the approximation will be coarse.
p1 = 2
p2 = 2
k1 = Knots(10:5:10)+p1*Knots(10,10)
k2 = Knots(10:5:10)+p2*Knots(10,10)
P1 = FastBSplineSpace(p1, k1)
P2 = FastBSplineSpace(p2, k2)
f(u1, u2) = [2u1 + sin(u1) + cos(u2) + u2 / 2, 3u2 + sin(u2) + sin(u1) / 2 + u1^2 / 6] / 5
a = fittingcontrolpoints(f, P1, P2)
M = BSplineManifold([P1,P2],a)
save_png("fitting_coarse.png", M, unitlength=50, up=10, down=10, left=10, right=10)
Draw smooth vector graphics
p = 3
k = Knots(range(2π,2π,length=8))+p*Knots(2π,2π)
P = FastBSplineSpace(p, k)
f(u) = [u,sin(u)]
a = fittingcontrolpoints(f, P)
M = BSplineManifold([P],a)
save_svg("sine_curve.svg", M, unitlength=50, up=2, down=2, left=8, right=8)
This is useful when you edit graphs (or curves) with your favorite vector graphics editor.
References
If you use BasicBSpline.jl in your work, please consider citing it by
@misc{hyrodium:2020:BasicBSpline,
title={BasicBSpline.jl: Basic operations for Bspline functions and related things with julia},
author={Yuto Horikawa},
year={2020},
howpublished={\url{https://hyrodium.github.io/BasicBSpline.jl/stable/}},
doi={10.5281/zenodo.4356869}
}