Skip to content

Trim a detection's polygon when its bounding box is shrunk over it#1783

Open
mattdawkins wants to merge 2 commits into
mainfrom
fix/clip-polygon-to-resized-box
Open

Trim a detection's polygon when its bounding box is shrunk over it#1783
mattdawkins wants to merge 2 commits into
mainfrom
fix/clip-polygon-to-resized-box

Conversation

@mattdawkins

@mattdawkins mattdawkins commented Jul 21, 2026

Copy link
Copy Markdown
Member

Problem

Resizing a detection's bounding box leaves its polygon untouched, so shrinking the box past the polygon leaves polygon geometry sticking out beyond the box.

Fix

Box edits now clip any polygon on the detection to the new bounds using a small Sutherland–Hodgman implementation (clipPolygonToBounds in src/utils.ts, no new dependency):

  • Polygons crossing the new box edge are trimmed to fit.
  • A polygon falling entirely outside the new box is removed.
  • Holes are clipped by the same rule; holes left with fewer than 3 points are dropped.
  • Clipping happens against the rounded bounds that setFeature stores, so the trimmed polygon is consistent with the persisted box.
  • Rotated boxes are exempt: their stored bounds are the unrotated envelope, so an axis-aligned clip would cut the wrong region.

Redundant full-box polygons are dropped

A polygon identical to the detection's bounding box carries no information beyond the box and makes editing harder, so (second commit):

  • When a box shrink clips a polygon down to exactly the new box, the polygon is removed rather than kept as a redundant rectangle.
  • On load, Track.fromJSON drops any polygon equal to its feature's bounds (extra collinear vertices and either winding still count as equal; polygons with holes or any interior structure are kept, and other geometry like head/tail points is untouched).

The equality test (polygonEqualsBounds) requires a hole-free polygon whose extent matches the bounds and whose area fills the box — a simple polygon with the area of its bounding box must be that rectangle.

Unit tests cover containment, single/multi-edge clipping, slanted-edge intersection points, full removal, hole handling, box-equality detection (including clip artifacts and near-miss shapes), and the load-time cleanup.

🤖 Generated with Claude Code

mattdawkins and others added 2 commits July 21, 2026 16:46
Resizing a bounding box previously left the detection's polygon
untouched, so shrinking the box could leave polygon geometry sticking
out beyond it. Box edits now clip any polygon on the detection to the
new bounds (Sutherland-Hodgman against the axis-aligned box), dropping
a polygon entirely when it falls completely outside. Holes are clipped
with the same rule. Rotated boxes are exempt since their stored bounds
are the unrotated envelope.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A polygon identical to the detection's bounding box carries no
information beyond the box itself and makes editing harder, so:

- when a box shrink clips a polygon down to exactly the new box, the
  polygon is removed instead of kept as a redundant rectangle;
- on load, Track.fromJSON drops any polygon equal to its feature's
  bounds (extra collinear vertices and either winding still count as
  equal; polygons with holes or any interior structure are kept).

The equality test (polygonEqualsBounds) requires a hole-free polygon
whose extent matches the bounds and whose area fills the box - a
simple polygon with the area of its bounding box must be that
rectangle.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.

1 participant