Skip to content

Commit 46ee50e

Browse files
JoshuaLampertgithub-actions[bot]juliohm
authored
Add parametric function for Chain (#1155)
* add parametric function for Chain * add tests * Apply suggestions from code review Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * reduce allocations * Update src/geometries/polytopes.jl Co-authored-by: Júlio Hoffimann <[email protected]> * fix * use measure * Apply suggestions from code review Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Fix type instabilities * add tests for Cartesian coords * Apply suggestions from code review Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * remove approximate latlon tests * Adjust tests --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Júlio Hoffimann <[email protected]>
1 parent 16383a9 commit 46ee50e

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed

src/geometries/polytopes.jl

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
We say that a geometry is a K-polytope when it is a collection of "flat" sides
99
that constitute a `K`-dimensional subspace. They are called chain, polygon and
1010
polyhedron respectively for 1D (`K=1`), 2D (`K=2`) and 3D (`K=3`) subspaces.
11-
The parameter `K` is also known as the rank or parametric dimension
11+
The parameter `K` is also known as the rank or parametric dimension
1212
of the polytope (<https://en.wikipedia.org/wiki/Abstract_polytope>).
1313
1414
The term polytope expresses a particular combinatorial structure. A polyhedron,
@@ -156,6 +156,23 @@ function angles(c::Chain)
156156
map(i -> (vs[i - 1], vs[i], vs[i + 1]), i1:i2)
157157
end
158158

159+
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
163+
segs = segments(c)
164+
sums = cumsum(measure.(segs))
165+
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)
170+
# reparametrization of t within s
171+
∑ₖ = iszero(k) ? zero(eltype(sums)) : sums[k]
172+
∑ₖ₊₁ = sums[k + 1]
173+
s((t - ∑ₖ) / (∑ₖ₊₁ - ∑ₖ))
174+
end
175+
159176
# implementations of Chain
160177
include("polytopes/segment.jl")
161178
include("polytopes/rope.jl")

test/polytopes.jl

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,25 @@ end
264264
r = Ring(merc.([(0, 0), (1, 0), (1, 1), (0, 1)]))
265265
@test crs(centroid(r)) === crs(r)
266266

267+
# parameterization
268+
r = boundary(Box(cart(0, 0), cart(1, 1)))
269+
@test r(T(0)) == cart(0, 0)
270+
@test r(T(0.25)) == cart(1, 0)
271+
@test r(T(0.5)) == cart(1, 1)
272+
@test r(T(0.75)) == cart(0, 1)
273+
r = Rope(cart(0, 0), cart(3, 0), cart(4, 0))
274+
@test r(T(0)) == cart(0, 0)
275+
@test r(T(0.25)) == cart(1, 0)
276+
@test r(T(0.5)) == cart(2, 0)
277+
@test r(T(0.75)) == cart(3, 0)
278+
@test r(T(1)) == cart(4, 0)
279+
r = Ring(latlon(45, 0), latlon(45, 90), latlon(90, 90))
280+
@test r(T(0)) == latlon(45, 0)
281+
@test r(T(1)) == latlon(45, 0)
282+
r = Rope(latlon(45, 0), latlon(45, 90), latlon(90, 90))
283+
@test r(T(0)) == latlon(45, 0)
284+
@test r(T(1)) == latlon(90, 90)
285+
267286
ri = Ring(cart.([(1, 1), (2, 2), (3, 3)]))
268287
ro = Rope(cart.([(1, 1), (2, 2), (3, 3)]))
269288
@test sprint(show, ri) == "Ring((x: 1.0 m, y: 1.0 m), (x: 2.0 m, y: 2.0 m), (x: 3.0 m, y: 3.0 m))"

0 commit comments

Comments
 (0)