Skip to content

Commit 28ca52d

Browse files
authored
Bottom top fixes (#1332)
* Fixes to botom and top of Cylinder * Fix Chain parametrization
1 parent 203ab19 commit 28ca52d

File tree

5 files changed

+49
-38
lines changed

5 files changed

+49
-38
lines changed

src/boundary.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ boundary(::Circle) = nothing
122122

123123
embedboundary(c::Circle) = c
124124

125-
boundary(c::Cylinder) = CylinderSurface(bottom(c), top(c), radius(c))
125+
boundary(c::Cylinder) = CylinderSurface(plane(bottom(c)), plane(top(c)), radius(c))
126126

127127
embedboundary(c::Cylinder) = boundary(c)
128128

src/geometries/polytopes.jl

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -157,20 +157,22 @@ function angles(c::Chain)
157157
end
158158

159159
function (c::Chain)(t)
160-
if t < 0 || t > 1
161-
throw(DomainError(t, "c(t) is not defined for t outside [0, 1]."))
162-
end
163160
segs = segments(c)
164161
sums = cumsum(measure.(segs))
165162
sums /= last(sums)
166-
# find k such that sums[k] ≤ t < sums[k + 1]
167-
k = searchsortedfirst(sums, t) - 1
168-
# select segment s at index k
169-
s, _ = iterate(segs, k)
163+
# find first k such that t ≤ sums[k]
164+
k = searchsortedfirst(sums, clamp(t, zero(t), one(t)))
170165
# reparametrization of t within s
171-
∑ₖ = iszero(k) ? zero(eltype(sums)) : sums[k]
172-
∑ₖ₊₁ = sums[k + 1]
173-
s((t - ∑ₖ) / (∑ₖ₊₁ - ∑ₖ))
166+
if isone(k)
167+
s = first(segs)
168+
Σₖ = sums[k]
169+
s(t / Σₖ)
170+
else
171+
s = first(Iterators.drop(segs, k - 1))
172+
Σₖ = sums[k]
173+
Σₖ₋₁ = sums[k - 1]
174+
s((t - Σₖ₋₁) / (Σₖ - Σₖ₋₁))
175+
end
174176
end
175177

176178
# implementations of Chain

src/geometries/primitives/cylinder.jl

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,13 @@ end
5656

5757
paramdim(::Type{<:Cylinder}) = 3
5858

59-
bottom(c::Cylinder) = c.bot
59+
bottom(c::Cylinder) = Disk(c.bot, bottomradius(c))
6060

61-
top(c::Cylinder) = c.top
61+
top(c::Cylinder) = Disk(c.top, topradius(c))
62+
63+
bottomradius(c::Cylinder) = norm(c(1, 0, 0) - c(0, 0, 0))
64+
65+
topradius(c::Cylinder) = norm(c(1, 0, 1) - c(0, 0, 1))
6266

6367
radius(c::Cylinder) = c.radius
6468

@@ -76,10 +80,12 @@ Base.isapprox(c₁::Cylinder, c₂::Cylinder; atol=atol(lentype(c₁)), kwargs..
7680
function (c::Cylinder)(ρ, φ, z)
7781
= lentype(c)
7882
T = numtype(ℒ)
79-
t = top(c)
80-
b = bottom(c)
81-
r = radius(c)
82-
a = axis(c)
83+
C = crs(c)
84+
D = datum(C)
85+
b = c.bot
86+
t = c.top
87+
r = c.radius
88+
a = Line(b(0, 0), t(0, 0))
8389
d = a(T(1)) - a(T(0))
8490

8591
# rotation to align z axis with cylinder axis
@@ -91,8 +97,8 @@ function (c::Cylinder)(ρ, φ, z)
9197
# project a parametric segment between the top and bottom planes
9298
ρ′ = T(ρ) * r
9399
φ′ = T(φ) * 2 * T(π) * u"rad"
94-
p₁ = Point(convert(crs(c), Cylindrical(ρ′, φ′, zero(ℒ))))
95-
p₂ = Point(convert(crs(c), Cylindrical(ρ′, φ′, norm(d))))
100+
p₁ = Point(convert(C, Cylindrical{D}(ρ′, φ′, zero(ℒ))))
101+
p₂ = Point(convert(C, Cylindrical{D}(ρ′, φ′, norm(d))))
96102
l = Line(p₁, p₂) |> Affine(R, o)
97103
s = Segment(l b, l t)
98104
s(T(z))

src/geometries/primitives/cylindersurface.jl

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -56,35 +56,38 @@ end
5656

5757
paramdim(::Type{<:CylinderSurface}) = 2
5858

59-
bottom(c::CylinderSurface) = c.bot
59+
bottom(c::CylinderSurface) = Disk(c.bot, bottomradius(c))
6060

61-
top(c::CylinderSurface) = c.top
61+
top(c::CylinderSurface) = Disk(c.top, topradius(c))
62+
63+
bottomradius(c::CylinderSurface) = bottomradius(Cylinder(c.bot, c.top, c.radius))
64+
65+
topradius(c::CylinderSurface) = topradius(Cylinder(c.bot, c.top, c.radius))
6266

6367
radius(c::CylinderSurface) = c.radius
6468

65-
axis(c::CylinderSurface) = Line(bottom(c)(0, 0), top(c)(0, 0))
69+
axis(c::CylinderSurface) = Line(c.bot(0, 0), c.top(0, 0))
6670

6771
# cylinder is right if axis is aligned with plane normals
6872
function isright(c::CylinderSurface)
6973
T = numtype(lentype(c))
7074
a = axis(c)
7175
d = a(T(1)) - a(T(0))
72-
u = normal(bottom(c))
73-
v = normal(top(c))
76+
u = normal(c.bot)
77+
v = normal(c.top)
7478
isapproxzero(norm(d × u)) && isapproxzero(norm(d × v))
7579
end
7680

7781
function hasintersectingplanes(c::CylinderSurface)
78-
l = bottom(c) top(c)
79-
!isnothing(l) && evaluate(Euclidean(), axis(c), l) < radius(c)
82+
l = c.bot c.top
83+
!isnothing(l) && evaluate(Euclidean(), axis(c), l) < c.radius
8084
end
8185

82-
==(c₁::CylinderSurface, c₂::CylinderSurface) =
83-
bottom(c₁) == bottom(c₂) && top(c₁) == top(c₂) && radius(c₁) == radius(c₂)
86+
==(c₁::CylinderSurface, c₂::CylinderSurface) = c₁.bot == c₂.bot && c₁.top == c₂.top && c₁.radius == c₂.radius
8487

8588
Base.isapprox(c₁::CylinderSurface, c₂::CylinderSurface; atol=atol(lentype(c₁)), kwargs...) =
86-
isapprox(bottom(c₁), bottom(c₂); atol, kwargs...) &&
87-
isapprox(top(c₁), top(c₂); atol, kwargs...) &&
88-
isapprox(radius(c₁), radius(c₂); atol, kwargs...)
89+
isapprox(c₁.bot, c₂.bot; atol, kwargs...) &&
90+
isapprox(c₁.top, c₂.top; atol, kwargs...) &&
91+
isapprox(c₁.radius, c₂.radius; atol, kwargs...)
8992

90-
(c::CylinderSurface)(φ, z) = Cylinder(bottom(c), top(c), radius(c))(1, φ, z)
93+
(c::CylinderSurface)(φ, z) = Cylinder(c.bot, c.top, c.radius)(1, φ, z)

test/primitives.jl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -863,8 +863,8 @@ end
863863
@test crs(c) <: Cartesian{NoDatum}
864864
@test Meshes.lentype(c) ==
865865
@test radius(c) == T(5) * u"m"
866-
@test bottom(c) == Plane(cart(1, 2, 3), vector(0, 0, 1))
867-
@test top(c) == Plane(cart(4, 5, 6), vector(0, 0, 1))
866+
@test bottom(c) == Disk(Plane(cart(1, 2, 3), vector(0, 0, 1)), Meshes.bottomradius(c))
867+
@test top(c) == Disk(Plane(cart(4, 5, 6), vector(0, 0, 1)), Meshes.topradius(c))
868868
@test axis(c) == Line(cart(1, 2, 3), cart(4, 5, 6))
869869
@test !isright(c)
870870
@test measure(c) == volume(c) T(5)^2 * pi * T(3) * sqrt(T(3)) * u"m^3"
@@ -897,8 +897,8 @@ end
897897

898898
c = Cylinder(cart(0, 0, 0), cart(0, 0, 1), T(1))
899899
@test radius(c) == T(1) * u"m"
900-
@test bottom(c) == Plane(cart(0, 0, 0), vector(0, 0, 1))
901-
@test top(c) == Plane(cart(0, 0, 1), vector(0, 0, 1))
900+
@test bottom(c) == Disk(Plane(cart(0, 0, 0), vector(0, 0, 1)), T(1))
901+
@test top(c) == Disk(Plane(cart(0, 0, 1), vector(0, 0, 1)), T(1))
902902
@test centroid(c) == cart(0.0, 0.0, 0.5)
903903
@test axis(c) == Line(cart(0, 0, 0), cart(0, 0, 1))
904904
@test isright(c)
@@ -943,8 +943,8 @@ end
943943
@test crs(c) <: Cartesian{NoDatum}
944944
@test Meshes.lentype(c) ==
945945
@test radius(c) == T(2) * u"m"
946-
@test bottom(c) == Plane(cart(0, 0, 0), vector(0, 0, 1))
947-
@test top(c) == Plane(cart(0, 0, 1), vector(0, 0, 1))
946+
@test bottom(c) == Disk(Plane(cart(0, 0, 0), vector(0, 0, 1)), T(2))
947+
@test top(c) == Disk(Plane(cart(0, 0, 1), vector(0, 0, 1)), T(2))
948948
@test centroid(c) == cart(0.0, 0.0, 0.5)
949949
@test axis(c) == Line(cart(0, 0, 0), cart(0, 0, 1))
950950
@test isright(c)

0 commit comments

Comments
 (0)