+ `;
+
+ return filter_html;
+}
+
+/**
+ * Make the result component given a minisearch result data object and the value of the search input as queryString.
+ * To view the result object structure, refer: https://lucaong.github.io/minisearch/modules/_minisearch_.html#searchresult
+ *
+ * @param {object} result
+ * @param {string} querystring
+ * @returns string
+ */
+function make_search_result(result, querystring) {
+ let search_divider = ``;
+ let display_link =
+ result.location.slice(Math.max(0), Math.min(50, result.location.length)) +
+ (result.location.length > 30 ? "..." : ""); // To cut-off the link because it messes with the overflow of the whole div
+
+ if (result.page !== "") {
+ display_link += ` (${result.page})`;
+ }
+
+ let textindex = new RegExp(`\\b${querystring}\\b`, "i").exec(result.text);
+ let text =
+ textindex !== null
+ ? result.text.slice(
+ Math.max(textindex.index - 100, 0),
+ Math.min(
+ textindex.index + querystring.length + 100,
+ result.text.length
+ )
+ )
+ : ""; // cut-off text before and after from the match
+
+ let display_result = text.length
+ ? "..." +
+ text.replace(
+ new RegExp(`\\b${querystring}\\b`, "i"), // For first occurrence
+ '$&'
+ ) +
+ "..."
+ : ""; // highlights the match
+
+ let in_code = false;
+ if (!["page", "section"].includes(result.category.toLowerCase())) {
+ in_code = true;
+ }
+
+ // We encode the full url to escape some special characters which can lead to broken links
+ let result_div = `
+
+
The main contributer Hyrodium is not native English speaker. So, English corrections would be really helpful. Of course, other code improvement are welcomed!
p = 2
+k = KnotVector([-1,-1,-1,1,1,1])
+P = BSplineSpace{p}(k)
+a = [SVector(i,j,2i^2+2j^2-2) for i in -1:1, j in -1:1]
+M = BSplineManifold(a,P,P)
+plot(M)
Currently, BasicBSpline.jl doesn't have APIs for interpolations, but it is not hard to implement some basic interpolation algorithms with this package.
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))
function interpolate_periodic(xs::AbstractVector, fs::AbstractVector, ::Val{p}) where p
+ # Closed B-spline space, any polynomial degrees can be accepted
+ n = length(xs) - 1
+ period = xs[end]-xs[begin]
+ k = KnotVector(vcat(
+ xs[end-p:end-1] .- period,
+ xs,
+ xs[begin+1:begin+p] .+ period
+ ))
+ P = BSplineSpace{p}(k)
+ A = [bsplinebasis(P,j,xs[i]) for i in 1:n, j in 1:n]
+ for i in 1:p-1, j in 1:i
+ A[n+i-p+1,j] += bsplinebasis(P,j+n,xs[i+n-p+1])
+ end
+ b = A \ fs[begin:end-1]
+ # Compute the interpolant function (1-dim B-spline manifold)
+ return BSplineManifold(vcat(b,b[1:p]), P)
+end
+
+# Example inputs
+xs = [1, 2, 3, 4, 6, 7]
+fs = [1.3, 1.5, 2, 2.1, 1.9, 1.3] # fs[1] == fs[end]
+
+f = interpolate_periodic(xs,fs,Val(2))
+
+# Plot
+scatter(xs, fs)
+plot!(t->f(mod(t-1,6)+1),1,14)
+plot!(t->f(t))
Note that the periodic interpolation supports any degree of polynomial.
julia> p = 22 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{p}(k)BSplineSpace{2, Float64, KnotVector{Float64}}(KnotVector([0.0, 1.5, 2.5, 5.5, 8.0, 9.0, 9.5, 10.0])) julia> plot(t->sum(bsplinebasis₊₀(P,i,t) for i in 1:dim(P)), 0, 10, ylims=(0,1.1), label=false)Plot{Plots.PlotlyBackend() n=1}
To satisfy the partition of unity on whole interval $[1,8]$, sometimes more knots will be inserted to the endpoints of the interval.
julia> p = 22 julia> k = KnotVector([0.0, 1.5, 2.5, 5.5, 8.0, 9.0, 9.5, 10.0]) + p * KnotVector([0,10])KnotVector([0.0, 0.0, 0.0, 1.5, 2.5, 5.5, 8.0, 9.0, 9.5, 10.0, 10.0, 10.0]) julia> P = BSplineSpace{p}(k)BSplineSpace{2, Float64, KnotVector{Float64}}(KnotVector([0.0, 0.0, 0.0, 1.5, 2.5, 5.5, 8.0, 9.0, 9.5, 10.0, 10.0, 10.0])) julia> plot(t->sum(bsplinebasis₊₀(P,i,t) for i in 1:dim(P)), 0, 10, ylims=(0,1.1), label=false)Plot{Plots.PlotlyBackend() n=1}
But, the sum $\sum_{i} B_{(i,p,k)}(t)$ is not equal to $1$ at $t=8$. Therefore, to satisfy partition of unity on closed interval $[k_{p+1}, k_{l-p}]$, the definition of first terms of B-spline basis functions are sometimes replaced:
Sometimes, you may need the non-zero values of B-spline basis functions at specific point. The bsplinebasisall function is much more efficient than evaluating B-spline functions one by one with bsplinebasis function.
The next figures illustlates the relation between domain(P), intervalindex(P,t) and bsplinebasisall(P,i,t).
k = KnotVector([0.0, 1.5, 2.5, 5.5, 8.0, 9.0, 9.5, 10.0])
+
+for p in 1:3
+ P = BSplineSpace{p}(k)
+ plot(P, legend=:topleft, label="B-spline basis (p=1)")
+ plot!(t->intervalindex(P,t),0,10, label="Interval index")
+ plot!(t->sum(bsplinebasis(P,i,t) for i in 1:dim(P)),0,10, label="Sum of B-spline basis")
+ scatter!(k.vector,zero(k.vector), label="knot vector")
+ plot!([t->bsplinebasisall(P,1,t)[i] for i in 1:p+1],0,10, color=:black, label="bsplinebasisall (i=1)", ylim=(-1,8-2p))
+end
Let $X_1, \dots, X_n$ be i.i.d. random variables with $X_i \sim U(0,1)$, then the probability density function of $X_1+\cdots+X_n$ can be obtained via BasicBSpline.uniform_bsplinebasis_kernel(Val(n-1),t).
N = 100000
+# polynomial degree 0
+plot1 = histogram([rand() for _ in 1:N], normalize=true, label=false)
+plot!(t->BasicBSpline.uniform_bsplinebasis_kernel(Val(0),t), label=false)
+# polynomial degree 1
+plot2 = histogram([rand()+rand() for _ in 1:N], normalize=true, label=false)
+plot!(t->BasicBSpline.uniform_bsplinebasis_kernel(Val(1),t), label=false)
+# polynomial degree 2
+plot3 = histogram([rand()+rand()+rand() for _ in 1:N], normalize=true, label=false)
+plot!(t->BasicBSpline.uniform_bsplinebasis_kernel(Val(2),t), label=false)
+# polynomial degree 3
+plot4 = histogram([rand()+rand()+rand()+rand() for _ in 1:N], normalize=true, label=false)
+plot!(t->BasicBSpline.uniform_bsplinebasis_kernel(Val(3),t), label=false)
+# plot all
+plot(plot1,plot2,plot3,plot4)
Settings
This document was generated with Documenter.jl version 1.1.2 on Sunday 12 November 2023. Using Julia version 1.9.3.
B-spline manifold is a parametric representation of a shape.
Def. B-spline manifold
For given $d$-dimensional B-spline basis functions $B_{(i^1,p^1,k^1)} \otimes \cdots \otimes B_{(i^d,p^d,k^d)}$ and given points $\bm{a}_{i^1 \dots i^d} \in V$, B-spline manifold is defined by the following equality:
Just like fixing first index such as A[3,:]::Array{1} for matrix A::Array{2}, fixing first argument M(4.3,:) will create BSplineManifold{1} for B-spline surface M::BSplineManifold{2}.
julia> p = 2; julia> k = KnotVector(1:8); julia> P = BSplineSpace{p}(k); julia> a = [SVector(5i+5j+rand(), 5i-5j+rand(), rand()) for i in 1:dim(P), j in 1:dim(P)]; julia> M = BSplineManifold(a,(P,P)); julia> M isa BSplineManifold{2}true julia> M(:,:) isa BSplineManifold{2}true julia> M(4.3,:) isa BSplineManifold{1} # Fix first argumenttrue
This space $\mathcal{P}[p]$ is a $(p+1)$-dimensional linear space.
Note that $\{t\mapsto t^i\}_{0 \le i \le p}$ is a basis of $\mathcal{P}[p]$, and also the set of Bernstein polynomial$\{B_{(i,p)}\}_i$ is a basis of $\mathcal{P}[p]$.
The following functions such as fittingcontolpoints were provided from BasicBSpline.jl before v0.9.0. From BasicBSpline v0.9.0, these functions are moved to BasicBSplineFitting.
julia> plot(
+ plot([t->bsplinebasis₊₀(P1,i,t) for i in 1:dim(P1)], 1, 9, ylims=(0,1), legend=false),
+ plot([t->sum(A12[i,j]*bsplinebasis₊₀(P2,j,t) for j in 1:dim(P2)) for i in 1:dim(P1)], 1, 9, ylims=(0,1), legend=false),
+ plot([t->sum(A13[i,j]*bsplinebasis₊₀(P3,j,t) for j in 1:dim(P3)) for i in 1:dim(P1)], 1, 9, ylims=(0,1), legend=false),
+ layout=(3,1),
+ link=:x
+ )Plot{Plots.PlotlyBackend() n=6}
Note that the operator +(::KnotVector, ::KnotVector) is commutative. This is why we choose the $+$ sign. We also introduce product operator$\cdot$ for knot vector.
For given knot vector $k$, the following function $\mathfrak{n}_k:\mathbb{R}\to\mathbb{Z}$ represents the number of knots that duplicate the knot vector $k$.
\[\mathfrak{n}_k(t) = \#\{i \mid k_i=t \}\]
For example, if $k=(1,2,2,3)$, then $\mathfrak{n}_k(0.3)=0$, $\mathfrak{n}_k(1)=1$, $\mathfrak{n}_k(2)=2$.
Rational B-spline manifold is a parametric representation of a shape.
Def. Rational B-spline manifold
For given $d$-dimensional B-spline basis functions $B_{(i^1,p^1,k^1)} \otimes \cdots \otimes B_{(i^d,p^d,k^d)}$, given points $\bm{a}_{i^1 \dots i^d} \in V$ and real numbers $w_{i^1 \dots i^d} > 0$, rational B-spline manifold is defined by the following equality:
p = 2 # degree of polynomial
+k = KnotVector(1:8) # knot vector
+P = BSplineSpace{p}(k) # B-spline space
+rand_a = [SVector(rand(), rand()) for i in 1:dim(P), j in 1:dim(P)]
+a = [SVector(2*i-6.5, 2*j-6.5) for i in 1:dim(P), j in 1:dim(P)] + rand_a # random
+M = BSplineManifold(a,(P,P)) # Define B-spline manifold
B-spline is a mathematical object, and it has a lot of application. (e.g. Geometric representation: NURBS, Interpolation, Numerical analysis: IGA)
In this page, we'll explain the mathematical definitions and properties of B-spline with Julia code. Before running the code in the following section, you need to import packages:
BasicBSpline.jl has a dependency on RecipesBase.jl. This means, users can easily visalize instances defined in BasicBSpline. In this section, we will provide some plottig examples.
This document was generated with Documenter.jl version 1.1.2 on Sunday 12 November 2023. Using Julia version 1.9.3.
diff --git a/previews/PR343/search_index.js b/previews/PR343/search_index.js
new file mode 100644
index 000000000..9f4959dfb
--- /dev/null
+++ b/previews/PR343/search_index.js
@@ -0,0 +1,3 @@
+var documenterSearchIndex = {"docs":
+[{"location":"math-fitting/#Fitting-with-B-spline-manifold","page":"Fitting","title":"Fitting with B-spline manifold","text":"","category":"section"},{"location":"math-fitting/","page":"Fitting","title":"Fitting","text":"The following functions such as fittingcontolpoints were provided from BasicBSpline.jl before v0.9.0. From BasicBSpline v0.9.0, these functions are moved to BasicBSplineFitting.","category":"page"},{"location":"math-fitting/","page":"Fitting","title":"Fitting","text":"using BasicBSpline\nusing BasicBSplineFitting\nusing BasicBSplineExporter\nusing StaticArrays\nusing Plots; plotly()","category":"page"},{"location":"math-fitting/","page":"Fitting","title":"Fitting","text":"Fitting with least squares method.","category":"page"},{"location":"math-fitting/","page":"Fitting","title":"Fitting","text":"fittingcontrolpoints","category":"page"},{"location":"math-fitting/#BasicBSplineFitting.fittingcontrolpoints","page":"Fitting","title":"BasicBSplineFitting.fittingcontrolpoints","text":"Fitting controlpoints with least squares method.\n\nfittingcontrolpoints(func, Ps::Tuple)\n\nThis function will calculate bma_i to minimize the following integral.\n\nint_I leftf(t)-sum_i B_(ipk)(t) bma_iright^2 dt\n\nSimilarly, for the two-dimensional case, minimize the following integral.\n\nint_I^1 times I^2 leftf(t^1 t^2)-sum_ij B_(ip^1k^1)(t^1)B_(jp^2k^2)(t^2) bma_ijright^2 dt^1dt^2\n\nCurrently, this function supports up to three dimensions.\n\nExamples\n\njulia> f(t) = SVector(cos(t),sin(t),t);\n\njulia> P = BSplineSpace{3}(KnotVector(range(0,2π,30)) + 3*KnotVector([0,2π]));\n\njulia> a = fittingcontrolpoints(f, P);\n\njulia> M = BSplineManifold(a, P);\n\njulia> norm(M(1) - f(1)) < 1e-5\ntrue\n\n\n\n\n\n","category":"function"},{"location":"math-fitting/","page":"Fitting","title":"Fitting","text":"p1 = 2\np2 = 2\nk1 = KnotVector(-10:10)+p1*KnotVector([-10,10])\nk2 = KnotVector(-10:10)+p2*KnotVector([-10,10])\nP1 = BSplineSpace{p1}(k1)\nP2 = BSplineSpace{p2}(k2)\n\nf(u1, u2) = SVector(2u1 + sin(u1) + cos(u2) + u2 / 2, 3u2 + sin(u2) + sin(u1) / 2 + u1^2 / 6) / 5\n\na = fittingcontrolpoints(f, (P1, P2))\nM = BSplineManifold(a, (P1, P2))\nsave_png(\"fitting.png\", M, unitlength=50, xlims=(-10,10), ylims=(-10,10))","category":"page"},{"location":"math-fitting/","page":"Fitting","title":"Fitting","text":"(Image: )","category":"page"},{"location":"math-fitting/","page":"Fitting","title":"Fitting","text":"Try on Desmos graphing graphing calculator! (Image: )","category":"page"},{"location":"math-refinement/#Refinement","page":"Refinement","title":"Refinement","text":"","category":"section"},{"location":"math-refinement/","page":"Refinement","title":"Refinement","text":"using BasicBSpline\nusing BasicBSplineExporter\nusing StaticArrays\nusing Plots; plotly()","category":"page"},{"location":"math-refinement/#Documentation","page":"Refinement","title":"Documentation","text":"","category":"section"},{"location":"math-refinement/","page":"Refinement","title":"Refinement","text":"refinement","category":"page"},{"location":"math-refinement/#BasicBSpline.refinement","page":"Refinement","title":"BasicBSpline.refinement","text":"Refinement of B-spline manifold with given B-spline spaces.\n\n\n\n\n\n","category":"function"},{"location":"math-refinement/#Example","page":"Refinement","title":"Example","text":"","category":"section"},{"location":"math-refinement/#Define-original-manifold","page":"Refinement","title":"Define original manifold","text":"","category":"section"},{"location":"math-refinement/","page":"Refinement","title":"Refinement","text":"p = 2 # degree of polynomial\nk = KnotVector(1:8) # knot vector\nP = BSplineSpace{p}(k) # B-spline space\nrand_a = [SVector(rand(), rand()) for i in 1:dim(P), j in 1:dim(P)]\na = [SVector(2*i-6.5, 2*j-6.5) for i in 1:dim(P), j in 1:dim(P)] + rand_a # random \nM = BSplineManifold(a,(P,P)) # Define B-spline manifold\nnothing # hide","category":"page"},{"location":"math-refinement/#h-refinement","page":"Refinement","title":"h-refinement","text":"","category":"section"},{"location":"math-refinement/","page":"Refinement","title":"Refinement","text":"Insert additional knots to knot vector.","category":"page"},{"location":"math-refinement/","page":"Refinement","title":"Refinement","text":"k₊ = (KnotVector([3.3,4.2]),KnotVector([3.8,3.2,5.3])) # additional knot vectors\nM_h = refinement(M, k₊) # refinement of B-spline manifold\nsave_png(\"2dim_h-refinement.png\", M_h) # save image","category":"page"},{"location":"math-refinement/","page":"Refinement","title":"Refinement","text":"(Image: )","category":"page"},{"location":"math-refinement/","page":"Refinement","title":"Refinement","text":"Note that this shape and the last shape are equivalent.","category":"page"},{"location":"math-refinement/#p-refinement","page":"Refinement","title":"p-refinement","text":"","category":"section"},{"location":"math-refinement/","page":"Refinement","title":"Refinement","text":"Increase the polynomial degree of B-spline manifold.","category":"page"},{"location":"math-refinement/","page":"Refinement","title":"Refinement","text":"p₊ = (Val(1), Val(2)) # additional degrees\nM_p = refinement(M, p₊) # refinement of B-spline manifold\nsave_png(\"2dim_p-refinement.png\", M_p) # save image","category":"page"},{"location":"math-refinement/","page":"Refinement","title":"Refinement","text":"(Image: )","category":"page"},{"location":"math-refinement/","page":"Refinement","title":"Refinement","text":"Note that this shape and the last shape are equivalent.","category":"page"},{"location":"interpolations/#Interpolations","page":"Interpolations","title":"Interpolations","text":"","category":"section"},{"location":"interpolations/","page":"Interpolations","title":"Interpolations","text":"Currently, BasicBSpline.jl doesn't have APIs for interpolations, but it is not hard to implement some basic interpolation algorithms with this package.","category":"page"},{"location":"interpolations/","page":"Interpolations","title":"Interpolations","text":"using BasicBSpline\nusing IntervalSets\nusing Random; Random.seed!(42)\nusing Plots; plotly()","category":"page"},{"location":"interpolations/#Interpolation-with-cubic-B-spline","page":"Interpolations","title":"Interpolation with cubic B-spline","text":"","category":"section"},{"location":"interpolations/","page":"Interpolations","title":"Interpolations","text":"function interpolate(xs::AbstractVector, fs::AbstractVector{T}) where T\n # Cubic open B-spline space\n p = 3\n k = KnotVector(xs) + KnotVector([xs[1],xs[end]]) * p\n P = BSplineSpace{p}(k)\n\n # dimensions\n m = length(xs)\n n = dim(P)\n\n # The interpolant function has a f''=0 property at bounds.\n ddP = BSplineDerivativeSpace{2}(P)\n dda = [bsplinebasis(ddP,j,xs[1]) for j in 1:n]\n ddb = [bsplinebasis(ddP,j,xs[m]) for j in 1:n]\n\n # Compute the interpolant function (1-dim B-spline manifold)\n M = [bsplinebasis(P,j,xs[i]) for i in 1:m, j in 1:n]\n M = vcat(dda', M, ddb')\n y = vcat(zero(T), fs, zero(T))\n return BSplineManifold(M\\y, P)\nend\n\n# Example inputs\nxs = [1, 2, 3, 4, 6, 7]\nfs = [1.3, 1.5, 2, 2.1, 1.9, 1.3]\nf = interpolate(xs,fs)\n\n# Plot\nscatter(xs, fs)\nplot!(t->f(t))\nsavefig(\"interpolation_cubic.html\") # hide\nnothing # hide","category":"page"},{"location":"interpolations/","page":"Interpolations","title":"Interpolations","text":"","category":"page"},{"location":"interpolations/#Interpolation-with-linear-B-spline","page":"Interpolations","title":"Interpolation with linear B-spline","text":"","category":"section"},{"location":"interpolations/","page":"Interpolations","title":"Interpolations","text":"function interpolate_linear(xs::AbstractVector, fs::AbstractVector{T}) where T\n # Linear open B-spline space\n p = 1\n k = KnotVector(xs) + KnotVector([xs[1],xs[end]])\n P = BSplineSpace{p}(k)\n\n # dimensions\n m = length(xs)\n n = dim(P)\n\n # Compute the interpolant function (1-dim B-spline manifold)\n return BSplineManifold(fs, P)\nend\n\n# Example inputs\nxs = [1, 2, 3, 4, 6, 7]\nfs = [1.3, 1.5, 2, 2.1, 1.9, 1.3]\n\nf = interpolate_linear(xs,fs)\n\n# Plot\nscatter(xs, fs)\nplot!(t->f(t))\nsavefig(\"interpolation_linear.html\") # hide\nnothing # hide","category":"page"},{"location":"interpolations/","page":"Interpolations","title":"Interpolations","text":"","category":"page"},{"location":"interpolations/#Interpolation-with-periodic-B-spline","page":"Interpolations","title":"Interpolation with periodic B-spline","text":"","category":"section"},{"location":"interpolations/","page":"Interpolations","title":"Interpolations","text":"function interpolate_periodic(xs::AbstractVector, fs::AbstractVector, ::Val{p}) where p\n # Closed B-spline space, any polynomial degrees can be accepted\n n = length(xs) - 1\n period = xs[end]-xs[begin]\n k = KnotVector(vcat(\n xs[end-p:end-1] .- period,\n xs,\n xs[begin+1:begin+p] .+ period\n ))\n P = BSplineSpace{p}(k)\n A = [bsplinebasis(P,j,xs[i]) for i in 1:n, j in 1:n]\n for i in 1:p-1, j in 1:i\n A[n+i-p+1,j] += bsplinebasis(P,j+n,xs[i+n-p+1])\n end\n b = A \\ fs[begin:end-1]\n # Compute the interpolant function (1-dim B-spline manifold)\n return BSplineManifold(vcat(b,b[1:p]), P)\nend\n\n# Example inputs\nxs = [1, 2, 3, 4, 6, 7]\nfs = [1.3, 1.5, 2, 2.1, 1.9, 1.3] # fs[1] == fs[end]\n\nf = interpolate_periodic(xs,fs,Val(2))\n\n# Plot\nscatter(xs, fs)\nplot!(t->f(mod(t-1,6)+1),1,14)\nplot!(t->f(t))\nsavefig(\"interpolation_periodic.html\") # hide\nnothing # hide","category":"page"},{"location":"interpolations/","page":"Interpolations","title":"Interpolations","text":"","category":"page"},{"location":"interpolations/","page":"Interpolations","title":"Interpolations","text":"Note that the periodic interpolation supports any degree of polynomial.","category":"page"},{"location":"interpolations/","page":"Interpolations","title":"Interpolations","text":"xs = 2π*rand(10)\nsort!(push!(xs, 0, 2π))\nfs = sin.(xs)\nf1 = interpolate_periodic(xs,fs,Val(1))\nf2 = interpolate_periodic(xs,fs,Val(2))\nf3 = interpolate_periodic(xs,fs,Val(3))\nf4 = interpolate_periodic(xs,fs,Val(4))\nf5 = interpolate_periodic(xs,fs,Val(5))\nscatter(xs, fs, label=\"sampling points\")\nplot!(sin, label=\"sine curve\", color=:black)\nplot!(t->f1(t), label=\"polynomial degree 1\")\nplot!(t->f2(t), label=\"polynomial degree 2\")\nplot!(t->f3(t), label=\"polynomial degree 3\")\nplot!(t->f4(t), label=\"polynomial degree 4\")\nplot!(t->f5(t), label=\"polynomial degree 5\")\nsavefig(\"interpolation_periodic_sin.html\") # hide\nnothing # hide","category":"page"},{"location":"interpolations/","page":"Interpolations","title":"Interpolations","text":"","category":"page"},{"location":"contributing/#Contributing","page":"Contributing","title":"Contributing","text":"","category":"section"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"The main contributer Hyrodium is not native English speaker. So, English corrections would be really helpful. Of course, other code improvement are welcomed!","category":"page"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"Feel free to open issues and pull requests!","category":"page"},{"location":"math-bsplinebasis/#B-spline-basis-function","page":"B-spline basis function","title":"B-spline basis function","text":"","category":"section"},{"location":"math-bsplinebasis/","page":"B-spline basis function","title":"B-spline basis function","text":"using BasicBSpline\nusing BasicBSplineExporter\nusing StaticArrays\nusing Plots; plotly()","category":"page"},{"location":"math-bsplinebasis/","page":"B-spline basis function","title":"B-spline basis function","text":"using BasicBSpline\nusing BasicBSplineExporter\nusing StaticArrays\nusing Plots; plotly()","category":"page"},{"location":"math-bsplinebasis/#Basic-properties-of-B-spline-basis-function","page":"B-spline basis function","title":"Basic properties of B-spline basis function","text":"","category":"section"},{"location":"math-bsplinebasis/","page":"B-spline basis function","title":"B-spline basis function","text":"tip: Def. B-spline space\nB-spline basis function is defined by Cox–de Boor recursion formula.beginaligned\nB_(ipk)(t)\n=\nfract-k_ik_i+p-k_iB_(ip-1k)(t)\n+frack_i+p+1-tk_i+p+1-k_i+1B_(i+1p-1k)(t) \nB_(i0k)(t)\n=\nbegincases\n 1quad (k_ile t k_i+1)\n 0quad (textotherwise)\nendcases\nendalignedIf the denominator is zero, then the term is assumed to be zero.","category":"page"},{"location":"math-bsplinebasis/","page":"B-spline basis function","title":"B-spline basis function","text":"The next figure shows the plot of B-spline basis functions. You can manipulate these plots on desmos graphing calculator!","category":"page"},{"location":"math-bsplinebasis/","page":"B-spline basis function","title":"B-spline basis function","text":"(Image: )","category":"page"},{"location":"math-bsplinebasis/","page":"B-spline basis function","title":"B-spline basis function","text":"info: Thm. Basis of B-spline space\nThe set of functions B_(ipk)_i is a basis of B-spline space mathcalPpk.","category":"page"},{"location":"math-bsplinebasis/","page":"B-spline basis function","title":"B-spline basis function","text":"p = 2\nk = KnotVector([0.0, 1.5, 2.5, 5.5, 8.0, 9.0, 9.5, 10.0])\nP = BSplineSpace{p}(k)\nplot([t->bsplinebasis₊₀(P,i,t) for i in 1:dim(P)], 0, 10, ylims=(0,1), label=false)\nsavefig(\"bsplinebasisplot.html\") # hide\nnothing # hide","category":"page"},{"location":"math-bsplinebasis/","page":"B-spline basis function","title":"B-spline basis function","text":"","category":"page"},{"location":"math-bsplinebasis/","page":"B-spline basis function","title":"B-spline basis function","text":"You can choose the first terms in different ways.","category":"page"},{"location":"math-bsplinebasis/","page":"B-spline basis function","title":"B-spline basis function","text":"beginaligned\nB_(i0k)(t)\n=\nbegincases\n 1quad (k_i t le k_i+1) \n 0quad (textotherwise)\nendcases\nendaligned","category":"page"},{"location":"math-bsplinebasis/","page":"B-spline basis function","title":"B-spline basis function","text":"p = 2\nk = KnotVector([0.0, 1.5, 2.5, 5.5, 8.0, 9.0, 9.5, 10.0])\nP = BSplineSpace{p}(k)\nplot([t->bsplinebasis₋₀(P,i,t) for i in 1:dim(P)], 0, 10, ylims=(0,1), label=false)\nsavefig(\"bsplinebasisplot2.html\") # hide\nnothing # hide","category":"page"},{"location":"math-bsplinebasis/","page":"B-spline basis function","title":"B-spline basis function","text":"","category":"page"},{"location":"math-bsplinebasis/","page":"B-spline basis function","title":"B-spline basis function","text":"In these cases, each B-spline basis function B_(i2k) is coninuous, so bsplinebasis₊₀ and bsplinebasis₋₀ are equal.","category":"page"},{"location":"math-bsplinebasis/#Support-of-B-spline-basis-function","page":"B-spline basis function","title":"Support of B-spline basis function","text":"","category":"section"},{"location":"math-bsplinebasis/","page":"B-spline basis function","title":"B-spline basis function","text":"info: Thm. Support of B-spline basis function\nIf a B-spline spacemathcalPpk is non-degenerate, the support of its basis function is calculated as follows:operatornamesupp(B_(ipk))=k_ik_i+p+1","category":"page"},{"location":"math-bsplinebasis/","page":"B-spline basis function","title":"B-spline basis function","text":"[TODO: fig]","category":"page"},{"location":"math-bsplinebasis/","page":"B-spline basis function","title":"B-spline basis function","text":"bsplinesupport","category":"page"},{"location":"math-bsplinebasis/#BasicBSpline.bsplinesupport","page":"B-spline basis function","title":"BasicBSpline.bsplinesupport","text":"Return the support of i-th B-spline basis function.\n\noperatornamesupp(B_(ipk))=k_ik_i+p+1\n\nExamples\n\njulia> k = KnotVector([0.0, 1.5, 2.5, 5.5, 8.0, 9.0, 9.5, 10.0])\nKnotVector([0.0, 1.5, 2.5, 5.5, 8.0, 9.0, 9.5, 10.0])\n\njulia> P = BSplineSpace{2}(k)\nBSplineSpace{2, Float64, KnotVector{Float64}}(KnotVector([0.0, 1.5, 2.5, 5.5, 8.0, 9.0, 9.5, 10.0]))\n\njulia> bsplinesupport(P,1)\n0.0 .. 5.5\n\njulia> bsplinesupport(P,2)\n1.5 .. 8.0\n\n\n\n\n\n","category":"function"},{"location":"math-bsplinebasis/#Partition-of-unity","page":"B-spline basis function","title":"Partition of unity","text":"","category":"section"},{"location":"math-bsplinebasis/","page":"B-spline basis function","title":"B-spline basis function","text":"info: Thm. Partition of unity\nLet B_(ipk) be a B-spline basis function, then the following equation is satisfied.beginaligned\nsum_iB_(ipk)(t) = 1 (k_p+1 le t k_l-p) \n0 le B_(ipk)(t) le 1\nendaligned","category":"page"},{"location":"math-bsplinebasis/","page":"B-spline basis function","title":"B-spline basis function","text":"p = 2\nk = KnotVector([0.0, 1.5, 2.5, 5.5, 8.0, 9.0, 9.5, 10.0])\nP = BSplineSpace{p}(k)\nplot(t->sum(bsplinebasis₊₀(P,i,t) for i in 1:dim(P)), 0, 10, ylims=(0,1.1), label=false)\nsavefig(\"sumofbsplineplot.html\") # hide\nnothing # hide","category":"page"},{"location":"math-bsplinebasis/","page":"B-spline basis function","title":"B-spline basis function","text":"","category":"page"},{"location":"math-bsplinebasis/","page":"B-spline basis function","title":"B-spline basis function","text":"To satisfy the partition of unity on whole interval 18, sometimes more knots will be inserted to the endpoints of the interval.","category":"page"},{"location":"math-bsplinebasis/","page":"B-spline basis function","title":"B-spline basis function","text":"p = 2\nk = KnotVector([0.0, 1.5, 2.5, 5.5, 8.0, 9.0, 9.5, 10.0]) + p * KnotVector([0,10])\nP = BSplineSpace{p}(k)\nplot(t->sum(bsplinebasis₊₀(P,i,t) for i in 1:dim(P)), 0, 10, ylims=(0,1.1), label=false)\nsavefig(\"sumofbsplineplot2.html\") # hide\nnothing # hide","category":"page"},{"location":"math-bsplinebasis/","page":"B-spline basis function","title":"B-spline basis function","text":"","category":"page"},{"location":"math-bsplinebasis/","page":"B-spline basis function","title":"B-spline basis function","text":"But, the sum sum_i B_(ipk)(t) is not equal to 1 at t=8. Therefore, to satisfy partition of unity on closed interval k_p+1 k_l-p, the definition of first terms of B-spline basis functions are sometimes replaced:","category":"page"},{"location":"math-bsplinebasis/","page":"B-spline basis function","title":"B-spline basis function","text":"beginaligned\nB_(i0k)(t)\n=\nbegincases\n 1quad (k_i le tk_i+1)\n 1quad (k_i t = k_i+1=k_l)\n 0quad (textotherwise)\nendcases\nendaligned","category":"page"},{"location":"math-bsplinebasis/","page":"B-spline basis function","title":"B-spline basis function","text":"p = 2\nk = KnotVector([0.0, 1.5, 2.5, 5.5, 8.0, 9.0, 9.5, 10.0]) + p * KnotVector([0,10])\nP = BSplineSpace{p}(k)\nplot(t->sum(bsplinebasis(P,i,t) for i in 1:dim(P)), 0, 10, ylims=(0,1.1), label=false)\nsavefig(\"sumofbsplineplot3.html\") # hide\nnothing # hide","category":"page"},{"location":"math-bsplinebasis/","page":"B-spline basis function","title":"B-spline basis function","text":"","category":"page"},{"location":"math-bsplinebasis/","page":"B-spline basis function","title":"B-spline basis function","text":"bsplinebasis₊₀","category":"page"},{"location":"math-bsplinebasis/#BasicBSpline.bsplinebasis₊₀","page":"B-spline basis function","title":"BasicBSpline.bsplinebasis₊₀","text":"i-th B-spline basis function. Right-sided limit version.\n\nbeginaligned\nB_(ipk)(t)\n=\nfract-k_ik_i+p-k_iB_(ip-1k)(t)\n+frack_i+p+1-tk_i+p+1-k_i+1B_(i+1p-1k)(t) \nB_(i0k)(t)\n=\nbegincases\n 1quad (k_ile t k_i+1)\n 0quad (textotherwise)\nendcases\nendaligned\n\nExamples\n\njulia> P = BSplineSpace{0}(KnotVector(1:6))\nBSplineSpace{0, Int64, KnotVector{Int64}}(KnotVector([1, 2, 3, 4, 5, 6]))\n\njulia> bsplinebasis₊₀.(P,1:5,(1:6)')\n5×6 Matrix{Float64}:\n 1.0 0.0 0.0 0.0 0.0 0.0\n 0.0 1.0 0.0 0.0 0.0 0.0\n 0.0 0.0 1.0 0.0 0.0 0.0\n 0.0 0.0 0.0 1.0 0.0 0.0\n 0.0 0.0 0.0 0.0 1.0 0.0\n\n\n\n\n\n","category":"function"},{"location":"math-bsplinebasis/","page":"B-spline basis function","title":"B-spline basis function","text":"bsplinebasis₋₀","category":"page"},{"location":"math-bsplinebasis/#BasicBSpline.bsplinebasis₋₀","page":"B-spline basis function","title":"BasicBSpline.bsplinebasis₋₀","text":"i-th B-spline basis function. Left-sided limit version.\n\nbeginaligned\nB_(ipk)(t)\n=\nfract-k_ik_i+p-k_iB_(ip-1k)(t)\n+frack_i+p+1-tk_i+p+1-k_i+1B_(i+1p-1k)(t) \nB_(i0k)(t)\n=\nbegincases\n 1quad (k_i tle k_i+1)\n 0quad (textotherwise)\nendcases\nendaligned\n\nExamples\n\njulia> P = BSplineSpace{0}(KnotVector(1:6))\nBSplineSpace{0, Int64, KnotVector{Int64}}(KnotVector([1, 2, 3, 4, 5, 6]))\n\njulia> bsplinebasis₋₀.(P,1:5,(1:6)')\n5×6 Matrix{Float64}:\n 0.0 1.0 0.0 0.0 0.0 0.0\n 0.0 0.0 1.0 0.0 0.0 0.0\n 0.0 0.0 0.0 1.0 0.0 0.0\n 0.0 0.0 0.0 0.0 1.0 0.0\n 0.0 0.0 0.0 0.0 0.0 1.0\n\n\n\n\n\n","category":"function"},{"location":"math-bsplinebasis/","page":"B-spline basis function","title":"B-spline basis function","text":"bsplinebasis","category":"page"},{"location":"math-bsplinebasis/#BasicBSpline.bsplinebasis","page":"B-spline basis function","title":"BasicBSpline.bsplinebasis","text":"i-th B-spline basis function. Modified version.\n\nbeginaligned\nB_(ipk)(t)\n=\nfract-k_ik_i+p-k_iB_(ip-1k)(t)\n+frack_i+p+1-tk_i+p+1-k_i+1B_(i+1p-1k)(t) \nB_(i0k)(t)\n=\nbegincases\n 1quad (k_i le t k_i+1) \n 1quad (k_i t = k_i+1=k_l) \n 0quad (textotherwise)\nendcases\nendaligned\n\nExamples\n\njulia> P = BSplineSpace{0}(KnotVector(1:6))\nBSplineSpace{0, Int64, KnotVector{Int64}}(KnotVector([1, 2, 3, 4, 5, 6]))\n\njulia> bsplinebasis.(P,1:5,(1:6)')\n5×6 Matrix{Float64}:\n 1.0 0.0 0.0 0.0 0.0 0.0\n 0.0 1.0 0.0 0.0 0.0 0.0\n 0.0 0.0 1.0 0.0 0.0 0.0\n 0.0 0.0 0.0 1.0 0.0 0.0\n 0.0 0.0 0.0 0.0 1.0 1.0\n\n\n\n\n\n","category":"function"},{"location":"math-bsplinebasis/","page":"B-spline basis function","title":"B-spline basis function","text":"BasicBSpline.bsplinebasis₋₀I","category":"page"},{"location":"math-bsplinebasis/#BasicBSpline.bsplinebasis₋₀I","page":"B-spline basis function","title":"BasicBSpline.bsplinebasis₋₀I","text":"i-th B-spline basis function. Modified version (2).\n\nbeginaligned\nB_(ipk)(t)\n=\nfract-k_ik_i+p-k_iB_(ip-1k)(t)\n+frack_i+p+1-tk_i+p+1-k_i+1B_(i+1p-1k)(t) \nB_(i0k)(t)\n=\nbegincases\n 1quad (k_1+p le k_i t le k_i+1) \n 1quad (t = k_1+p = k_i k_i+1) \n 1quad (k_i le t k_i+1 le k_1+p) \n 0quad (textotherwise)\nendcases\nendaligned\n\nExamples\n\njulia> P = BSplineSpace{0}(KnotVector(1:6))\nBSplineSpace{0, Int64, KnotVector{Int64}}(KnotVector([1, 2, 3, 4, 5, 6]))\n\njulia> BasicBSpline.bsplinebasis₋₀I.(P,1:5,(1:6)')\n5×6 Matrix{Float64}:\n 1.0 1.0 0.0 0.0 0.0 0.0\n 0.0 0.0 1.0 0.0 0.0 0.0\n 0.0 0.0 0.0 1.0 0.0 0.0\n 0.0 0.0 0.0 0.0 1.0 0.0\n 0.0 0.0 0.0 0.0 0.0 1.0\n\n\n\n\n\n","category":"function"},{"location":"math-bsplinebasis/#B-spline-basis-functions-at-specific-point","page":"B-spline basis function","title":"B-spline basis functions at specific point","text":"","category":"section"},{"location":"math-bsplinebasis/","page":"B-spline basis function","title":"B-spline basis function","text":"Sometimes, you may need the non-zero values of B-spline basis functions at specific point. The bsplinebasisall function is much more efficient than evaluating B-spline functions one by one with bsplinebasis function.","category":"page"},{"location":"math-bsplinebasis/","page":"B-spline basis function","title":"B-spline basis function","text":"using BenchmarkTools, BasicBSpline\nP = BSplineSpace{2}(KnotVector([0.0, 1.5, 2.5, 5.5, 8.0, 9.0, 9.5, 10.0]))\nt = 6.3\n(bsplinebasis(P, 2, t), bsplinebasis(P, 3, t), bsplinebasis(P, 4, t))\nbsplinebasisall(P, 2, t)\n@benchmark (bsplinebasis($P, 2, $t), bsplinebasis($P, 3, $t), bsplinebasis($P, 4, $t))\n@benchmark bsplinebasisall($P, 2, $t)","category":"page"},{"location":"math-bsplinebasis/","page":"B-spline basis function","title":"B-spline basis function","text":"intervalindex","category":"page"},{"location":"math-bsplinebasis/#BasicBSpline.intervalindex","page":"B-spline basis function","title":"BasicBSpline.intervalindex","text":"Return an index of a interval in the domain of B-spline space\n\nExamples\n\njulia> k = KnotVector([0.0, 1.5, 2.5, 5.5, 8.0, 9.0, 9.5, 10.0]);\n\n\njulia> P = BSplineSpace{2}(k);\n\n\njulia> domain(P)\n2.5 .. 9.0\n\njulia> intervalindex(P,2.6)\n1\n\njulia> intervalindex(P,5.6)\n2\n\njulia> intervalindex(P,8.5)\n3\n\njulia> intervalindex(P,9.5)\n3\n\n\n\n\n\n","category":"function"},{"location":"math-bsplinebasis/","page":"B-spline basis function","title":"B-spline basis function","text":"bsplinebasisall","category":"page"},{"location":"math-bsplinebasis/#BasicBSpline.bsplinebasisall","page":"B-spline basis function","title":"BasicBSpline.bsplinebasisall","text":"B-spline basis functions at point t on i-th interval.\n\nExamples\n\njulia> k = KnotVector([0.0, 1.5, 2.5, 5.5, 8.0, 9.0, 9.5, 10.0])\nKnotVector([0.0, 1.5, 2.5, 5.5, 8.0, 9.0, 9.5, 10.0])\n\njulia> p = 2\n2\n\njulia> P = BSplineSpace{p}(k)\nBSplineSpace{2, Float64, KnotVector{Float64}}(KnotVector([0.0, 1.5, 2.5, 5.5, 8.0, 9.0, 9.5, 10.0]))\n\njulia> t = 5.7\n5.7\n\njulia> i = intervalindex(P,t)\n2\n\njulia> bsplinebasisall(P,i,t)\n3-element SVector{3, Float64} with indices SOneTo(3):\n 0.3847272727272727\n 0.6107012987012989\n 0.00457142857142858\n\njulia> bsplinebasis.(P,i:i+p,t)\n3-element Vector{Float64}:\n 0.38472727272727264\n 0.6107012987012989\n 0.00457142857142858\n\n\n\n\n\n","category":"function"},{"location":"math-bsplinebasis/","page":"B-spline basis function","title":"B-spline basis function","text":"The next figures illustlates the relation between domain(P), intervalindex(P,t) and bsplinebasisall(P,i,t).","category":"page"},{"location":"math-bsplinebasis/","page":"B-spline basis function","title":"B-spline basis function","text":"k = KnotVector([0.0, 1.5, 2.5, 5.5, 8.0, 9.0, 9.5, 10.0])\n\nfor p in 1:3\n P = BSplineSpace{p}(k)\n plot(P, legend=:topleft, label=\"B-spline basis (p=1)\")\n plot!(t->intervalindex(P,t),0,10, label=\"Interval index\")\n plot!(t->sum(bsplinebasis(P,i,t) for i in 1:dim(P)),0,10, label=\"Sum of B-spline basis\")\n scatter!(k.vector,zero(k.vector), label=\"knot vector\")\n plot!([t->bsplinebasisall(P,1,t)[i] for i in 1:p+1],0,10, color=:black, label=\"bsplinebasisall (i=1)\", ylim=(-1,8-2p))\n savefig(\"bsplinebasisall-$(p).html\") # hide\n nothing # hide\nend","category":"page"},{"location":"math-bsplinebasis/","page":"B-spline basis function","title":"B-spline basis function","text":"","category":"page"},{"location":"math-bsplinebasis/","page":"B-spline basis function","title":"B-spline basis function","text":"","category":"page"},{"location":"math-bsplinebasis/","page":"B-spline basis function","title":"B-spline basis function","text":"","category":"page"},{"location":"math-bsplinebasis/#Uniform-B-spline-basis-and-uniform-distribution","page":"B-spline basis function","title":"Uniform B-spline basis and uniform distribution","text":"","category":"section"},{"location":"math-bsplinebasis/","page":"B-spline basis function","title":"B-spline basis function","text":"Let X_1 dots X_n be i.i.d. random variables with X_i sim U(01), then the probability density function of X_1+cdots+X_n can be obtained via BasicBSpline.uniform_bsplinebasis_kernel(Val(n-1),t).","category":"page"},{"location":"math-bsplinebasis/","page":"B-spline basis function","title":"B-spline basis function","text":"N = 100000\n# polynomial degree 0\nplot1 = histogram([rand() for _ in 1:N], normalize=true, label=false)\nplot!(t->BasicBSpline.uniform_bsplinebasis_kernel(Val(0),t), label=false)\n# polynomial degree 1\nplot2 = histogram([rand()+rand() for _ in 1:N], normalize=true, label=false)\nplot!(t->BasicBSpline.uniform_bsplinebasis_kernel(Val(1),t), label=false)\n# polynomial degree 2\nplot3 = histogram([rand()+rand()+rand() for _ in 1:N], normalize=true, label=false)\nplot!(t->BasicBSpline.uniform_bsplinebasis_kernel(Val(2),t), label=false)\n# polynomial degree 3\nplot4 = histogram([rand()+rand()+rand()+rand() for _ in 1:N], normalize=true, label=false)\nplot!(t->BasicBSpline.uniform_bsplinebasis_kernel(Val(3),t), label=false)\n# plot all\nplot(plot1,plot2,plot3,plot4)\nsavefig(\"histogram-uniform.html\") # hide\nnothing # hide","category":"page"},{"location":"math-bsplinebasis/","page":"B-spline basis function","title":"B-spline basis function","text":"","category":"page"},{"location":"math-knotvector/#Knot-vector","page":"Knot vector","title":"Knot vector","text":"","category":"section"},{"location":"math-knotvector/#Definition","page":"Knot vector","title":"Definition","text":"","category":"section"},{"location":"math-knotvector/","page":"Knot vector","title":"Knot vector","text":"using BasicBSpline\nusing BasicBSplineExporter\nusing StaticArrays\nusing Plots; plotly()","category":"page"},{"location":"math-knotvector/","page":"Knot vector","title":"Knot vector","text":"tip: Def. Knot vector\nA finite sequencek = (k_1 dots k_l)is called knot vector if the sequence is broad monotonic increase, i.e. k_i le k_i+1.","category":"page"},{"location":"math-knotvector/","page":"Knot vector","title":"Knot vector","text":"[TODO: fig]","category":"page"},{"location":"math-knotvector/","page":"Knot vector","title":"Knot vector","text":"KnotVector","category":"page"},{"location":"math-knotvector/#BasicBSpline.KnotVector","page":"Knot vector","title":"BasicBSpline.KnotVector","text":"Construct knot vector from given array.\n\nk=(k_1dotsk_l)\n\nExamples\n\njulia> k = KnotVector([1,2,3])\nKnotVector([1, 2, 3])\n\njulia> k = KnotVector(1:3)\nKnotVector([1, 2, 3])\n\n\n\n\n\n","category":"type"},{"location":"math-knotvector/","page":"Knot vector","title":"Knot vector","text":"UniformKnotVector","category":"page"},{"location":"math-knotvector/#BasicBSpline.UniformKnotVector","page":"Knot vector","title":"BasicBSpline.UniformKnotVector","text":"Construct uniform knot vector from given range.\n\nk=(k_1dotsk_l)\n\nExamples\n\njulia> k = UniformKnotVector(1:8)\nUniformKnotVector(1:8)\n\njulia> UniformKnotVector(8:-1:3)\nUniformKnotVector(3:1:8)\n\n\n\n\n\n","category":"type"},{"location":"math-knotvector/","page":"Knot vector","title":"Knot vector","text":"SubKnotVector","category":"page"},{"location":"math-knotvector/#BasicBSpline.SubKnotVector","page":"Knot vector","title":"BasicBSpline.SubKnotVector","text":"A type to represetnt sub knot vector.\n\nk=(k_1dotsk_l)\n\nExamples\n\njulia> k = knotvector\"1 11 211\"\nKnotVector([1, 3, 4, 6, 6, 7, 8])\n\njulia> view(k, 2:5)\nSubKnotVector([3, 4, 6, 6])\n\n\n\n\n\n","category":"type"},{"location":"math-knotvector/","page":"Knot vector","title":"Knot vector","text":"EmptyKnotVector","category":"page"},{"location":"math-knotvector/#BasicBSpline.EmptyKnotVector","page":"Knot vector","title":"BasicBSpline.EmptyKnotVector","text":"Knot vector with zero-element.\n\nk=()\n\nThis struct is intended for internal use.\n\nExamples\n\njulia> EmptyKnotVector()\nEmptyKnotVector{Bool}()\n\njulia> EmptyKnotVector{Float64}()\nEmptyKnotVector{Float64}()\n\n\n\n\n\n","category":"type"},{"location":"math-knotvector/#Operations-for-knot-vectors","page":"Knot vector","title":"Operations for knot vectors","text":"","category":"section"},{"location":"math-knotvector/","page":"Knot vector","title":"Knot vector","text":"length(k::AbstractKnotVector)","category":"page"},{"location":"math-knotvector/#Base.length-Tuple{AbstractKnotVector}","page":"Knot vector","title":"Base.length","text":"Length of knot vector\n\nbeginaligned\nk\n=(textnumber of knot elements of k) \nendaligned\n\nFor example, (1223)=4.\n\nExamples\n\njulia> k = KnotVector([1,2,2,3]);\n\n\njulia> length(k)\n4\n\n\n\n\n\n","category":"method"},{"location":"math-knotvector/","page":"Knot vector","title":"Knot vector","text":"Although a knot vector is not a vector in linear algebra, but we introduce additional operator +.","category":"page"},{"location":"math-knotvector/","page":"Knot vector","title":"Knot vector","text":"Base.:+(k1::KnotVector{T}, k2::KnotVector{T}) where T","category":"page"},{"location":"math-knotvector/#Base.:+-Union{Tuple{T}, Tuple{KnotVector{T}, KnotVector{T}}} where T","page":"Knot vector","title":"Base.:+","text":"Sum of knot vectors\n\nbeginaligned\nk^(1)+k^(2)\n=(k^(1)_1 dots k^(1)_l^(1)) + (k^(2)_1 dots k^(2)_l^(2)) \n=(textsort of union of k^(1) textand k^(2) text)\nendaligned\n\nFor example, (1235)+(458)=(1234558).\n\nExamples\n\njulia> k1 = KnotVector([1,2,3,5]);\n\n\njulia> k2 = KnotVector([4,5,8]);\n\n\njulia> k1 + k2\nKnotVector([1, 2, 3, 4, 5, 5, 8])\n\n\n\n\n\n","category":"method"},{"location":"math-knotvector/","page":"Knot vector","title":"Knot vector","text":"Note that the operator +(::KnotVector, ::KnotVector) is commutative. This is why we choose the + sign. We also introduce product operator cdot for knot vector.","category":"page"},{"location":"math-knotvector/","page":"Knot vector","title":"Knot vector","text":"*(m::Integer, k::AbstractKnotVector)","category":"page"},{"location":"math-knotvector/#Base.:*-Tuple{Integer, AbstractKnotVector}","page":"Knot vector","title":"Base.:*","text":"Product of integer and knot vector\n\nbeginaligned\nmcdot k=underbracek+cdots+k_m\nendaligned\n\nFor example, 2cdot (1225)=(11222255).\n\nExamples\n\njulia> k = KnotVector([1,2,2,5]);\n\n\njulia> 2 * k\nKnotVector([1, 1, 2, 2, 2, 2, 5, 5])\n\n\n\n\n\n","category":"method"},{"location":"math-knotvector/","page":"Knot vector","title":"Knot vector","text":"Inclusive relationship between knot vectors.","category":"page"},{"location":"math-knotvector/","page":"Knot vector","title":"Knot vector","text":"Base.issubset(k::KnotVector, k′::KnotVector)","category":"page"},{"location":"math-knotvector/#Base.issubset-Tuple{KnotVector, KnotVector}","page":"Knot vector","title":"Base.issubset","text":"Check a inclusive relationship ksubseteq k, for example:\n\nbeginaligned\n(12) subseteq (123) \n(122) notsubseteq (123) \n(123) subseteq (123) \nendaligned\n\nExamples\n\njulia> KnotVector([1,2]) ⊆ KnotVector([1,2,3])\ntrue\n\njulia> KnotVector([1,2,2]) ⊆ KnotVector([1,2,3])\nfalse\n\njulia> KnotVector([1,2,3]) ⊆ KnotVector([1,2,3])\ntrue\n\n\n\n\n\n","category":"method"},{"location":"math-knotvector/","page":"Knot vector","title":"Knot vector","text":"unique(k::AbstractKnotVector)","category":"page"},{"location":"math-knotvector/#Base.unique-Tuple{AbstractKnotVector}","page":"Knot vector","title":"Base.unique","text":"Unique elements of knot vector.\n\nbeginaligned\nwidehatk\n=(textunique knot elements of k) \nendaligned\n\nFor example, widehat(1223)=(123).\n\nExamples\n\njulia> k = KnotVector([1,2,2,3]);\n\n\njulia> unique(k)\nKnotVector([1, 2, 3])\n\n\n\n\n\n","category":"method"},{"location":"math-knotvector/","page":"Knot vector","title":"Knot vector","text":"countknots(k::AbstractKnotVector, t::Real)","category":"page"},{"location":"math-knotvector/#BasicBSpline.countknots-Tuple{AbstractKnotVector, Real}","page":"Knot vector","title":"BasicBSpline.countknots","text":"For given knot vector k, the following function mathfrakn_kmathbbRtomathbbZ represents the number of knots that duplicate the knot vector k.\n\nmathfrakn_k(t) = i mid k_i=t \n\nFor example, if k=(1223), then mathfrakn_k(03)=0, mathfrakn_k(1)=1, mathfrakn_k(2)=2.\n\njulia> k = KnotVector([1,2,2,3]);\n\n\njulia> countknots(k,0.3)\n0\n\njulia> countknots(k,1.0)\n1\n\njulia> countknots(k,2.0)\n2\n\n\n\n\n\n","category":"method"},{"location":"math-knotvector/#KnotVector-with-string-macro","page":"Knot vector","title":"KnotVector with string macro","text":"","category":"section"},{"location":"math-knotvector/","page":"Knot vector","title":"Knot vector","text":"@knotvector_str","category":"page"},{"location":"math-knotvector/#BasicBSpline.@knotvector_str","page":"Knot vector","title":"BasicBSpline.@knotvector_str","text":"@knotvector_str -> KnotVector\n\nConstruct a knotvector by specifying the numbers of duplicates of knots.\n\nExamples\n\njulia> knotvector\"11111\"\nKnotVector([1, 2, 3, 4, 5])\n\njulia> knotvector\"123\"\nKnotVector([1, 2, 2, 3, 3, 3])\n\njulia> knotvector\" 2 2 2\"\nKnotVector([2, 2, 4, 4, 6, 6])\n\njulia> knotvector\" 1\"\nKnotVector([6])\n\n\n\n\n\n","category":"macro"},{"location":"plots/#Plots.jl","page":"Plots.jl","title":"Plots.jl","text":"","category":"section"},{"location":"plots/","page":"Plots.jl","title":"Plots.jl","text":"BasicBSpline.jl has a dependency on RecipesBase.jl. This means, users can easily visalize instances defined in BasicBSpline. In this section, we will provide some plottig examples.","category":"page"},{"location":"plots/","page":"Plots.jl","title":"Plots.jl","text":"using BasicBSpline\nusing BasicBSplineFitting\nusing StaticArrays\nusing Plots; plotly()","category":"page"},{"location":"plots/#BSplineSpace","page":"Plots.jl","title":"BSplineSpace","text":"","category":"section"},{"location":"plots/","page":"Plots.jl","title":"Plots.jl","text":"k = KnotVector([0.0, 1.5, 2.5, 5.5, 8.0, 9.0, 9.5, 10.0])\nP0 = BSplineSpace{0}(k) # 0th degree piecewise polynomial space\nP1 = BSplineSpace{1}(k) # 1st degree piecewise polynomial space\nP2 = BSplineSpace{2}(k) # 2nd degree piecewise polynomial space\nP3 = BSplineSpace{3}(k) # 3rd degree piecewise polynomial space\nplot(\n plot([t->bsplinebasis(P0,i,t) for i in 1:dim(P0)], 0, 10, ylims=(0,1), legend=false, title=\"0th polynomial degree\"),\n plot([t->bsplinebasis(P1,i,t) for i in 1:dim(P1)], 0, 10, ylims=(0,1), legend=false, title=\"1st polynomial degree\"),\n plot([t->bsplinebasis(P2,i,t) for i in 1:dim(P2)], 0, 10, ylims=(0,1), legend=false, title=\"2nd polynomial degree\"),\n plot([t->bsplinebasis(P3,i,t) for i in 1:dim(P3)], 0, 10, ylims=(0,1), legend=false, title=\"3rd polynomial degree\"),\n)\nsavefig(\"plots-bsplinebasis-raw.html\") # hide\nnothing # hide","category":"page"},{"location":"plots/","page":"Plots.jl","title":"Plots.jl","text":"","category":"page"},{"location":"plots/","page":"Plots.jl","title":"Plots.jl","text":"k = KnotVector([0.0, 1.5, 2.5, 5.5, 8.0, 9.0, 9.5, 10.0])\nP0 = BSplineSpace{0}(k) # 0th degree piecewise polynomial space\nP1 = BSplineSpace{1}(k) # 1st degree piecewise polynomial space\nP2 = BSplineSpace{2}(k) # 2nd degree piecewise polynomial space\nP3 = BSplineSpace{3}(k) # 3rd degree piecewise polynomial space\nplot(\n plot(P0, ylims=(0,1), legend=false, title=\"0th polynomial degree\"),\n plot(P1, ylims=(0,1), legend=false, title=\"1st polynomial degree\"),\n plot(P2, ylims=(0,1), legend=false, title=\"2nd polynomial degree\"),\n plot(P3, ylims=(0,1), legend=false, title=\"3rd polynomial degree\"),\n layout=(2,2),\n)\nsavefig(\"plots-bsplinebasis.html\") # hide\nnothing # hide","category":"page"},{"location":"plots/","page":"Plots.jl","title":"Plots.jl","text":"","category":"page"},{"location":"plots/#BSplineDerivativeSpace","page":"Plots.jl","title":"BSplineDerivativeSpace","text":"","category":"section"},{"location":"plots/","page":"Plots.jl","title":"Plots.jl","text":"k = KnotVector([0.0, 1.5, 2.5, 5.5, 8.0, 9.0, 9.5, 10.0])\nP = BSplineSpace{3}(k)\nplot(\n plot(BSplineDerivativeSpace{0}(P), label=\"0th derivative\", color=:black),\n plot(BSplineDerivativeSpace{1}(P), label=\"1st derivative\", color=:red),\n plot(BSplineDerivativeSpace{2}(P), label=\"2nd derivative\", color=:green),\n plot(BSplineDerivativeSpace{3}(P), label=\"3rd derivative\", color=:blue),\n)\nsavefig(\"plots-bsplinebasisderivative.html\") # hide\nnothing # hide","category":"page"},{"location":"plots/","page":"Plots.jl","title":"Plots.jl","text":"","category":"page"},{"location":"plots/#BSplineManifold","page":"Plots.jl","title":"BSplineManifold","text":"","category":"section"},{"location":"plots/#Cardioid-(planar-curve)","page":"Plots.jl","title":"Cardioid (planar curve)","text":"","category":"section"},{"location":"plots/","page":"Plots.jl","title":"Plots.jl","text":"f(t) = SVector((1+cos(t))*cos(t),(1+cos(t))*sin(t))\np = 3\nk = KnotVector(range(0,2π,15)) + p * KnotVector([0,2π]) + 2 * KnotVector([π])\nP = BSplineSpace{p}(k)\na = fittingcontrolpoints(f, P)\nM = BSplineManifold(a, P)\n\nplot(M)\nsavefig(\"plots-cardioid.html\") # hide\nnothing # hide","category":"page"},{"location":"plots/","page":"Plots.jl","title":"Plots.jl","text":"","category":"page"},{"location":"plots/#Helix-(spatial-curve)","page":"Plots.jl","title":"Helix (spatial curve)","text":"","category":"section"},{"location":"plots/","page":"Plots.jl","title":"Plots.jl","text":"f(t) = SVector(cos(t),sin(t),t)\np = 3\nk = KnotVector(range(0,6π,15)) + p * KnotVector([0,6π])\nP = BSplineSpace{p}(k)\na = fittingcontrolpoints(f, P)\nM = BSplineManifold(a, P)\n\nplot(M)\nsavefig(\"plots-helix.html\") # hide\nnothing # hide","category":"page"},{"location":"plots/","page":"Plots.jl","title":"Plots.jl","text":"","category":"page"},{"location":"plots/#B-spline-surface","page":"Plots.jl","title":"B-spline surface","text":"","category":"section"},{"location":"plots/","page":"Plots.jl","title":"Plots.jl","text":"p1 = 2\np2 = 3\nk1 = KnotVector(1:10)\nk2 = KnotVector(1:20)\nP1 = BSplineSpace{p1}(k1)\nP2 = BSplineSpace{p2}(k2)\na = [SVector(i-j^2/20, j+i^2/10, sin((i+j)/2)+randn()) for i in 1:dim(P1), j in 1:dim(P2)]\nM = BSplineManifold(a,(P1,P2))\nplot(M)\n\nsavefig(\"plots-surface.html\") # hide\nnothing # hide","category":"page"},{"location":"plots/","page":"Plots.jl","title":"Plots.jl","text":"","category":"page"},{"location":"plots/#RationalBSplineManifold","page":"Plots.jl","title":"RationalBSplineManifold","text":"","category":"section"},{"location":"plots/","page":"Plots.jl","title":"Plots.jl","text":"k = KnotVector([0,0,0,1,1,1])\nP = BSplineSpace{2}(k)\na = [SVector(1,0),SVector(1,1),SVector(0,1)]\nw = [1,1/√2,1]\nM = BSplineManifold(a,P)\nR = RationalBSplineManifold(a,w,P)\nts = 0:0.01:2\nplot(cospi.(ts),sinpi.(ts), label=\"circle\")\nplot!(M, label=\"B-spline curve\")\nplot!(R, label=\"Rational B-spline curve\")\n\nsavefig(\"plots-arc.html\") # hide\nnothing # hide","category":"page"},{"location":"plots/","page":"Plots.jl","title":"Plots.jl","text":"","category":"page"},{"location":"basicbsplineexporter/#BasicBSplineExporter.jl","page":"BasicBSplineExporter.jl","title":"BasicBSplineExporter.jl","text":"","category":"section"},{"location":"basicbsplineexporter/","page":"BasicBSplineExporter.jl","title":"BasicBSplineExporter.jl","text":"BasicBSplineExporter.jl supports export BasicBSpline.BSplineManifold{Dim,Deg,<:StaticVector} to:","category":"page"},{"location":"basicbsplineexporter/","page":"BasicBSplineExporter.jl","title":"BasicBSplineExporter.jl","text":"PNG image (.png)\nSVG image (.png)\nPOV-Ray mesh (.inc)","category":"page"},{"location":"basicbsplineexporter/#Installation","page":"BasicBSplineExporter.jl","title":"Installation","text":"","category":"section"},{"location":"basicbsplineexporter/","page":"BasicBSplineExporter.jl","title":"BasicBSplineExporter.jl","text":"] add https://github.com/hyrodium/BasicBSplineExporter.jl","category":"page"},{"location":"basicbsplineexporter/#First-example","page":"BasicBSplineExporter.jl","title":"First example","text":"","category":"section"},{"location":"basicbsplineexporter/","page":"BasicBSplineExporter.jl","title":"BasicBSplineExporter.jl","text":"using BasicBSpline\nusing BasicBSplineExporter\nusing StaticArrays\n\np = 2 # degree of polynomial\nk1 = KnotVector(1:8) # knot vector\nk2 = KnotVector(rand(7))+(p+1)*KnotVector([1])\nP1 = BSplineSpace{p}(k1) # B-spline space\nP2 = BSplineSpace{p}(k2)\nn1 = dim(P1) # dimension of B-spline space\nn2 = dim(P2)\na = [SVector(2i-6.5+rand(),1.5j-6.5+rand()) for i in 1:dim(P1), j in 1:dim(P2)] # random generated control points\nM = BSplineManifold(a,(P1,P2)) # Define B-spline manifold\nsave_png(\"BasicBSplineExporter_2dim.png\", M) # save image","category":"page"},{"location":"basicbsplineexporter/","page":"BasicBSplineExporter.jl","title":"BasicBSplineExporter.jl","text":"(Image: )","category":"page"},{"location":"basicbsplineexporter/#Other-examples","page":"BasicBSplineExporter.jl","title":"Other examples","text":"","category":"section"},{"location":"basicbsplineexporter/","page":"BasicBSplineExporter.jl","title":"BasicBSplineExporter.jl","text":"Here are some images rendared with POV-Ray.","category":"page"},{"location":"basicbsplineexporter/","page":"BasicBSplineExporter.jl","title":"BasicBSplineExporter.jl","text":"(Image: ) (Image: ) (Image: )","category":"page"},{"location":"basicbsplineexporter/","page":"BasicBSplineExporter.jl","title":"BasicBSplineExporter.jl","text":"See BasicBSplineExporter.jl/test for more examples.","category":"page"},{"location":"math-derivative/#Derivative-of-B-spline","page":"Derivative","title":"Derivative of B-spline","text":"","category":"section"},{"location":"math-derivative/","page":"Derivative","title":"Derivative","text":"using BasicBSpline\nusing BasicBSplineExporter\nusing StaticArrays\nusing Plots; plotly()","category":"page"},{"location":"math-derivative/","page":"Derivative","title":"Derivative","text":"info: Thm. Derivative of B-spline basis function\nThe derivative of B-spline basis function can be expressed as follows:beginaligned\ndotB_(ipk)(t)\n=fracddtB_(ipk)(t) \n=pleft(frac1k_i+p-k_iB_(ip-1k)(t)-frac1k_i+p+1-k_i+1B_(i+1p-1k)(t)right)\nendalignedNote that dotB_(ipk)inmathcalPp-1k.","category":"page"},{"location":"math-derivative/","page":"Derivative","title":"Derivative","text":"k = KnotVector([0.0, 1.5, 2.5, 5.5, 8.0, 9.0, 9.5, 10.0])\nP = BSplineSpace{3}(k)\nplot(\n plot(BSplineDerivativeSpace{0}(P), label=\"0th derivative\", color=:black),\n plot(BSplineDerivativeSpace{1}(P), label=\"1st derivative\", color=:red),\n plot(BSplineDerivativeSpace{2}(P), label=\"2nd derivative\", color=:green),\n plot(BSplineDerivativeSpace{3}(P), label=\"3rd derivative\", color=:blue),\n)\nsavefig(\"bsplinebasisderivativeplot.html\") # hide\nnothing # hide","category":"page"},{"location":"math-derivative/","page":"Derivative","title":"Derivative","text":"","category":"page"},{"location":"math-derivative/","page":"Derivative","title":"Derivative","text":"BSplineDerivativeSpace","category":"page"},{"location":"math-derivative/#BasicBSpline.BSplineDerivativeSpace","page":"Derivative","title":"BasicBSpline.BSplineDerivativeSpace","text":"BSplineDerivativeSpace{r}(P::BSplineSpace)\n\nConstruct derivative of B-spline space from given differential order and B-spline space.\n\nD^r(mathcalPpk)\n=leftt mapsto left fracd^r fdt^r(t) right f in mathcalPpk right\n\nExamples\n\njulia> P = BSplineSpace{2}(KnotVector([1,2,3,4,5,6]))\nBSplineSpace{2, Int64, KnotVector{Int64}}(KnotVector([1, 2, 3, 4, 5, 6]))\n\njulia> dP = BSplineDerivativeSpace{1}(P)\nBSplineDerivativeSpace{1, BSplineSpace{2, Int64, KnotVector{Int64}}, Int64}(BSplineSpace{2, Int64, KnotVector{Int64}}(KnotVector([1, 2, 3, 4, 5, 6])))\n\njulia> degree(P), degree(dP)\n(2, 1)\n\n\n\n\n\n","category":"type"},{"location":"math-derivative/","page":"Derivative","title":"Derivative","text":"BasicBSpline.derivative","category":"page"},{"location":"math-derivative/#BasicBSpline.derivative","page":"Derivative","title":"BasicBSpline.derivative","text":"derivative(::BSplineDerivativeSpace{r}) -> BSplineDerivativeSpace{r+1}\nderivative(::BSplineSpace) -> BSplineDerivativeSpace{1}\n\nDerivative of B-spline related space.\n\nExamples\n\njulia> BSplineSpace{2}(KnotVector(0:5))\nBSplineSpace{2, Int64, KnotVector{Int64}}(KnotVector([0, 1, 2, 3, 4, 5]))\n\njulia> BasicBSpline.derivative(ans)\nBSplineDerivativeSpace{1, BSplineSpace{2, Int64, KnotVector{Int64}}, Int64}(BSplineSpace{2, Int64, KnotVector{Int64}}(KnotVector([0, 1, 2, 3, 4, 5])))\n\njulia> BasicBSpline.derivative(ans)\nBSplineDerivativeSpace{2, BSplineSpace{2, Int64, KnotVector{Int64}}, Int64}(BSplineSpace{2, Int64, KnotVector{Int64}}(KnotVector([0, 1, 2, 3, 4, 5])))\n\n\n\n\n\n","category":"function"},{"location":"math-derivative/","page":"Derivative","title":"Derivative","text":"bsplinebasis′₊₀","category":"page"},{"location":"math-derivative/#BasicBSpline.bsplinebasis′₊₀","page":"Derivative","title":"BasicBSpline.bsplinebasis′₊₀","text":"bsplinebasis′₊₀(::AbstractFunctionSpace, ::Integer, ::Real) -> Real\n\n1st derivative of B-spline basis function. Right-sided limit version.\n\ndotB_(ipk)(t)\n=pleft(frac1k_i+p-k_iB_(ip-1k)(t)-frac1k_i+p+1-k_i+1B_(i+1p-1k)(t)right)\n\nbsplinebasis′₊₀(P, i, t) is equivalent to bsplinebasis₊₀(derivative(P), i, t).\n\n\n\n\n\n","category":"function"},{"location":"math-derivative/","page":"Derivative","title":"Derivative","text":"bsplinebasis′₋₀","category":"page"},{"location":"math-derivative/#BasicBSpline.bsplinebasis′₋₀","page":"Derivative","title":"BasicBSpline.bsplinebasis′₋₀","text":"bsplinebasis′₋₀(::AbstractFunctionSpace, ::Integer, ::Real) -> Real\n\n1st derivative of B-spline basis function. Left-sided limit version.\n\ndotB_(ipk)(t)\n=pleft(frac1k_i+p-k_iB_(ip-1k)(t)-frac1k_i+p+1-k_i+1B_(i+1p-1k)(t)right)\n\nbsplinebasis′₋₀(P, i, t) is equivalent to bsplinebasis₋₀(derivative(P), i, t).\n\n\n\n\n\n","category":"function"},{"location":"math-derivative/","page":"Derivative","title":"Derivative","text":"bsplinebasis′","category":"page"},{"location":"math-derivative/#BasicBSpline.bsplinebasis′","page":"Derivative","title":"BasicBSpline.bsplinebasis′","text":"bsplinebasis′(::AbstractFunctionSpace, ::Integer, ::Real) -> Real\n\n1st derivative of B-spline basis function. Modified version.\n\ndotB_(ipk)(t)\n=pleft(frac1k_i+p-k_iB_(ip-1k)(t)-frac1k_i+p+1-k_i+1B_(i+1p-1k)(t)right)\n\nbsplinebasis′(P, i, t) is equivalent to bsplinebasis(derivative(P), i, t).\n\n\n\n\n\n","category":"function"},{"location":"plotlyjs/#PlotlyJS.jl","page":"PlotlyJS.jl","title":"PlotlyJS.jl","text":"","category":"section"},{"location":"plotlyjs/#Cardioid","page":"PlotlyJS.jl","title":"Cardioid","text":"","category":"section"},{"location":"plotlyjs/","page":"PlotlyJS.jl","title":"PlotlyJS.jl","text":"using BasicBSpline\nusing BasicBSplineFitting\nusing StaticArrays\nusing PlotlyJS\nf(t) = SVector((1+cos(t))*cos(t),(1+cos(t))*sin(t))\np = 3\nk = KnotVector(range(0,2π,15)) + p * KnotVector([0,2π]) + 2 * KnotVector([π])\nP = BSplineSpace{p}(k)\na = fittingcontrolpoints(f, P)\nM = BSplineManifold(a, P)\n\nts = range(0,2π,250)\nxs_a = getindex.(a,1)\nys_a = getindex.(a,2)\nxs_f = getindex.(M.(ts),1)\nys_f = getindex.(M.(ts),2)\nfig = Plot(scatter(x=xs_a, y=ys_a, name=\"control points\", line_color=\"blue\", marker_size=8))\naddtraces!(fig, scatter(x=xs_f, y=ys_f, name=\"B-spline curve\", mode=\"lines\", line_color=\"red\"))\nrelayout!(fig, width=500, height=500)\nsavefig(fig,\"cardioid.html\") # hide\nnothing # hide","category":"page"},{"location":"plotlyjs/","page":"PlotlyJS.jl","title":"PlotlyJS.jl","text":"","category":"page"},{"location":"plotlyjs/#Helix","page":"PlotlyJS.jl","title":"Helix","text":"","category":"section"},{"location":"plotlyjs/","page":"PlotlyJS.jl","title":"PlotlyJS.jl","text":"using BasicBSpline\nusing BasicBSplineFitting\nusing StaticArrays\nusing PlotlyJS\nf(t) = SVector(cos(t),sin(t),t)\np = 3\nk = KnotVector(range(0,6π,15)) + p * KnotVector([0,6π])\nP = BSplineSpace{p}(k)\na = fittingcontrolpoints(f, P)\nM = BSplineManifold(a, P)\n\nts = range(0,6π,250)\nxs_a = getindex.(a,1)\nys_a = getindex.(a,2)\nzs_a = getindex.(a,3)\nxs_f = getindex.(M.(ts),1)\nys_f = getindex.(M.(ts),2)\nzs_f = getindex.(M.(ts),3)\nfig = Plot(scatter3d(x=xs_a, y=ys_a, z=zs_a, name=\"control points\", line_color=\"blue\", marker_size=8))\naddtraces!(fig, scatter3d(x=xs_f, y=ys_f, z=zs_f, name=\"B-spline curve\", mode=\"lines\", line_color=\"red\"))\nrelayout!(fig, width=500, height=500)\nsavefig(fig,\"helix.html\") # hide\nnothing # hide","category":"page"},{"location":"plotlyjs/","page":"PlotlyJS.jl","title":"PlotlyJS.jl","text":"","category":"page"},{"location":"internal/#Private-API","page":"Private API","title":"Private API","text":"","category":"section"},{"location":"internal/","page":"Private API","title":"Private API","text":"Note that the following methods are considered private methods, and changes in their behavior are not considered breaking changes.","category":"page"},{"location":"internal/","page":"Private API","title":"Private API","text":"BasicBSpline.r_nomial","category":"page"},{"location":"internal/#BasicBSpline.r_nomial","page":"Private API","title":"BasicBSpline.r_nomial","text":"Calculate r-nomial coefficient\n\nr_nomial(n, k, r)\n\n(1+x+cdots+x^r)^n = sum_k a_nkr x^k\n\n\n\n\n\n","category":"function"},{"location":"internal/","page":"Private API","title":"Private API","text":"BasicBSpline._vec","category":"page"},{"location":"internal/#BasicBSpline._vec","page":"Private API","title":"BasicBSpline._vec","text":"Convert AbstractKnotVector to AbstractVector\n\n\n\n\n\n","category":"function"},{"location":"internal/","page":"Private API","title":"Private API","text":"BasicBSpline._lower_R","category":"page"},{"location":"internal/#BasicBSpline._lower_R","page":"Private API","title":"BasicBSpline._lower_R","text":"Internal methods for obtaining a B-spline space with one degree lower.\n\nbeginaligned\nmathcalPpk mapsto mathcalPp-1k \nD^rmathcalPpk mapsto D^r-1mathcalPp-1k\nendaligned\n\n\n\n\n\n","category":"function"},{"location":"internal/","page":"Private API","title":"Private API","text":"BasicBSpline._changebasis_sim","category":"page"},{"location":"internal/#BasicBSpline._changebasis_sim","page":"Private API","title":"BasicBSpline._changebasis_sim","text":"Return a coefficient matrix A which satisfy\n\nB_(ip_1k_1) = sum_jA_ijB_(jp_2k_2)\n\nAssumption:\n\nP_1 P_2\n\n\n\n\n\n","category":"function"},{"location":"internal/","page":"Private API","title":"Private API","text":"BasicBSplineFitting.innerproduct_R","category":"page"},{"location":"internal/#BasicBSplineFitting.innerproduct_R","page":"Private API","title":"BasicBSplineFitting.innerproduct_R","text":"Calculate a matrix\n\nA_ij=int_mathbbR B_(ipk)(t) B_(jpk)(t) dt\n\n\n\n\n\n","category":"function"},{"location":"internal/","page":"Private API","title":"Private API","text":"BasicBSplineFitting.innerproduct_I","category":"page"},{"location":"internal/#BasicBSplineFitting.innerproduct_I","page":"Private API","title":"BasicBSplineFitting.innerproduct_I","text":"Calculate a matrix\n\nA_ij=int_I B_(ipk)(t) B_(jpk)(t) dt\n\n\n\n\n\n","category":"function"},{"location":"math-inclusive/#Inclusive-relation-between-B-spline-spaces","page":"Inclusive relationship","title":"Inclusive relation between B-spline spaces","text":"","category":"section"},{"location":"math-inclusive/","page":"Inclusive relationship","title":"Inclusive relationship","text":"using BasicBSpline\nusing BasicBSplineExporter\nusing StaticArrays\nusing Plots; plotly()","category":"page"},{"location":"math-inclusive/","page":"Inclusive relationship","title":"Inclusive relationship","text":"info: Thm. Inclusive relation between B-spline spaces\nFor non-degenerate B-spline spaces, the following relationship holds.mathcalPpk\nsubseteq mathcalPpk\nLeftrightarrow (m=p-p ge 0 textand k+mwidehatksubseteq k)","category":"page"},{"location":"math-inclusive/","page":"Inclusive relationship","title":"Inclusive relationship","text":"Base.issubset(P::BSplineSpace{p}, P′::BSplineSpace{p′}) where {p, p′}","category":"page"},{"location":"math-inclusive/#Base.issubset-Union{Tuple{p′}, Tuple{p}, Tuple{BSplineSpace{p, T} where T<:Real, BSplineSpace{p′, T} where T<:Real}} where {p, p′}","page":"Inclusive relationship","title":"Base.issubset","text":"Check inclusive relationship between B-spline spaces.\n\nmathcalPpk\nsubseteqmathcalPpk\n\nExamples\n\njulia> P1 = BSplineSpace{1}(KnotVector([1,3,5,8]));\n\n\njulia> P2 = BSplineSpace{1}(KnotVector([1,3,5,6,8,9]));\n\n\njulia> P3 = BSplineSpace{2}(KnotVector([1,1,3,3,5,5,8,8]));\n\n\njulia> P1 ⊆ P2\ntrue\n\njulia> P1 ⊆ P3\ntrue\n\njulia> P2 ⊆ P3\nfalse\n\njulia> P2 ⊈ P3\ntrue\n\n\n\n\n\n","category":"method"},{"location":"math-inclusive/","page":"Inclusive relationship","title":"Inclusive relationship","text":"Here are plots of the B-spline basis functions of the spaces P1, P2, P3.","category":"page"},{"location":"math-inclusive/","page":"Inclusive relationship","title":"Inclusive relationship","text":"P1 = BSplineSpace{1}(KnotVector([1,3,5,8]))\nP2 = BSplineSpace{1}(KnotVector([1,3,5,6,8,9]))\nP3 = BSplineSpace{2}(KnotVector([1,1,3,3,5,5,8,8]))\nplot(\n plot([t->bsplinebasis₊₀(P1,i,t) for i in 1:dim(P1)], 1, 9, ylims=(0,1), legend=false),\n plot([t->bsplinebasis₊₀(P2,i,t) for i in 1:dim(P2)], 1, 9, ylims=(0,1), legend=false),\n plot([t->bsplinebasis₊₀(P3,i,t) for i in 1:dim(P3)], 1, 9, ylims=(0,1), legend=false),\n layout=(3,1),\n link=:x\n)\nsavefig(\"subbsplineplot.html\") # hide\nnothing # hide","category":"page"},{"location":"math-inclusive/","page":"Inclusive relationship","title":"Inclusive relationship","text":"","category":"page"},{"location":"math-inclusive/","page":"Inclusive relationship","title":"Inclusive relationship","text":"This means, there exists a n times n matrix A which holds:","category":"page"},{"location":"math-inclusive/","page":"Inclusive relationship","title":"Inclusive relationship","text":"beginaligned\nB_(ipk)\n=sum_jA_ij B_(jpk) \nn=dim(mathcalPpk) \nn=dim(mathcalPpk)\nendaligned","category":"page"},{"location":"math-inclusive/","page":"Inclusive relationship","title":"Inclusive relationship","text":"You can calculate the change of basis matrix A with changebasis.","category":"page"},{"location":"math-inclusive/","page":"Inclusive relationship","title":"Inclusive relationship","text":"A12 = changebasis(P1,P2)\nA13 = changebasis(P1,P3)","category":"page"},{"location":"math-inclusive/","page":"Inclusive relationship","title":"Inclusive relationship","text":"plot(\n plot([t->bsplinebasis₊₀(P1,i,t) for i in 1:dim(P1)], 1, 9, ylims=(0,1), legend=false),\n plot([t->sum(A12[i,j]*bsplinebasis₊₀(P2,j,t) for j in 1:dim(P2)) for i in 1:dim(P1)], 1, 9, ylims=(0,1), legend=false),\n plot([t->sum(A13[i,j]*bsplinebasis₊₀(P3,j,t) for j in 1:dim(P3)) for i in 1:dim(P1)], 1, 9, ylims=(0,1), legend=false),\n layout=(3,1),\n link=:x\n)\nsavefig(\"subbsplineplot2.html\") # hide\nnothing # hide","category":"page"},{"location":"math-inclusive/","page":"Inclusive relationship","title":"Inclusive relationship","text":"","category":"page"},{"location":"math-inclusive/","page":"Inclusive relationship","title":"Inclusive relationship","text":"changebasis_R","category":"page"},{"location":"math-inclusive/#BasicBSpline.changebasis_R","page":"Inclusive relationship","title":"BasicBSpline.changebasis_R","text":"Return a coefficient matrix A which satisfy\n\nB_(ipk) = sum_jA_ijB_(jpk)\n\nAssumption:\n\nP P^prime\n\n\n\n\n\n","category":"function"},{"location":"math-inclusive/","page":"Inclusive relationship","title":"Inclusive relationship","text":"changebasis_I","category":"page"},{"location":"math-inclusive/#BasicBSpline.changebasis_I","page":"Inclusive relationship","title":"BasicBSpline.changebasis_I","text":"Return a coefficient matrix A which satisfy\n\nB_(ipk) = sum_jA_ijB_(jpk)\n\nAssumption:\n\nP P^prime\n\n\n\n\n\n","category":"function"},{"location":"math-inclusive/","page":"Inclusive relationship","title":"Inclusive relationship","text":"issqsubset","category":"page"},{"location":"math-inclusive/#BasicBSpline.issqsubset","page":"Inclusive relationship","title":"BasicBSpline.issqsubset","text":"Check inclusive relationship between B-spline spaces.\n\nmathcalPpk\nsqsubseteqmathcalPpk\nLeftrightarrow\nmathcalPpk_k_p+1k_l-p\nsubseteqmathcalPpk_k_p+1k_l-p\n\n\n\n\n\n","category":"function"},{"location":"math-inclusive/","page":"Inclusive relationship","title":"Inclusive relationship","text":"expandspace","category":"page"},{"location":"math-inclusive/#BasicBSpline.expandspace","page":"Inclusive relationship","title":"BasicBSpline.expandspace","text":"Expand B-spline space with given additional degree and knotvector. The behavior of expandspace is same as expandspace_I.\n\n\n\n\n\n","category":"function"},{"location":"math-inclusive/","page":"Inclusive relationship","title":"Inclusive relationship","text":"expandspace_R","category":"page"},{"location":"math-inclusive/#BasicBSpline.expandspace_R","page":"Inclusive relationship","title":"BasicBSpline.expandspace_R","text":"Expand B-spline space with given additional degree and knotvector. This function is compatible with issubset (⊆).\n\nExamples\n\njulia> k = KnotVector([0.0, 1.5, 2.5, 5.5, 8.0, 9.0, 9.5, 10.0]);\n\n\njulia> P = BSplineSpace{2}(k);\n\n\njulia> P′ = expandspace_R(P, Val(1), KnotVector([6.0]))\nBSplineSpace{3, Float64, KnotVector{Float64}}(KnotVector([0.0, 0.0, 1.5, 1.5, 2.5, 2.5, 5.5, 5.5, 6.0, 8.0, 8.0, 9.0, 9.0, 9.5, 9.5, 10.0, 10.0]))\n\njulia> P ⊆ P′\ntrue\n\njulia> P ⊑ P′\nfalse\n\njulia> domain(P)\n2.5 .. 9.0\n\njulia> domain(P′)\n1.5 .. 9.5\n\n\n\n\n\n","category":"function"},{"location":"math-inclusive/","page":"Inclusive relationship","title":"Inclusive relationship","text":"expandspace_I","category":"page"},{"location":"math-inclusive/#BasicBSpline.expandspace_I","page":"Inclusive relationship","title":"BasicBSpline.expandspace_I","text":"Expand B-spline space with given additional degree and knotvector. This function is compatible with issqsubset (⊑)\n\nExamples\n\njulia> k = KnotVector([0.0, 1.5, 2.5, 5.5, 8.0, 9.0, 9.5, 10.0]);\n\n\njulia> P = BSplineSpace{2}(k);\n\n\njulia> P′ = expandspace_I(P, Val(1), KnotVector([6.0]))\nBSplineSpace{3, Float64, KnotVector{Float64}}(KnotVector([0.0, 1.5, 2.5, 2.5, 5.5, 5.5, 6.0, 8.0, 8.0, 9.0, 9.0, 9.5, 10.0]))\n\njulia> P ⊆ P′\nfalse\n\njulia> P ⊑ P′\ntrue\n\njulia> domain(P)\n2.5 .. 9.0\n\njulia> domain(P′)\n2.5 .. 9.0\n\n\n\n\n\n","category":"function"},{"location":"math/#Mathematical-properties-of-B-spline","page":"Introduction","title":"Mathematical properties of B-spline","text":"","category":"section"},{"location":"math/#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"math/","page":"Introduction","title":"Introduction","text":"B-spline is a mathematical object, and it has a lot of application. (e.g. Geometric representation: NURBS, Interpolation, Numerical analysis: IGA)","category":"page"},{"location":"math/","page":"Introduction","title":"Introduction","text":"In this page, we'll explain the mathematical definitions and properties of B-spline with Julia code. Before running the code in the following section, you need to import packages:","category":"page"},{"location":"math/","page":"Introduction","title":"Introduction","text":"using BasicBSpline\nusing Plots; plotly()","category":"page"},{"location":"math/#Notice","page":"Introduction","title":"Notice","text":"","category":"section"},{"location":"math/","page":"Introduction","title":"Introduction","text":"Some of notations in this page are our original, but these are well-considered results.","category":"page"},{"location":"math/#References","page":"Introduction","title":"References","text":"","category":"section"},{"location":"math/","page":"Introduction","title":"Introduction","text":"Most of this documentation around B-spline is self-contained. If you want to learn more, the following resources are recommended.","category":"page"},{"location":"math/","page":"Introduction","title":"Introduction","text":"\"Geometric Modeling with Splines\" by Elaine Cohen, Richard F. Riesenfeld, Gershon Elber\n\"Spline Functions: Basic Theory\" by Larry Schumaker","category":"page"},{"location":"math/","page":"Introduction","title":"Introduction","text":"日本語の文献では以下がおすすめです。","category":"page"},{"location":"math/","page":"Introduction","title":"Introduction","text":"スプライン関数とその応用 by 市田浩三, 吉本富士市\nNURBS多様体による形状表現\nBasicBSpline.jlを作ったので宣伝です!\nB-spline入門(線形代数がすこし分かる人向け)","category":"page"},{"location":"math-bsplinemanifold/#B-spline-manifold","page":"B-spline manifold","title":"B-spline manifold","text":"","category":"section"},{"location":"math-bsplinemanifold/","page":"B-spline manifold","title":"B-spline manifold","text":"using BasicBSpline\nusing BasicBSplineExporter\nusing StaticArrays\nusing Plots; plotly()","category":"page"},{"location":"math-bsplinemanifold/#Multi-dimensional-B-spline","page":"B-spline manifold","title":"Multi-dimensional B-spline","text":"","category":"section"},{"location":"math-bsplinemanifold/","page":"B-spline manifold","title":"B-spline manifold","text":"info: Thm. Basis of tensor product of B-spline spaces\nThe tensor product of B-spline spaces mathcalPp^1k^1otimesmathcalPp^2k^2 is a linear space with the following basis.mathcalPp^1k^1otimesmathcalPp^2k^2\n= operatorname*span_ij (B_(ip^1k^1) otimes B_(jp^2k^2))where the basis are defined as(B_(ip^1k^1) otimes B_(jp^2k^2))(t^1 t^2)\n= B_(ip^1k^1)(t^1) cdot B_(jp^2k^2)(t^2)","category":"page"},{"location":"math-bsplinemanifold/","page":"B-spline manifold","title":"B-spline manifold","text":"Higher dimensional tensor products mathcalPp^1k^1otimescdotsotimesmathcalPp^dk^d are defined similarly.","category":"page"},{"location":"math-bsplinemanifold/#B-spline-manifold-2","page":"B-spline manifold","title":"B-spline manifold","text":"","category":"section"},{"location":"math-bsplinemanifold/","page":"B-spline manifold","title":"B-spline manifold","text":"B-spline manifold is a parametric representation of a shape.","category":"page"},{"location":"math-bsplinemanifold/","page":"B-spline manifold","title":"B-spline manifold","text":"tip: Def. B-spline manifold\nFor given d-dimensional B-spline basis functions B_(i^1p^1k^1) otimes cdots otimes B_(i^dp^dk^d) and given points bma_i^1 dots i^d in V, B-spline manifold is defined by the following equality:bmp(t^1dotst^dbma_i^1 dots i^d)\n=sum_i^1dotsi^d(B_(i^1p^1k^1) otimes cdots otimes B_(i^dp^dk^d))(t^1dotst^d) bma_i^1 dots i^dWhere bma_i^1 dots i^d are called control points.","category":"page"},{"location":"math-bsplinemanifold/","page":"B-spline manifold","title":"B-spline manifold","text":"We will also write bmp(t^1dotst^d bma), bmp(t^1dotst^d), bmp(t bma) or bmp(t) for simplicity.","category":"page"},{"location":"math-bsplinemanifold/","page":"B-spline manifold","title":"B-spline manifold","text":"Note that the BSplineManifold objects are callable, and the arguments will be checked if it fits in the domain of BSplineSpace.","category":"page"},{"location":"math-bsplinemanifold/","page":"B-spline manifold","title":"B-spline manifold","text":"BSplineManifold","category":"page"},{"location":"math-bsplinemanifold/#BasicBSpline.BSplineManifold","page":"B-spline manifold","title":"BasicBSpline.BSplineManifold","text":"Construct B-spline manifold from given control points and B-spline spaces.\n\nExamples\n\njulia> using StaticArrays\n\njulia> P = BSplineSpace{2}(KnotVector([0,0,0,1,1,1]))\nBSplineSpace{2, Int64, KnotVector{Int64}}(KnotVector([0, 0, 0, 1, 1, 1]))\n\njulia> a = [SVector(1,0), SVector(1,1), SVector(0,1)]\n3-element Vector{SVector{2, Int64}}:\n [1, 0]\n [1, 1]\n [0, 1]\n\njulia> M = BSplineManifold(a, P);\n\n\njulia> M(0.4)\n2-element SVector{2, Float64} with indices SOneTo(2):\n 0.84\n 0.64\n\njulia> M(1.2)\nERROR: DomainError with 1.2:\nThe input 1.2 is out of range.\n[...]\n\n\n\n\n\n","category":"type"},{"location":"math-bsplinemanifold/","page":"B-spline manifold","title":"B-spline manifold","text":"If you need extension of BSplineManifold or don't need the arguments check, you can call unbounded_mapping.","category":"page"},{"location":"math-bsplinemanifold/","page":"B-spline manifold","title":"B-spline manifold","text":"unbounded_mapping","category":"page"},{"location":"math-bsplinemanifold/#BasicBSpline.unbounded_mapping","page":"B-spline manifold","title":"BasicBSpline.unbounded_mapping","text":"unbounded_mapping(M::BSplineManifold{Dim}, t::Vararg{Real,Dim})\n\nExamples\n\njulia> P = BSplineSpace{1}(KnotVector([0,0,1,1]))\nBSplineSpace{1, Int64, KnotVector{Int64}}(KnotVector([0, 0, 1, 1]))\n\njulia> domain(P)\n0 .. 1\n\njulia> M = BSplineManifold([0,1], P);\n\n\njulia> unbounded_mapping(M, 0.1)\n0.1\n\njulia> M(0.1)\n0.1\n\njulia> unbounded_mapping(M, 1.2)\n1.2\n\njulia> M(1.2)\nERROR: DomainError with 1.2:\nThe input 1.2 is out of range.\n[...]\n\n\n\n\n\n","category":"function"},{"location":"math-bsplinemanifold/","page":"B-spline manifold","title":"B-spline manifold","text":"unbounded_mapping(M,t...) is a little bit faster than M(t...) because it does not check the domain.","category":"page"},{"location":"math-bsplinemanifold/#B-spline-curve","page":"B-spline manifold","title":"B-spline curve","text":"","category":"section"},{"location":"math-bsplinemanifold/","page":"B-spline manifold","title":"B-spline manifold","text":"## 1-dim B-spline manifold\np = 2 # degree of polynomial\nk = KnotVector(1:12) # knot vector\nP = BSplineSpace{p}(k) # B-spline space\na = [SVector(i-5, 3*sin(i^2)) for i in 1:dim(P)] # control points\nM = BSplineManifold(a, P) # Define B-spline manifold\nplot(M)\nsavefig(\"1dim-manifold.html\") # hide\nnothing # hide","category":"page"},{"location":"math-bsplinemanifold/","page":"B-spline manifold","title":"B-spline manifold","text":"","category":"page"},{"location":"math-bsplinemanifold/#B-spline-surface","page":"B-spline manifold","title":"B-spline surface","text":"","category":"section"},{"location":"math-bsplinemanifold/","page":"B-spline manifold","title":"B-spline manifold","text":"## 2-dim B-spline manifold\np = 2 # degree of polynomial\nk = KnotVector(1:8) # knot vector\nP = BSplineSpace{p}(k) # B-spline space\nrand_a = [SVector(rand(), rand(), rand()) for i in 1:dim(P), j in 1:dim(P)]\na = [SVector(2*i-6.5, 2*j-6.5, 0) for i in 1:dim(P), j in 1:dim(P)] + rand_a # random generated control points\nM = BSplineManifold(a,(P,P)) # Define B-spline manifold\nplot(M)\nsavefig(\"2dim-manifold.html\") # hide\nnothing # hide","category":"page"},{"location":"math-bsplinemanifold/","page":"B-spline manifold","title":"B-spline manifold","text":"","category":"page"},{"location":"math-bsplinemanifold/#Affine-commutativity","page":"B-spline manifold","title":"Affine commutativity","text":"","category":"section"},{"location":"math-bsplinemanifold/","page":"B-spline manifold","title":"B-spline manifold","text":"info: Thm. Affine commutativity\nLet T be a affine transform V to W, then the following equality holds.T(bmp(t bma))\n=bmp(t T(bma))","category":"page"},{"location":"math-bsplinemanifold/#Fixing-arguments-(currying)","page":"B-spline manifold","title":"Fixing arguments (currying)","text":"","category":"section"},{"location":"math-bsplinemanifold/","page":"B-spline manifold","title":"B-spline manifold","text":"Just like fixing first index such as A[3,:]::Array{1} for matrix A::Array{2}, fixing first argument M(4.3,:) will create BSplineManifold{1} for B-spline surface M::BSplineManifold{2}.","category":"page"},{"location":"math-bsplinemanifold/","page":"B-spline manifold","title":"B-spline manifold","text":"p = 2;\nk = KnotVector(1:8);\nP = BSplineSpace{p}(k);\na = [SVector(5i+5j+rand(), 5i-5j+rand(), rand()) for i in 1:dim(P), j in 1:dim(P)];\nM = BSplineManifold(a,(P,P));\nM isa BSplineManifold{2}\nM(:,:) isa BSplineManifold{2}\nM(4.3,:) isa BSplineManifold{1} # Fix first argument","category":"page"},{"location":"math-bsplinemanifold/","page":"B-spline manifold","title":"B-spline manifold","text":"plot(M)\nplot!(M(4.3,:), linewidth = 5, color=:cyan)\nplot!(M(4.4,:), linewidth = 5, color=:red)\nplot!(M(:,5.2), linewidth = 5, color=:green)\nsavefig(\"2dim-manifold-currying.html\") # hide\nnothing # hide","category":"page"},{"location":"math-bsplinemanifold/","page":"B-spline manifold","title":"B-spline manifold","text":"","category":"page"},{"location":"math-bsplinespace/#B-spline-space","page":"B-spline space","title":"B-spline space","text":"","category":"section"},{"location":"math-bsplinespace/","page":"B-spline space","title":"B-spline space","text":"using BasicBSpline\nusing BasicBSplineExporter\nusing StaticArrays\nusing Plots; plotly()","category":"page"},{"location":"math-bsplinespace/#Defnition","page":"B-spline space","title":"Defnition","text":"","category":"section"},{"location":"math-bsplinespace/","page":"B-spline space","title":"B-spline space","text":"Before defining B-spline space, we'll define polynomial space with degree p.","category":"page"},{"location":"math-bsplinespace/","page":"B-spline space","title":"B-spline space","text":"tip: Def. Polynomial space\nPolynomial space with degree p.mathcalPp\n=leftfmathbbRtomathbbR tmapsto a_0+a_1t^1+cdots+a_pt^p left \n a_iin mathbbR\n right\nrightThis space mathcalPp is a (p+1)-dimensional linear space.","category":"page"},{"location":"math-bsplinespace/","page":"B-spline space","title":"B-spline space","text":"Note that tmapsto t^i_0 le i le p is a basis of mathcalPp, and also the set of Bernstein polynomial B_(ip)_i is a basis of mathcalPp.","category":"page"},{"location":"math-bsplinespace/","page":"B-spline space","title":"B-spline space","text":"beginaligned\nB_(ip)(t)\n=binompi-1t^i-1(1-t)^p-i+1\n(i=1 dots p+1)\nendaligned","category":"page"},{"location":"math-bsplinespace/","page":"B-spline space","title":"B-spline space","text":"Where binompi-1 is a binomial coefficient. You can try Bernstein polynomial on desmos graphing calculator!","category":"page"},{"location":"math-bsplinespace/","page":"B-spline space","title":"B-spline space","text":"tip: Def. B-spline space\nFor given polynomial degree pge 0 and knot vector k=(k_1dotsk_l), B-spline space mathcalPpk is defined as follows:mathcalPpk\n=leftfmathbbRtomathbbR left \n begingathered\n operatornamesupp(f)subseteq k_1 k_l \n exists tildefinmathcalPp f_k_i k_i+1) = tildef_k_i k_i+1) \n forall t in mathbbR exists delta 0 f_(t-deltat+delta)in C^p-mathfrakn_k(t)\n endgathered right\nright","category":"page"},{"location":"math-bsplinespace/","page":"B-spline space","title":"B-spline space","text":"Note that each element of the space mathcalPpk is a piecewise polynomial.","category":"page"},{"location":"math-bsplinespace/","page":"B-spline space","title":"B-spline space","text":"[TODO: fig]","category":"page"},{"location":"math-bsplinespace/","page":"B-spline space","title":"B-spline space","text":"BSplineSpace","category":"page"},{"location":"math-bsplinespace/#BasicBSpline.BSplineSpace","page":"B-spline space","title":"BasicBSpline.BSplineSpace","text":"Construct B-spline space from given polynominal degree and knot vector.\n\nmathcalPpk\n\nExamples\n\njulia> p = 2\n2\n\njulia> k = KnotVector([1,3,5,6,8,9])\nKnotVector([1, 3, 5, 6, 8, 9])\n\njulia> BSplineSpace{p}(k)\nBSplineSpace{2, Int64, KnotVector{Int64}}(KnotVector([1, 3, 5, 6, 8, 9]))\n\n\n\n\n\n","category":"type"},{"location":"math-bsplinespace/#Degeneration","page":"B-spline space","title":"Degeneration","text":"","category":"section"},{"location":"math-bsplinespace/","page":"B-spline space","title":"B-spline space","text":"tip: Def. Degeneration\nA B-spline space is said to be non-degenerate if its degree and knot vector satisfies following property:beginaligned\nk_ik_i+p+1 (1 le i le l-p-1)\nendaligned","category":"page"},{"location":"math-bsplinespace/","page":"B-spline space","title":"B-spline space","text":"isnondegenerate","category":"page"},{"location":"math-bsplinespace/#BasicBSpline.isnondegenerate","page":"B-spline space","title":"BasicBSpline.isnondegenerate","text":"Check if given B-spline space is non-degenerate.\n\nExamples\n\njulia> isnondegenerate(BSplineSpace{2}(KnotVector([1,3,5,6,8,9])))\ntrue\n\njulia> isnondegenerate(BSplineSpace{1}(KnotVector([1,3,3,3,8,9])))\nfalse\n\n\n\n\n\n","category":"function"},{"location":"math-bsplinespace/","page":"B-spline space","title":"B-spline space","text":"isdegenerate(P::BSplineSpace)","category":"page"},{"location":"math-bsplinespace/#BasicBSpline.isdegenerate-Tuple{BSplineSpace}","page":"B-spline space","title":"BasicBSpline.isdegenerate","text":"Check if given B-spline space is degenerate.\n\nExamples\n\njulia> isdegenerate(BSplineSpace{2}(KnotVector([1,3,5,6,8,9])))\nfalse\n\njulia> isdegenerate(BSplineSpace{1}(KnotVector([1,3,3,3,8,9])))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"math-bsplinespace/#Dimensions","page":"B-spline space","title":"Dimensions","text":"","category":"section"},{"location":"math-bsplinespace/","page":"B-spline space","title":"B-spline space","text":"info: Thm. Dimension of B-spline space\nThe B-spline space is a linear space, and if a B-spline space is non-degenerate, its dimension is calculated by:dim(mathcalPpk)= k - p -1","category":"page"},{"location":"math-bsplinespace/","page":"B-spline space","title":"B-spline space","text":"dim","category":"page"},{"location":"math-bsplinespace/#BasicBSpline.dim","page":"B-spline space","title":"BasicBSpline.dim","text":"Return dimention of a B-spline space.\n\ndim(mathcalPpk)\n= k - p -1\n\nExamples\n\njulia> dim(BSplineSpace{1}(KnotVector([1,2,3,4,5,6,7])))\n5\n\njulia> dim(BSplineSpace{1}(KnotVector([1,2,4,4,4,6,7])))\n5\n\njulia> dim(BSplineSpace{1}(KnotVector([1,2,3,5,5,5,7])))\n5\n\n\n\n\n\n","category":"function"},{"location":"math-bsplinespace/","page":"B-spline space","title":"B-spline space","text":"exactdim_R(P::BSplineSpace)","category":"page"},{"location":"math-bsplinespace/#BasicBSpline.exactdim_R-Tuple{BSplineSpace}","page":"B-spline space","title":"BasicBSpline.exactdim_R","text":"Exact dimension of a B-spline space.\n\nExamples\n\njulia> exactdim_R(BSplineSpace{1}(KnotVector([1,2,3,4,5,6,7])))\n5\n\njulia> exactdim_R(BSplineSpace{1}(KnotVector([1,2,4,4,4,6,7])))\n4\n\njulia> exactdim_R(BSplineSpace{1}(KnotVector([1,2,3,5,5,5,7])))\n4\n\n\n\n\n\n","category":"method"},{"location":"math-bsplinespace/","page":"B-spline space","title":"B-spline space","text":"exactdim_I(P::BSplineSpace)","category":"page"},{"location":"math-bsplinespace/#BasicBSpline.exactdim_I-Tuple{BSplineSpace}","page":"B-spline space","title":"BasicBSpline.exactdim_I","text":"Exact dimension of a B-spline space.\n\nExamples\n\njulia> exactdim_I(BSplineSpace{1}(KnotVector([1,2,3,4,5,6,7])))\n5\n\njulia> exactdim_I(BSplineSpace{1}(KnotVector([1,2,4,4,4,6,7])))\n4\n\njulia> exactdim_I(BSplineSpace{1}(KnotVector([1,2,3,5,5,5,7])))\n3\n\n\n\n\n\n","category":"method"},{"location":"math-rationalbsplinemanifold/#Rational-B-spline-manifold","page":"Rational B-spline manifold","title":"Rational B-spline manifold","text":"","category":"section"},{"location":"math-rationalbsplinemanifold/","page":"Rational B-spline manifold","title":"Rational B-spline manifold","text":"using BasicBSpline\nusing BasicBSplineExporter\nusing StaticArrays\nusing Plots; plotly()","category":"page"},{"location":"math-rationalbsplinemanifold/","page":"Rational B-spline manifold","title":"Rational B-spline manifold","text":"Non-uniform rational basis spline (NURBS) is also supported in BasicBSpline.jl package.","category":"page"},{"location":"math-rationalbsplinemanifold/#Rational-B-spline-manifold-2","page":"Rational B-spline manifold","title":"Rational B-spline manifold","text":"","category":"section"},{"location":"math-rationalbsplinemanifold/","page":"Rational B-spline manifold","title":"Rational B-spline manifold","text":"Rational B-spline manifold is a parametric representation of a shape.","category":"page"},{"location":"math-rationalbsplinemanifold/","page":"Rational B-spline manifold","title":"Rational B-spline manifold","text":"tip: Def. Rational B-spline manifold\nFor given d-dimensional B-spline basis functions B_(i^1p^1k^1) otimes cdots otimes B_(i^dp^dk^d), given points bma_i^1 dots i^d in V and real numbers w_i^1 dots i^d 0, rational B-spline manifold is defined by the following equality:bmp(t^1dotst^d bma_i^1 dots i^d w_i^1 dots i^d)\n=sum_i^1dotsi^d\nfrac(B_(i^1p^1k^1) otimes cdots otimes B_(i^dp^dk^d))(t^1dotst^d) w_i^1 dots i^d\nsumlimits_j^1dotsj^d(B_(j^1p^1k^1) otimes cdots otimes B_(j^dp^dk^d))(t^1dotst^d) w_j^1 dots j^d\nbma_i^1 dots i^dWhere bma_i^1dotsi^d are called control points, and w_i^1 dots i^d are called weights.","category":"page"},{"location":"math-rationalbsplinemanifold/","page":"Rational B-spline manifold","title":"Rational B-spline manifold","text":"RationalBSplineManifold","category":"page"},{"location":"math-rationalbsplinemanifold/#BasicBSpline.RationalBSplineManifold","page":"Rational B-spline manifold","title":"BasicBSpline.RationalBSplineManifold","text":"Construct Rational B-spline manifold from given control points, weights and B-spline spaces.\n\nExamples\n\njulia> using StaticArrays, LinearAlgebra\n\njulia> P = BSplineSpace{2}(KnotVector([0,0,0,1,1,1]))\nBSplineSpace{2, Int64, KnotVector{Int64}}(KnotVector([0, 0, 0, 1, 1, 1]))\n\njulia> w = [1, 1/√2, 1]\n3-element Vector{Float64}:\n 1.0\n 0.7071067811865475\n 1.0\n\njulia> a = [SVector(1,0), SVector(1,1), SVector(0,1)]\n3-element Vector{SVector{2, Int64}}:\n [1, 0]\n [1, 1]\n [0, 1]\n\njulia> M = RationalBSplineManifold(a,w,P); # 1/4 arc\n\n\njulia> M(0.3)\n2-element SVector{2, Float64} with indices SOneTo(2):\n 0.8973756499953727\n 0.4412674277525845\n\njulia> norm(M(0.3))\n1.0\n\n\n\n\n\n","category":"type"},{"location":"math-rationalbsplinemanifold/#Properties","page":"Rational B-spline manifold","title":"Properties","text":"","category":"section"},{"location":"math-rationalbsplinemanifold/","page":"Rational B-spline manifold","title":"Rational B-spline manifold","text":"Similar to BSplineManifold, RationalBSplineManifold supports the following methods and properties.","category":"page"},{"location":"math-rationalbsplinemanifold/","page":"Rational B-spline manifold","title":"Rational B-spline manifold","text":"currying\nrefinement\nAffine commutativity","category":"page"},{"location":"geometricmodeling/#Geometric-modeling","page":"Geometric modeling","title":"Geometric modeling","text":"","category":"section"},{"location":"geometricmodeling/#Load-packages","page":"Geometric modeling","title":"Load packages","text":"","category":"section"},{"location":"geometricmodeling/","page":"Geometric modeling","title":"Geometric modeling","text":"using BasicBSpline\nusing StaticArrays\nusing Plots\nusing LinearAlgebra\nplotly()","category":"page"},{"location":"geometricmodeling/#Arc","page":"Geometric modeling","title":"Arc","text":"","category":"section"},{"location":"geometricmodeling/","page":"Geometric modeling","title":"Geometric modeling","text":"p = 2\nk = KnotVector([0,0,0,1,1,1])\nP = BSplineSpace{p}(k)\nt = 1 # angle in radians\na = [SVector(1,0), SVector(1,tan(t/2)), SVector(cos(t),sin(t))]\nw = [1,cos(t/2),1]\nM = RationalBSplineManifold(a,w,P)\nplot(M, xlims=(0,1.1), ylims=(0,1.1), aspectratio=1)\nsavefig(\"geometricmodeling-arc.html\") # hide\nnothing # hide","category":"page"},{"location":"geometricmodeling/","page":"Geometric modeling","title":"Geometric modeling","text":"","category":"page"},{"location":"geometricmodeling/#Circle","page":"Geometric modeling","title":"Circle","text":"","category":"section"},{"location":"geometricmodeling/","page":"Geometric modeling","title":"Geometric modeling","text":"p = 2\nk = KnotVector([0,0,0,1,1,2,2,3,3,4,4,4])\nP = BSplineSpace{p}(k)\na = [\n SVector( 1, 0),\n SVector( 1, 1),\n SVector( 0, 1),\n SVector(-1, 1),\n SVector(-1, 0),\n SVector(-1,-1),\n SVector( 0,-1),\n SVector( 1,-1),\n SVector( 1, 0)\n]\nw = [1,1/√2,1,1/√2,1,1/√2,1,1/√2,1]\nM = RationalBSplineManifold(a,w,P)\nplot(M, xlims=(-1.2,1.2), ylims=(-1.2,1.2), aspectratio=1)\nsavefig(\"geometricmodeling-circle.html\") # hide\nnothing # hide","category":"page"},{"location":"geometricmodeling/","page":"Geometric modeling","title":"Geometric modeling","text":"","category":"page"},{"location":"geometricmodeling/#Torus","page":"Geometric modeling","title":"Torus","text":"","category":"section"},{"location":"geometricmodeling/","page":"Geometric modeling","title":"Geometric modeling","text":"R = 3\nr = 1\n\na0 = [\n SVector( 1, 0, 0),\n SVector( 1, 1, 0),\n SVector( 0, 1, 0),\n SVector(-1, 1, 0),\n SVector(-1, 0, 0),\n SVector(-1,-1, 0),\n SVector( 0,-1, 0),\n SVector( 1,-1, 0),\n SVector( 1, 0, 0)\n]\n\na1 = (R+r)*a0\na5 = (R-r)*a0\na2 = [p+r*SVector(0,0,1) for p in a1]\na3 = [p+r*SVector(0,0,1) for p in R*a0]\na4 = [p+r*SVector(0,0,1) for p in a5]\na6 = [p-r*SVector(0,0,1) for p in a5]\na7 = [p-r*SVector(0,0,1) for p in R*a0]\na8 = [p-r*SVector(0,0,1) for p in a1]\na9 = a1\n\na = hcat(a1,a2,a3,a4,a5,a6,a7,a8,a9)\nM = RationalBSplineManifold(a,w*w',P,P)\nplot(M)\nsavefig(\"geometricmodeling-torus.html\") # hide\nnothing # hide","category":"page"},{"location":"geometricmodeling/","page":"Geometric modeling","title":"Geometric modeling","text":"","category":"page"},{"location":"geometricmodeling/#Paraboloid","page":"Geometric modeling","title":"Paraboloid","text":"","category":"section"},{"location":"geometricmodeling/","page":"Geometric modeling","title":"Geometric modeling","text":"p = 2\nk = KnotVector([-1,-1,-1,1,1,1])\nP = BSplineSpace{p}(k)\na = [SVector(i,j,2i^2+2j^2-2) for i in -1:1, j in -1:1]\nM = BSplineManifold(a,P,P)\nplot(M)\nsavefig(\"geometricmodeling-paraboloid.html\") # hide\nnothing # hide","category":"page"},{"location":"geometricmodeling/","page":"Geometric modeling","title":"Geometric modeling","text":"","category":"page"},{"location":"geometricmodeling/#Hyperbolic-paraboloid","page":"Geometric modeling","title":"Hyperbolic paraboloid","text":"","category":"section"},{"location":"geometricmodeling/","page":"Geometric modeling","title":"Geometric modeling","text":"a = [SVector(i,j,2i^2-2j^2) for i in -1:1, j in -1:1]\nM = BSplineManifold(a,P,P)\nplot(M)\nsavefig(\"geometricmodeling-hyperbolicparaboloid.html\") # hide\nnothing # hide","category":"page"},{"location":"geometricmodeling/","page":"Geometric modeling","title":"Geometric modeling","text":"","category":"page"},{"location":"#BasicBSpline.jl","page":"Home","title":"BasicBSpline.jl","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"Basic (mathematical) operations for B-spline functions and related things with Julia.","category":"page"},{"location":"","page":"Home","title":"Home","text":"(Image: Stable) (Image: Dev) (Image: Build Status) (Image: Coverage) (Image: Aqua QA) (Image: DOI) (Image: BasicBSpline Downloads).","category":"page"},{"location":"","page":"Home","title":"Home","text":"(Image: )","category":"page"},{"location":"#Summary","page":"Home","title":"Summary","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"This package provides basic mathematical operations for B-spline.","category":"page"},{"location":"","page":"Home","title":"Home","text":"B-spline basis function\nSome operations for knot vector\nSome operations for B-spline space (piecewise polynomial space)\nB-spline manifold (includes curve, surface and solid)\nRefinement algorithm for B-spline manifold\nFitting control points for a given function","category":"page"},{"location":"#Comparison-to-other-Julia-packages-for-B-spline","page":"Home","title":"Comparison to other Julia packages for B-spline","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"There are several Julia packages for B-spline, and this package distinguishes itself with the following key benefits:","category":"page"},{"location":"","page":"Home","title":"Home","text":"Supports all degrees of polynomials.\nIncludes a refinement algorithm for B-spline manifolds.\nOffers a fitting algorithm using least squares. (BasicBSplineFitting.jl)\nDelivers high-speed performance.\nIs mathematically oriented.","category":"page"},{"location":"","page":"Home","title":"Home","text":"If you have any thoughts, please comment in:","category":"page"},{"location":"","page":"Home","title":"Home","text":"Issue#161\nDiscourse post about BasicBSpline.jl.","category":"page"},{"location":"#Installation","page":"Home","title":"Installation","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"Install this package","category":"page"},{"location":"","page":"Home","title":"Home","text":"]add BasicBSpline","category":"page"},{"location":"","page":"Home","title":"Home","text":"To export graphics, use BasicBSplineExporter.jl.","category":"page"},{"location":"","page":"Home","title":"Home","text":"]add https://github.com/hyrodium/BasicBSplineExporter.jl","category":"page"},{"location":"#Example","page":"Home","title":"Example","text":"","category":"section"},{"location":"#B-spline-function","page":"Home","title":"B-spline function","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"using BasicBSpline\nusing Plots\n\nk = KnotVector([0.0, 1.5, 2.5, 5.5, 8.0, 9.0, 9.5, 10.0])\nP0 = BSplineSpace{0}(k) # 0th degree piecewise polynomial space\nP1 = BSplineSpace{1}(k) # 1st degree piecewise polynomial space\nP2 = BSplineSpace{2}(k) # 2nd degree piecewise polynomial space\nP3 = BSplineSpace{3}(k) # 3rd degree piecewise polynomial space\nplot(\n plot([t->bsplinebasis(P0,i,t) for i in 1:dim(P0)], 0, 10, ylims=(0,1), legend=false),\n plot([t->bsplinebasis(P1,i,t) for i in 1:dim(P1)], 0, 10, ylims=(0,1), legend=false),\n plot([t->bsplinebasis(P2,i,t) for i in 1:dim(P2)], 0, 10, ylims=(0,1), legend=false),\n plot([t->bsplinebasis(P3,i,t) for i in 1:dim(P3)], 0, 10, ylims=(0,1), legend=false),\n layout=(2,2),\n)","category":"page"},{"location":"","page":"Home","title":"Home","text":"(Image: )","category":"page"},{"location":"","page":"Home","title":"Home","text":"Try an interactive graph with Desmos graphing calculator!","category":"page"},{"location":"#B-spline-manifold","page":"Home","title":"B-spline manifold","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"using BasicBSpline\nusing BasicBSplineExporter\nusing StaticArrays\n\np = 2 # degree of polynomial\nk1 = KnotVector(1:8) # knot vector\nk2 = KnotVector(rand(7))+(p+1)*KnotVector([1])\nP1 = BSplineSpace{p}(k1) # B-spline space\nP2 = BSplineSpace{p}(k2)\nn1 = dim(P1) # dimension of B-spline space\nn2 = dim(P2)\na = [SVector(2i-6.5+rand(),1.5j-6.5+rand()) for i in 1:dim(P1), j in 1:dim(P2)] # random generated control points\nM = BSplineManifold(a,(P1,P2)) # Define B-spline manifold\nsave_png(\"2dim.png\", M) # save image","category":"page"},{"location":"","page":"Home","title":"Home","text":"(Image: )","category":"page"},{"location":"#Refinement","page":"Home","title":"Refinement","text":"","category":"section"},{"location":"#h-refinement","page":"Home","title":"h-refinement","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"k₊=(KnotVector([3.3,4.2]),KnotVector([0.3,0.5])) # additional knot vectors\nM_h = refinement(M, k₊) # refinement of B-spline manifold\nsave_png(\"2dim_h-refinement.png\", M_h) # save image","category":"page"},{"location":"","page":"Home","title":"Home","text":"(Image: )","category":"page"},{"location":"","page":"Home","title":"Home","text":"Note that this shape and the last shape are equivalent.","category":"page"},{"location":"#p-refinement","page":"Home","title":"p-refinement","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"p₊=(Val(1),Val(2)) # additional degrees\nM_p = refinement(M, p₊) # refinement of B-spline manifold\nsave_png(\"2dim_p-refinement.png\", M_p) # save image","category":"page"},{"location":"","page":"Home","title":"Home","text":"(Image: )","category":"page"},{"location":"","page":"Home","title":"Home","text":"Note that this shape and the last shape are equivalent.","category":"page"},{"location":"#Fitting-B-spline-manifold","page":"Home","title":"Fitting B-spline manifold","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"Try on Desmos graphing calculator!","category":"page"},{"location":"","page":"Home","title":"Home","text":"using BasicBSplineFitting\n\np1 = 2\np2 = 2\nk1 = KnotVector(-10:10)+p1*KnotVector([-10,10])\nk2 = KnotVector(-10:10)+p2*KnotVector([-10,10])\nP1 = BSplineSpace{p1}(k1)\nP2 = BSplineSpace{p2}(k2)\n\nf(u1, u2) = SVector(2u1 + sin(u1) + cos(u2) + u2 / 2, 3u2 + sin(u2) + sin(u1) / 2 + u1^2 / 6) / 5\n\na = fittingcontrolpoints(f, (P1, P2))\nM = BSplineManifold(a, (P1, P2))\nsave_png(\"fitting.png\", M, unitlength=50, xlims=(-10,10), ylims=(-10,10))","category":"page"},{"location":"","page":"Home","title":"Home","text":"(Image: ) (Image: )","category":"page"},{"location":"","page":"Home","title":"Home","text":"If the knot vector span is too coarse, the approximation will be coarse.","category":"page"},{"location":"","page":"Home","title":"Home","text":"p1 = 2\np2 = 2\nk1 = KnotVector(-10:5:10)+p1*KnotVector([-10,10])\nk2 = KnotVector(-10:5:10)+p2*KnotVector([-10,10])\nP1 = BSplineSpace{p1}(k1)\nP2 = BSplineSpace{p2}(k2)\n\nf(u1, u2) = SVector(2u1 + sin(u1) + cos(u2) + u2 / 2, 3u2 + sin(u2) + sin(u1) / 2 + u1^2 / 6) / 5\n\na = fittingcontrolpoints(f, (P1, P2))\nM = BSplineManifold(a, (P1, P2))\nsave_png(\"fitting_coarse.png\", M, unitlength=50, xlims=(-10,10), ylims=(-10,10))","category":"page"},{"location":"","page":"Home","title":"Home","text":"(Image: )","category":"page"},{"location":"#Draw-smooth-vector-graphics","page":"Home","title":"Draw smooth vector graphics","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"p = 3\nk = KnotVector(range(-2π,2π,length=8))+p*KnotVector(-2π,2π)\nP = BSplineSpace{p}(k)\n\nf(u) = SVector(u,sin(u))\n\na = fittingcontrolpoints(f, P)\nM = BSplineManifold(a, P)\nsave_svg(\"sine-curve.svg\", M, unitlength=50, xlims=(-2,2), ylims=(-8,8))\nsave_svg(\"sine-curve_no-points.svg\", M, unitlength=50, xlims=(-2,2), ylims=(-8,8), points=false)","category":"page"},{"location":"","page":"Home","title":"Home","text":"(Image: ) (Image: )","category":"page"},{"location":"","page":"Home","title":"Home","text":"This is useful when you edit graphs (or curves) with your favorite vector graphics editor.","category":"page"},{"location":"","page":"Home","title":"Home","text":"(Image: )","category":"page"},{"location":"","page":"Home","title":"Home","text":"See Plotting smooth graphs with Julia for more tutorials.","category":"page"}]
+}
diff --git a/previews/PR343/siteinfo.js b/previews/PR343/siteinfo.js
new file mode 100644
index 000000000..925bcae20
--- /dev/null
+++ b/previews/PR343/siteinfo.js
@@ -0,0 +1 @@
+var DOCUMENTER_CURRENT_VERSION = "previews/PR343";
diff --git a/previews/PR343/subbsplineplot.html b/previews/PR343/subbsplineplot.html
new file mode 100644
index 000000000..7902aafcd
--- /dev/null
+++ b/previews/PR343/subbsplineplot.html
@@ -0,0 +1,2655 @@
+
+
diff --git a/previews/PR343/subbsplineplot2.html b/previews/PR343/subbsplineplot2.html
new file mode 100644
index 000000000..6f5f6aedb
--- /dev/null
+++ b/previews/PR343/subbsplineplot2.html
@@ -0,0 +1,1244 @@
+
+
diff --git a/previews/PR343/sumofbsplineplot.html b/previews/PR343/sumofbsplineplot.html
new file mode 100644
index 000000000..528003253
--- /dev/null
+++ b/previews/PR343/sumofbsplineplot.html
@@ -0,0 +1,467 @@
+
+
diff --git a/previews/PR343/sumofbsplineplot2.html b/previews/PR343/sumofbsplineplot2.html
new file mode 100644
index 000000000..603553707
--- /dev/null
+++ b/previews/PR343/sumofbsplineplot2.html
@@ -0,0 +1,235 @@
+
+
diff --git a/previews/PR343/sumofbsplineplot3.html b/previews/PR343/sumofbsplineplot3.html
new file mode 100644
index 000000000..7c4d43b58
--- /dev/null
+++ b/previews/PR343/sumofbsplineplot3.html
@@ -0,0 +1,1871 @@
+
+