From bbd8540bfb5ff5fcbe02d4a08c33c3b27fca78c1 Mon Sep 17 00:00:00 2001 From: Yuto Horikawa Date: Fri, 9 Feb 2024 01:26:01 +0900 Subject: [PATCH] Update docs (#378) * update geometric modeling * update * update * update * update * update docs around bsplinemanifold * fix typo --- docs/src/api.md | 2 + docs/src/geometricmodeling.md | 68 +++++++++++--------------------- docs/src/math/bsplinebasis.md | 25 ++++++------ docs/src/math/bsplinemanifold.md | 25 ++++++------ 4 files changed, 53 insertions(+), 67 deletions(-) diff --git a/docs/src/api.md b/docs/src/api.md index 8f6a5820b..401eaf7ef 100644 --- a/docs/src/api.md +++ b/docs/src/api.md @@ -27,6 +27,8 @@ exactdim_I(P::BSplineSpace) BSplineSpace isnondegenerate isdegenerate(P::BSplineSpace) +BSplineManifold +unbounded_mapping ``` ```@docs diff --git a/docs/src/geometricmodeling.md b/docs/src/geometricmodeling.md index 4881393d4..afe52b78e 100644 --- a/docs/src/geometricmodeling.md +++ b/docs/src/geometricmodeling.md @@ -1,13 +1,13 @@ # Geometric modeling -## Load packages +## Setup ```@example geometricmodeling using BasicBSpline using StaticArrays using Plots using LinearAlgebra -plotly() +gr() ``` ## Arc @@ -20,69 +20,45 @@ a = [SVector(1,0), SVector(1,tan(t/2)), SVector(cos(t),sin(t))] w = [1,cos(t/2),1] M = RationalBSplineManifold(a,w,P) plot(M, xlims=(0,1.1), ylims=(0,1.1), aspectratio=1) -savefig("geometricmodeling-arc.html") # hide +savefig("geometricmodeling-arc.png") # hide nothing # hide ``` -```@raw html - -``` +![](geometricmodeling-arc.png) ## Circle ```@example geometricmodeling p = 2 k = KnotVector([0,0,0,1,1,2,2,3,3,4,4,4]) P = BSplineSpace{p}(k) -a = [ - SVector( 1, 0), - SVector( 1, 1), - SVector( 0, 1), - SVector(-1, 1), - SVector(-1, 0), - SVector(-1,-1), - SVector( 0,-1), - SVector( 1,-1), - SVector( 1, 0) -] -w = [1,1/√2,1,1/√2,1,1/√2,1,1/√2,1] +a = [normalize(SVector(cosd(t), sind(t)), Inf) for t in 0:45:360] +w = [ifelse(isodd(i), √2, 1) for i in 1:9] M = RationalBSplineManifold(a,w,P) plot(M, xlims=(-1.2,1.2), ylims=(-1.2,1.2), aspectratio=1) -savefig("geometricmodeling-circle.html") # hide +savefig("geometricmodeling-circle.png") # hide nothing # hide ``` -```@raw html - -``` +![](geometricmodeling-circle.png) ## Torus ```@example geometricmodeling -R = 3 -r = 1 +plotly() +R1 = 3 +R2 = 1 -a0 = [ - SVector( 1, 0, 0), - SVector( 1, 1, 0), - SVector( 0, 1, 0), - SVector(-1, 1, 0), - SVector(-1, 0, 0), - SVector(-1,-1, 0), - SVector( 0,-1, 0), - SVector( 1,-1, 0), - SVector( 1, 0, 0) -] +A = push.(a, 0) -a1 = (R+r)*a0 -a5 = (R-r)*a0 -a2 = [p+r*SVector(0,0,1) for p in a1] -a3 = [p+r*SVector(0,0,1) for p in R*a0] -a4 = [p+r*SVector(0,0,1) for p in a5] -a6 = [p-r*SVector(0,0,1) for p in a5] -a7 = [p-r*SVector(0,0,1) for p in R*a0] -a8 = [p-r*SVector(0,0,1) for p in a1] -a9 = a1 +a1 = (R1+R2)*A +a5 = (R1-R2)*A +a2 = [p+R2*SVector(0,0,1) for p in a1] +a3 = [p+R2*SVector(0,0,1) for p in R1*A] +a4 = [p+R2*SVector(0,0,1) for p in a5] +a6 = [p-R2*SVector(0,0,1) for p in a5] +a7 = [p-R2*SVector(0,0,1) for p in R1*A] +a8 = [p-R2*SVector(0,0,1) for p in a1] -a = hcat(a1,a2,a3,a4,a5,a6,a7,a8,a9) +a = hcat(a1,a2,a3,a4,a5,a6,a7,a8,a1) M = RationalBSplineManifold(a,w*w',P,P) plot(M) savefig("geometricmodeling-torus.html") # hide @@ -95,6 +71,7 @@ nothing # hide ## Paraboloid ```@example geometricmodeling +plotly() p = 2 k = KnotVector([-1,-1,-1,1,1,1]) P = BSplineSpace{p}(k) @@ -111,6 +88,7 @@ nothing # hide ## Hyperbolic paraboloid ```@example geometricmodeling +plotly() a = [SVector(i,j,2i^2-2j^2) for i in -1:1, j in -1:1] M = BSplineManifold(a,P,P) plot(M) diff --git a/docs/src/math/bsplinebasis.md b/docs/src/math/bsplinebasis.md index c7ef96952..d910773d0 100644 --- a/docs/src/math/bsplinebasis.md +++ b/docs/src/math/bsplinebasis.md @@ -38,7 +38,7 @@ You can manipulate these plots on [desmos graphing calculator](https://www.desmo These B-spline basis functions can be calculated with [`bsplinebasis₊₀`](@ref). -```@repl math_bsplinebasis +```@example math_bsplinebasis p = 2 k = KnotVector([0.0, 1.5, 2.5, 5.5, 8.0, 9.0, 9.5, 10.0]) P = BSplineSpace{p}(k) @@ -62,7 +62,7 @@ The first terms can be defined in different ways ([`bsplinebasis₋₀`](@ref)). \end{aligned} ``` -```@repl math_bsplinebasis +```@example math_bsplinebasis p = 2 k = KnotVector([0.0, 1.5, 2.5, 5.5, 8.0, 9.0, 9.5, 10.0]) P = BSplineSpace{p}(k) @@ -94,11 +94,12 @@ In these cases, each B-spline basis function ``B_{(i,2,k)}`` is coninuous, so [` \end{aligned} ``` -```@repl math_bsplinebasis +```@example math_bsplinebasis p = 2 k = KnotVector([0.0, 1.5, 2.5, 5.5, 8.0, 9.0, 9.5, 10.0]) P = BSplineSpace{p}(k) -plot(t->sum(bsplinebasis₊₀(P,i,t) for i in 1:dim(P)), 0, 10, ylims=(0,1.1), label=false) +plot(t->sum(bsplinebasis₊₀(P,i,t) for i in 1:dim(P)), 0, 10, ylims=(-0.1, 1.1), label="sum of bspline basis functions") +plot!(k, label="knot vector", legend=:inside) savefig("sumofbsplineplot.png") # hide nothing # hide ``` @@ -107,11 +108,12 @@ nothing # hide To satisfy the partition of unity on whole interval ``[0,10]``, sometimes more knots will be inserted to the endpoints of the interval. -```@repl math_bsplinebasis +```@example math_bsplinebasis p = 2 k = KnotVector([0.0, 1.5, 2.5, 5.5, 8.0, 9.0, 9.5, 10.0]) + p * KnotVector([0,10]) P = BSplineSpace{p}(k) -plot(t->sum(bsplinebasis₊₀(P,i,t) for i in 1:dim(P)), 0, 10, ylims=(0,1.1), label=false) +plot(t->sum(bsplinebasis₊₀(P,i,t) for i in 1:dim(P)), 0, 10, ylims=(-0.1, 1.1), label="sum of bspline basis functions") +plot!(k, label="knot vector", legend=:inside) savefig("sumofbsplineplot2.png") # hide nothing # hide ``` @@ -133,11 +135,12 @@ Therefore, to satisfy partition of unity on closed interval ``[k_{p+1}, k_{l-p}] \end{aligned} ``` -```@repl math_bsplinebasis +```@example math_bsplinebasis p = 2 k = KnotVector([0.0, 1.5, 2.5, 5.5, 8.0, 9.0, 9.5, 10.0]) + p * KnotVector([0,10]) P = BSplineSpace{p}(k) -plot(t->sum(bsplinebasis(P,i,t) for i in 1:dim(P)), 0, 10, ylims=(0,1.1), label=false) +plot(t->sum(bsplinebasis(P,i,t) for i in 1:dim(P)), 0, 10, ylims=(-0.1, 1.1), label="sum of bspline basis functions") +plot!(k, label="knot vector", legend=:inside) savefig("sumofbsplineplot3.png") # hide nothing # hide ``` @@ -215,8 +218,8 @@ The [`bsplinebasisall`](@ref) function is much more efficient than evaluating B- P = BSplineSpace{2}(KnotVector([0.0, 1.5, 2.5, 5.5, 8.0, 9.0, 9.5, 10.0])) t = 6.3 plot(P; label="P", ylims=(0,1)) -scatter!(fill(t,3), [bsplinebasis(P,2,t), bsplinebasis(P,3,t), bsplinebasis(P,4,t)]; markershape=:hline, label="bsplinebasis") -scatter!(fill(t,3), bsplinebasisall(P, 2, t); markershape=:vline, label="bsplinebasisall") +scatter!(fill(t,3), [bsplinebasis(P,2,t), bsplinebasis(P,3,t), bsplinebasis(P,4,t)]; markershape=:circle, markersize=10, label="bsplinebasis") +scatter!(fill(t,3), bsplinebasisall(P, 2, t); markershape=:star7, markersize=10, label="bsplinebasisall") savefig("bsplinebasis_vs_bsplinebasisall.png") # hide nothing # hide ``` @@ -247,7 +250,7 @@ for p in 1:3 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") - plot!(k, label="knot vector") + plot!(k, label="knot vector", legend=:inside) 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)) savefig("bsplinebasisall-$(p).html") # hide nothing # hide diff --git a/docs/src/math/bsplinemanifold.md b/docs/src/math/bsplinemanifold.md index f8339e2ce..e657bf3db 100644 --- a/docs/src/math/bsplinemanifold.md +++ b/docs/src/math/bsplinemanifold.md @@ -4,6 +4,7 @@ ```@example math_bsplinemanifold using BasicBSpline using StaticArrays +using StaticArrays using Plots; plotly() ``` @@ -24,10 +25,6 @@ using Plots; plotly() The next plot shows ``B_{(3,p^1,k^1)} \otimes B_{(4,p^2,k^2)}`` basis function. ```@example math_bsplinemanifold -using BasicBSpline -using Plots -plotly() - # Define shape k1 = KnotVector([0.0, 1.5, 2.5, 5.5, 8.0, 9.0, 9.5, 10.0]) k2 = knotvector"31 2 121" @@ -60,7 +57,7 @@ Higher dimensional tensor products ``\mathcal{P}[p^1,k^1]\otimes\cdots\otimes\ma B-spline manifold is a parametric representation of a shape. !!! tip "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: + 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 parametrization: ```math \bm{p}(t^1,\dots,t^d;\bm{a}_{i^1 \dots i^d}) =\sum_{i^1,\dots,i^d}(B_{(i^1,p^1,k^1)} \otimes \cdots \otimes B_{(i^d,p^d,k^d)})(t^1,\dots,t^d) \bm{a}_{i^1 \dots i^d} @@ -69,16 +66,22 @@ B-spline manifold is a parametric representation of a shape. We will also write ``\bm{p}(t^1,\dots,t^d; \bm{a})``, ``\bm{p}(t^1,\dots,t^d)``, ``\bm{p}(t; \bm{a})`` or ``\bm{p}(t)`` for simplicity. -Note that the `BSplineManifold` objects are callable, and the arguments will be checked if it fits in the domain of `BSplineSpace`. +Note that the [`BSplineManifold`](@ref) objects are callable, and the arguments will be checked if it fits in the domain of [`BSplineSpace`](@ref). -```@docs -BSplineManifold +```@example math_bsplinemanifold +P = BSplineSpace{2}(KnotVector([0,0,0,1,1,1])) +a = [SVector(1,0), SVector(1,1), SVector(0,1)] # `length(a) == dim(P)` +M = BSplineManifold(a, P) +M(0.4) # Calculate `sum(a[i]*bsplinebasis(P, i, 0.4) for i in 1:dim(P))` ``` -If you need extension of `BSplineManifold` or don't need the arguments check, you can call `unbounded_mapping`. +If you need extension of [`BSplineManifold`](@ref) or don't need the arguments check, you can call [`unbounded_mapping`](@ref). -```@docs -unbounded_mapping +```@repl math_bsplinemanifold +M(0.4) +unbounded_mapping(M, 0.4) +M(1.2) +unbounded_mapping(M, 1.2) ``` `unbounded_mapping(M,t...)` is a little bit faster than `M(t...)` because it does not check the domain.