Skip to content

Implemented ellipse-rectangle intersection test #3833

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions src/ConcreteOperations/isdisjoint.jl
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,53 @@ end
end
end

"""
# Extended help

isdisjoint(H::Hyperrectangle, E::Ellipsoid)

### Algorithm

The sets are disjoint if the ellipse center lies outside the Minkowski sum
(rectangle expanded by the ellipsoid). Otherwise, we check one corner using
a quadratic form derived from the ellipsoids support function.

### Notes
It works only for 2D axis-aligned rectangles and ellipsoids.

### Reference
David Eberly, “Distance Between a Point and an Ellipse, an Ellipsoid, or a Hyperellipsoid”,
Comment on lines +627 to +631
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
### Notes
It works only for 2D axis-aligned rectangles and ellipsoids.
### Reference
David Eberly, “Distance Between a Point and an Ellipse, an Ellipsoid, or a Hyperellipsoid”,
### Notes
It works only for 2D axis-aligned rectangles and ellipsoids.
### Reference
David Eberly, “Distance Between a Point and an Ellipse, an Ellipsoid, or a Hyperellipsoid”,

Geometric Tools, 2015. https://www.geometrictools.com/Documentation/DistancePointEllipseEllipsoid.pdf
Comment on lines +631 to +632
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where exactly can I find the algorithm in that reference?

"""

@commutative function isdisjoint(H::Hyperrectangle, E::Ellipsoid)
@assert dim(H) == dim(E) == 2 "$H and $E must both have 2 dimensions."

# center to the origin
H_trans = translate(H, -H.center)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You do not need H_trans. You can just use H and modify the center of bbox.

E_trans = translate(E, -H.center)
K = E_trans.center

bbox = overapproximate(H_trans ⊕ E_trans, Hyperrectangle)
if any(abs.(K) .> bbox.radius)
return true
end
Comment on lines +643 to +646
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this first part necessary? It sounds more expensive to compute than the rest of the method.


# find the rectangle corner corresponding to K.
s = sign.(K)
P = s .* H_trans.radius
Δ = K - P

# support vector on the boundary of E_trans in direction Δ.
v = σ(Δ, E_trans)
if any(s .* v .<= 0)
return false
end

# check the ellipse condition
return (ρ(Δ, E_trans))^2 ≤ 1
end

# ============== #
# disambiguation #
# ============== #
Expand Down
22 changes: 22 additions & 0 deletions test/ConcreteOperations/isdisjoint.jl
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,25 @@ for N in [Float64, Float32, Rational{Int}]
end
end
end

for N in [Float64, Float32]
# case 1: ellipse completely outside
R1 = Hyperrectangle(N[1.0, -1.0], N[2, 1])
El1 = Ellipsoid(N[5.0, 5.0], Matrix{N}(I, 2, 2))
@test isdisjoint(R1, El1)

# case 2: ellipse completely inside
R2 = Hyperrectangle(N[0.0, 0.0], N[4.0, 1.0])
El2 = Ellipsoid(N[1.0, 0.0], Matrix{N}(I, 2, 2))
@test !isdisjoint(R2, El2)

# case 3: ellipse overlapping
R3 = Hyperrectangle(N[0.0, 0.0], N[1.0, 1.0])
El3 = Ellipsoid(N[2.0, 0.0], Diagonal(N[2.0, 1.0]))
@test !isdisjoint(R3, El3)

# case 4: ellipse tangent in one point
R4 = Hyperrectangle(N[0.0, 0.0], N[1.0, 1.0])
El4 = Ellipsoid(N[2.0, 0.0], Diagonal(N[1.0, 1.0]))
@test !isdisjoint(R4, El4)
end
Loading