Skip to content

Clean up Rect set operations (union, intersect, diff, overlaps)#276

Merged
ffreyer merged 15 commits into
masterfrom
ff/rect-diff
Jun 10, 2026
Merged

Clean up Rect set operations (union, intersect, diff, overlaps)#276
ffreyer merged 15 commits into
masterfrom
ff/rect-diff

Conversation

@ffreyer

@ffreyer ffreyer commented Jan 31, 2026

Copy link
Copy Markdown
Collaborator

This is something I will probably need for optimizing an SDF volume plots in Makie. Doesn't need to be merged/tagged until I get that near completion

Changes:

  • added volumetric kwarg to isempty to switch between "any" and "all" widths <= 0 checks
  • exclude all-empty rects from union (probably to avoid Rect() including Inf in unions)
  • add bbox_diffto calculate the bounding box of the pieces left after cutting one rect out of another (without explicitly calculating the pieces)
  • return empty rect in intersect if rects have no overlap (+ type promotion)
  • all one rect being fully inside the other in overlaps
  • move rect tests into their own file, categorize tests, add tests for
    • add tests for bbox_diff
    • add tests for isempty
    • extend tests for in (using explicit rects to go through specific situations rather than results from splt)
    • extend tests for overlaps to cover edge cases
    • add numeric tests for union (not just isa Rect)
    • add numeric tests for intersect (not just isa Rect)
    • add numeric tests for update (not just isa Rect)

TODO:

  • consider removing Allen's Interval Algebra functions for general Rects, see below

@ffreyer

ffreyer commented Jan 31, 2026

Copy link
Copy Markdown
Collaborator Author

https://en.wikipedia.org/wiki/Allen%27s_interval_algebra

# http://en.wikipedia.org/wiki/Allen%27s_interval_algebra
function before(b1::Rect{N}, b2::Rect{N}) where {N}
for i in 1:N
maximum(b1)[i] < minimum(b2)[i] || return false
end
return true
end
meets(b1::Rect{N}, b2::Rect{N}) where {N} = maximum(b1) == minimum(b2)
function overlaps(b1::Rect{N}, b2::Rect{N}) where {N}
for i in 1:N
maximum(b2)[i] > maximum(b1)[i] > minimum(b2)[i] &&
minimum(b1)[i] < minimum(b2)[i] || return false
end
return true
end
function starts(b1::Rect{N}, b2::Rect{N}) where {N}
return if minimum(b1) == minimum(b2)
for i in 1:N
maximum(b1)[i] < maximum(b2)[i] || return false
end
return true
else
return false
end
end
function during(b1::Rect{N}, b2::Rect{N}) where {N}
for i in 1:N
maximum(b1)[i] < maximum(b2)[i] && minimum(b1)[i] > minimum(b2)[i] || return false
end
return true
end
function finishes(b1::Rect{N}, b2::Rect{N}) where {N}
return if maximum(b1) == maximum(b2)
for i in 1:N
minimum(b1)[i] > minimum(b2)[i] || return false
end
return true
else
return false
end
end

This stuff makes sense for intervals but I fail to see how this should generalize to rectangles. For examples saying one interval is before another is clear, but for 2D rects it could mean being outside towards -x, or -y or -(x, y) (current), or any of those. meets(a, b) could be:

--.--
a | b
--'--

or

| b |
|---|
| a |

or (current)

  | b
--+---
a |

or other rotations. Also, for the edge versions, do widths need to match for the dimension that doesn't meet?

This doesn't seem clear enough to have. It's been there since the dawn of GeometryTypes 11 years ago

@ffreyer ffreyer changed the title Add rect diff Clean up Rect set operations (union, intersect, diff, overlaps) Feb 2, 2026
Comment thread src/primitives/rectangles.jl Outdated

"""
isempty(h::Rect)
isempty(h::Rect[, volumetric = true])

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

since this is a base overload and not really self explanatory, i think this should be a kwarg.

@ffreyer ffreyer marked this pull request as ready for review June 10, 2026 14:58
@ffreyer ffreyer merged commit 7f38799 into master Jun 10, 2026
14 checks passed
@ffreyer ffreyer deleted the ff/rect-diff branch June 10, 2026 15:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants