Surfaces
Surfaces can be refined, splitted, knots can be removed, and the degree can be manipulated.
Refining a Surface
Based on the principles of knot insertion, several knots can be inserted into a surface (without changing the points the surface describes) by the refine
function.
BSurfaceRef = refine(BSurface; U=[0.5, 0.5, 0.72], V=[0.2, 0.42])
plotPatches([BSurfaceRef], enforceRatio=false, plotControlPoints=true)
Refining a surface does not change the points in space described by the surface. Effectively, in the plots it can be seen that the number of control points is increased. However, also underlying properties such as the differentiability are changed.
Splitting a Surface
To split a surface into multiple separate surfaces the function split
is provided which returns an array of surfaces.
sVec = split(BSurface, U=[0.5,0.75], V=[0.6])
plotPatches(sVec, enforceRatio=false, plotControlPoints=false)
To equally split a surface into $n$ times $m$ surfaces as second and third argument an integer can be provided:
sVec = split(BSurface, 3, 2) # split into 3 x 2 surfaces
6-element Vector{BsplineSurface{Float64}}:
BsplineSurface{Float64}(Bspline{Float64}(2, [0.0, 0.0, 0.0, 0.6000000000000001, 1.0, 1.0, 1.0]), Bspline{Float64}(2, [0.0, 0.0, 0.0, 0.4, 0.8, 1.0, 1.0, 1.0]), StaticArraysCore.SVector{3, Float64}[[0.0, 0.0, 3.0] [0.0, 1.0, 3.0] … [0.0, 2.75, 2.0] [0.0, 3.0, 2.0]; [1.0, 0.0, 3.0] [1.0, 1.0, 3.0] … [1.0, 2.75, 2.0] [1.0, 3.0, 2.0]; [1.8333333333333333, 0.0, 2.166666666666667] [1.8333333333333333, 1.0, 2.166666666666667] … [1.8333333333333333, 2.75, 1.1666666666666667] [1.8333333333333333, 3.0, 1.1666666666666665]; [2.166666666666666, 0.0, 2.055555555555556] [2.166666666666666, 1.0, 2.055555555555556] … [2.166666666666666, 2.75, 1.0555555555555556] [2.166666666666666, 3.0, 1.0555555555555556]])
BsplineSurface{Float64}(Bspline{Float64}(2, [0.0, 0.0, 0.0, 0.6000000000000001, 1.0, 1.0, 1.0]), Bspline{Float64}(2, [0.0, 0.0, 0.0, 0.19999999999999996, 0.6000000000000001, 1.0, 1.0, 1.0]), StaticArraysCore.SVector{3, Float64}[[0.0, 3.0, 2.0] [0.0, 3.25, 2.0] … [0.0, 5.0, 2.0] [0.0, 6.0, 2.0]; [1.0, 3.0, 2.0] [1.0, 3.25, 2.0] … [1.0, 5.0, 2.0] [1.0, 6.0, 2.0]; [1.8333333333333333, 3.0, 1.1666666666666665] [1.8333333333333333, 3.25, 1.1666666666666665] … [1.8333333333333333, 5.0, 1.1666666666666667] [1.8333333333333333, 6.0, 1.1666666666666667]; [2.166666666666666, 3.0, 1.0555555555555556] [2.166666666666666, 3.25, 1.0555555555555556] … [2.166666666666666, 5.0, 0.8333333333333335] [2.166666666666666, 6.222222222222222, 0.8333333333333335]])
BsplineSurface{Float64}(Bspline{Float64}(2, [0.0, 0.0, 0.0, 0.20000000000000012, 0.8, 1.0, 1.0, 1.0]), Bspline{Float64}(2, [0.0, 0.0, 0.0, 0.4, 0.8, 1.0, 1.0, 1.0]), StaticArraysCore.SVector{3, Float64}[[2.166666666666666, 0.0, 2.055555555555556] [2.166666666666666, 1.0, 2.055555555555556] … [2.166666666666666, 2.75, 1.0555555555555556] [2.166666666666666, 3.0, 1.0555555555555556]; [2.333333333333333, 0.0, 2.0] [2.333333333333333, 1.0, 2.0] … [2.333333333333333, 2.75, 1.0] [2.333333333333333, 3.0, 1.0]; … ; [3.6666666666666665, 0.0, 1.3333333333333335] [3.6666666666666665, 1.0, 1.3333333333333335] … [3.6666666666666665, 2.75, 0.3333333333333335] [3.6666666666666665, 3.0, 0.41666666666666674]; [3.833333333333333, 0.0, 1.2222222222222223] [3.833333333333333, 1.0, 1.2222222222222223] … [3.833333333333333, 2.75, 0.22222222222222238] [3.833333333333333, 3.0, 0.3125000000000001]])
BsplineSurface{Float64}(Bspline{Float64}(2, [0.0, 0.0, 0.0, 0.20000000000000012, 0.8, 1.0, 1.0, 1.0]), Bspline{Float64}(2, [0.0, 0.0, 0.0, 0.19999999999999996, 0.6000000000000001, 1.0, 1.0, 1.0]), StaticArraysCore.SVector{3, Float64}[[2.166666666666666, 3.0, 1.0555555555555556] [2.166666666666666, 3.25, 1.0555555555555556] … [2.166666666666666, 5.0, 0.8333333333333335] [2.166666666666666, 6.222222222222222, 0.8333333333333335]; [2.333333333333333, 3.0, 1.0] [2.333333333333333, 3.25, 1.0] … [2.333333333333333, 5.0, 0.6666666666666667] [2.333333333333333, 6.333333333333333, 0.6666666666666667]; … ; [3.6666666666666665, 3.0, 0.41666666666666674] [3.6666666666666665, 3.25, 0.5] … [3.6666666666666665, 5.0, 0.0] [3.6666666666666665, 6.333333333333334, 0.0]; [3.833333333333333, 3.0, 0.3125000000000001] [3.833333333333333, 3.25, 0.40277777777777785] … [3.833333333333333, 5.0, 0.0] [3.833333333333333, 6.222222222222223, 0.0]])
BsplineSurface{Float64}(Bspline{Float64}(2, [0.0, 0.0, 0.0, 0.4000000000000002, 1.0, 1.0, 1.0]), Bspline{Float64}(2, [0.0, 0.0, 0.0, 0.4, 0.8, 1.0, 1.0, 1.0]), StaticArraysCore.SVector{3, Float64}[[3.833333333333333, 0.0, 1.2222222222222223] [3.833333333333333, 1.0, 1.2222222222222223] … [3.833333333333333, 2.75, 0.22222222222222238] [3.833333333333333, 3.0, 0.3125000000000001]; [4.166666666666667, 0.0, 1.0] [4.166666666666667, 1.0, 1.0] … [4.166666666666667, 2.75, 0.0] [4.166666666666666, 3.0, 0.10416666666666664]; [5.0, 0.0, 1.0] [5.0, 1.0, 1.0] … [5.0, 2.75, 0.0] [5.0, 3.0, 0.0]; [6.0, 0.0, 1.0] [6.0, 1.0, 1.0] … [6.0, 2.75, 0.0] [6.0, 3.0, 0.0]])
BsplineSurface{Float64}(Bspline{Float64}(2, [0.0, 0.0, 0.0, 0.4000000000000002, 1.0, 1.0, 1.0]), Bspline{Float64}(2, [0.0, 0.0, 0.0, 0.19999999999999996, 0.6000000000000001, 1.0, 1.0, 1.0]), StaticArraysCore.SVector{3, Float64}[[3.833333333333333, 3.0, 0.3125000000000001] [3.833333333333333, 3.25, 0.40277777777777785] … [3.833333333333333, 5.0, 0.0] [3.833333333333333, 6.222222222222223, 0.0]; [4.166666666666666, 3.0, 0.10416666666666664] [4.166666666666666, 3.25, 0.2083333333333333] … [4.166666666666667, 5.0, 0.0] [4.166666666666667, 6.0, 0.0]; [5.0, 3.0, 0.0] [5.0, 3.25, 0.0] … [5.0, 5.0, 0.0] [5.0, 6.0, 0.0]; [6.0, 3.0, 0.0] [6.0, 3.25, 0.0] … [6.0, 5.0, 0.0] [6.0, 6.0, 0.0]])
Removing Knots from a Surface
Based on the principles of knot removal, an interior knot can potentially be removed multiple times from a surface (without changing the points the surface describes) by the removeKnotU
and the removeKnotV
functions.
# --- surface with removable knots
p = 3
kVec = Float64[0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2]
P1 = SVector(0.0, 0.0, 0.0)
P2 = SVector(0.0, 2.0, 0.0)
P3 = SVector(1.5, 3.0, 0.0)
P4 = SVector(3.0, 3.0, 0.0)
P5 = SVector(4.5, 3.0, 0.0)
P6 = SVector(6.0, 2.0, 0.0)
P7 = SVector(6.0, 0.0, 0.0)
cP = [P1 , P2 , P3 , P4 , P5 , P6 , P7 ]
P1 = SVector(0.0, 0.0, 2.0)
P2 = SVector(0.0, 2.0, 2.0)
P3 = SVector(1.5, 3.0, 2.0)
P4 = SVector(3.0, 3.0, 2.0)
P5 = SVector(4.5, 3.0, 2.0)
P6 = SVector(6.0, 2.0, 2.0)
P7 = SVector(6.0, 0.0, 2.0)
cP2 = [P1 , P2 , P3 , P4 , P5 , P6 , P7 ]
controlPoints = [[cP, cP2][j][i] for i in 1:7, j in 1:2]
BS1 = BsplineSurface(Bspline(p, kVec), Bspline(1, [0.0,0.0,1.0,1.0]), controlPoints)
# --- remove knot
BS2 = removeKnotU(BS1, 0.5, 1) # remove knot once
# --- plot before and after
t1 = plotPatches([BS1], enforceRatio=true, plotControlPoints=true)
t2 = plotPatches([BS2], enforceRatio=true, plotControlPoints=true)
uEval = vEval = collect(0:0.005:1.0)
S1 = BS1(uEval, vEval)
S2 = BS2(uEval, vEval)
x, t1 = plotSurface(S1, controlPoints=BS1.controlPoints, returnTrace=true)
x, t2 = plotSurface(S2, controlPoints=BS2.controlPoints, returnTrace=true)
fig = make_subplots(
rows=1, cols=2,
specs=fill(Spec(kind="scene"), 1, 2)
)
for i in eachindex(t1)
add_trace!(fig, t1[i], row=1, col=1)
end
for i in eachindex(t2)
add_trace!(fig, t2[i], row=1, col=2)
end
fig
[ Info: The knot vector is being modified (normalized).
Removing a knot from a surface is only possible when the continuity of the surface is sufficient at the knot. A central part of the removeKnot functions is to verify if the knot can actually be removed. If not, warnings are generated, indicating the encountered limitations.
Degree Manipulation
To be done.