Skip to contents

has_overlap2d() is an S3 generic that returns whether two 2D shapes have a non-zero-area overlap (i.e. their interiors intersect).

Usage

has_overlap2d(x, y, ...)

# S3 method for class 'Polygon2D'
has_overlap2d(x, y, ..., n = 64L, tol = sqrt(.Machine$double.eps))

# S3 method for class 'Ellipse2D'
has_overlap2d(x, y, ..., n = 64L, tol = sqrt(.Machine$double.eps))

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 than tol before 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