has_overlap2d() is an S3 generic that returns whether two 2D shapes
have a non-zero-area overlap (i.e. their interiors intersect).
Arguments
- x, y
The two shapes to check. Supported classes are Polygon2D and Ellipse2D.
- ...
Ignored; only included for S3 method consistency.
- n
Number of vertices used to approximate non-circular Ellipse2D objects (default
64L). Larger values give tighter bounds.- tol
Numeric tolerance for overlap comparisons (default
0). A positive value requires projections to overlap by more thantolbefore overlap is declared, which avoids false positives caused by floating-point error accumulating in rotated coordinates.sqrt(.Machine$double.eps)is a reasonable choice when shapes are constructed via trigonometric transformations.
Value
A logical vector (or NA) of length equal to the longer of x
and y (for Ellipse2D objects; Polygon2D objects are always scalar).
Details
For two convex shapes the function uses the
Separating Axis Theorem (SAT).
For concave Polygon2D objects the function first checks whether the
axis-aligned bounding box and convex hull overlap; if neither rules out
overlap it returns NA with a warning because exact detection is not yet
supported.
For non-circular Ellipse2D objects the function approximates the ellipse
with inner and outer polygons: if the outer polygon does not overlap the
result is FALSE; if the inner polygon overlaps the result is TRUE;
otherwise NA is returned with a warning.
Examples
# Two overlapping squares
sq1 <- as_polygon2d(as_coord2d(
x = c(0, 1, 1, 0),
y = c(0, 0, 1, 1)
))
sq2 <- as_polygon2d(as_coord2d(
x = c(0.5, 1.5, 1.5, 0.5),
y = c(0.5, 0.5, 1.5, 1.5)
))
sq3 <- as_polygon2d(as_coord2d(
x = c(2, 3, 3, 2),
y = c(2, 2, 3, 3)
))
has_overlap2d(sq1, sq2)
#> [1] TRUE
has_overlap2d(sq1, sq3)
#> [1] FALSE
# Circle vs polygon
circ <- as_ellipse2d(as_coord2d(0.5, 0.5), rx = 0.4)
has_overlap2d(sq1, circ)
#> [1] TRUE
has_overlap2d(sq3, circ)
#> [1] FALSE
# Two circles
c1 <- as_ellipse2d(as_coord2d(0, 0), rx = 1)
c2 <- as_ellipse2d(as_coord2d(1.5, 0), rx = 1)
c3 <- as_ellipse2d(as_coord2d(3, 0), rx = 1)
has_overlap2d(c1, c2)
#> [1] TRUE
has_overlap2d(c1, c3)
#> [1] FALSE
