Skip to content

Commit bfe678e

Browse files
authored
Add isinside functionality (#96)
1 parent 1e5f5d1 commit bfe678e

File tree

7 files changed

+139
-75
lines changed

7 files changed

+139
-75
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ jobs:
3030
- uses: julia-actions/julia-buildpkg@v1
3131
- uses: julia-actions/julia-runtest@v1
3232
- uses: julia-actions/julia-processcoverage@v1
33-
- uses: codecov/codecov-action@v2
33+
- uses: codecov/codecov-action@v3
3434
if: ${{ matrix.version == '1' && matrix.os == 'ubuntu-latest' }}
3535
with:
3636
file: lcov.info

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "CoherentStructures"
22
uuid = "0c1513b4-3a13-56f1-9cd2-8312eaec88c4"
3-
version = "0.4.10"
3+
version = "0.4.11"
44

55
[deps]
66
ArnoldiMethod = "ec485272-7323-5ecc-a04f-4719b315124d"

docs/Manifest.toml

Lines changed: 89 additions & 66 deletions
Large diffs are not rendered by default.

docs/src/elliptic.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,8 @@ compute_closed_orbits
147147
First of all, [`Singularity`](@ref), [`EllipticBarrier`](@ref) and [`EllipticVortex`](@ref)
148148
objects can be passed as initial conditions to the [`flow`](@ref) function, which returns
149149
a (time-resolved) vector of corresponding objects. Moreover, we have advection with
150-
adaptive point insertion (known in oceanography as "Dritschel advection") and an function
151-
to compute the area of [`EllipticBarrier`](@ref) and [`EllipticVortex`](@ref) objects.
150+
adaptive point insertion (known in oceanography as "Dritschel advection") and some more
151+
convenience functions.
152152

153153
```@docs
154154
FlowGrowParams
@@ -157,4 +157,5 @@ area
157157
centroid
158158
clockwise
159159
Base.extrema(::EllipticBarrier)
160+
isinside
160161
```

src/ellipticLCS.jl

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1755,3 +1755,39 @@ function clockwise(barrier::EllipticBarrier, velo::ODEFunction{false}, t0; p=not
17551755
end
17561756
clockwise(vortex::EllipticVortex, velo, t0; p=nothing) =
17571757
clockwise(last(vortex.barriers), velo, t0; p=p)
1758+
1759+
"""
1760+
isinside(p, polygon)
1761+
1762+
Determine whether the point `p` (or [`Singularity`](@ref)) lies inside `polygon`, which can
1763+
be of type `Vector{SVector{2}}`, `EllipticBarrier` or `EllipticVortex`. In the latter case,
1764+
the outermost (i.e., the last `EllipticBarrier` in the `barriers` field) is used.
1765+
"""
1766+
isinside(p::SVector{2}, poly::Vector{<:SVector{2}}) = !iszero(winding_number(p, poly))
1767+
isinside(p::SVector{2}, barrier::EllipticBarrier) = isinside(p, barrier.curve)
1768+
isinside(p::SVector{2}, vortex::EllipticVortex) = isinside(p, last(vortex.barriers))
1769+
isinside(s::Singularity, curve) = isinside(s.coords, curve)
1770+
1771+
function quadrant(p::SVector{2})
1772+
if p[1] > 0
1773+
p[2] >= 0 && return 1
1774+
return 4
1775+
else
1776+
p[2] >= 0 && return 2
1777+
return 3
1778+
end
1779+
end
1780+
function winding_number(q::SVector{2}, poly::Vector{<:SVector{2}})
1781+
qprev = qfirst = quadrant(poly[1] - q)
1782+
qnext = quadrant(poly[2] - q)
1783+
Δq = qnext - qprev
1784+
@inbounds for i in 3:length(poly)
1785+
qnext = quadrant(poly[i] - q)
1786+
qdiff = qnext - qprev
1787+
Δq += qdiff == 3 ? -1 : qdiff == -3 ? 1 : qdiff
1788+
qprev = qnext
1789+
end
1790+
qdiff = qfirst - qnext
1791+
Δq += qdiff == 3 ? -1 : qdiff == -3 ? 1 : qdiff
1792+
return Δq ÷ 4
1793+
end

src/exports.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ export
3131
area,
3232
centroid,
3333
clockwise,
34+
isinside,
3435

3536
#diffusion_operators.jl
3637
gaussian,

test/test_elliptic.jl

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -173,16 +173,19 @@ end
173173
@test area(square) 4 rtol=5eps()
174174
@test centroid(square) ones(2) atol=5eps()
175175
barrier = CS.EllipticBarrier(circle, SVector{2}(0.0, 0.0), 1.0, true)
176-
vortices = CS.EllipticVortex(SVector{2}(0.0, 0.0), [barrier])
176+
vortex = CS.EllipticVortex(SVector{2}(0.0, 0.0), [barrier])
177177
LL, UR = extrema(barrier)
178-
@test area(vortices) == area(barrier) == area(circle)
179-
@test centroid(vortices) == centroid(barrier) == centroid(circle)
180-
@test extrema(vortices) == extrema(barrier)
178+
@test area(vortex) == area(barrier) == area(circle)
179+
@test centroid(vortex) == centroid(barrier) == centroid(circle)
180+
@test extrema(vortex) == extrema(barrier)
181181
@test LL -ones(2) rtol=1e-5
182182
@test UR ones(2) rtol=1e-6
183183
@test !clockwise(barrier, ODEFunction((u, p, t) -> SVector{2}(-u[2], u[1])), 0)
184184
@test clockwise(barrier, ODEFunction((u, p, t) -> SVector{2}(-u[2], u[1])), 0) ==
185-
clockwise(vortices, ODEFunction((u, p, t) -> SVector{2}(-u[2], u[1])), 0)
185+
clockwise(vortex, ODEFunction((u, p, t) -> SVector{2}(-u[2], u[1])), 0)
186+
@test isinside(SVector(1-eps(),0), vortex)
187+
@test isinside(Singularity(vortex.center, 1), vortex)
188+
@test !isinside(SVector(1+eps(),0), vortex)
186189
barrier = CS.EllipticBarrier(square, SVector{2}(1.0, 1.0), 1.0, true)
187190
LL, UR = extrema(barrier)
188191
@test LL zeros(2)

0 commit comments

Comments
 (0)