Skip to content

Add geomGetDominantSurroundingRectangle and rename SSR type - #308

Merged
bhousel merged 1 commit into
mainfrom
longest_surrounding_rectangle
May 5, 2026
Merged

bhousel merged 1 commit into
mainfrom
longest_surrounding_rectangle

Conversation

@bhousel

@bhousel bhousel commented May 5, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Adds geomGetLongestSurroundingRectanglegeomDominantSurroundingRectangle alongside the existing geomGetSmallestSurroundingRectangle, and renames the SSR interface to SurroundingRectangle.

Changes

  • New function: geomGetLongestSurroundingRectangle — returns the surrounding rectangle whose longest side is maximized. This may result in generating a more intuitive bounding box around features with a dominant axis (like buildings), and may be useful for placing labels and icons aligned to a building's dominant axis.
  • Renamed type: SSR → SurroundingRectangle for clarity.
  • Shared implementation: Both functions delegate to a generalized getSurroundingRectangle helper, differing only in their scoring strategy.
  • Angle deduplication: Candidate angles are deduplicated via a Set keyed on Math.round(angle / ANGLE_EPSILON), avoiding testing of redundant rotations.
  • Loop optimization: Replaced reduce with a for...of loop for extent accumulation; inlined rotation math to avoid allocating a temporary rotated-polygon array.
  • Tests: Added real off-axis L-shaped building fixture (offAxisLShapedBuildingPoints) and assertions verifying both functions choose the correct envelope orientation.

👉 Update

After some testing I ended up using a different approach and making a new function geomGetDominantSurroundingRectangle.

The previous approach of selecting the "longest" edge would always pick a hypotenuse, generating diamond shapes around everything, which is not at all what we want.

Instead we'll compute an “edge-length-weighted dominant orientation” - use the outline segments as "votes" for an axis, fold perpendicular edges into the same bucket, then build the enclosing rectangle from there.
See 4f9d086

Closes #267
Closes facebook/Rapid#1045

@bhousel
bhousel merged commit 70da5b1 into main May 5, 2026
1 check passed
@bhousel
bhousel deleted the longest_surrounding_rectangle branch May 5, 2026 19:25
bhousel added a commit that referenced this pull request May 19, 2026
@bhousel bhousel changed the title Add geomGetLongestSurroundingRectangle and rename SSR type Add geomGetDominantSurroundingRectangle and rename SSR type May 19, 2026
bhousel added a commit to bhousel/Rapid that referenced this pull request May 19, 2026
(closes  facebook#1045)

see rapideditor/rapid-sdk#267 and rapideditor/rapid-sdk#308

This new approach can pick better surrounding rectangles in cases where
the shape has zigzags or L-shape.  The "smallest" rectangle would often
appear at an angle.

Instead, the computed "dominant" rectangle considers the weighted-edge
angles as "votes" and builds a rectangle using more long edges.
bhousel added a commit that referenced this pull request May 21, 2026
Add centroid, longAxis, shortAxis fields to SurroundingRectangle.
Remove redundant geomGetSurroundingRectangle; extract _normalizeAngle,
_getRotatedExtent, and _buildSurroundingRectangle private helpers.
geomGetDominantSurroundingRectangle no longer needs a convex hull.
_getRotatedExtent delegates to geomRotate + Extent.extendSelf (no duplicate trig).
Remove Edge type; vecProject now returns Closest (same shape: index/distance/point).
Add extensive inline comments explaining the rotate-extent-rotate algorithm.
Update CHANGELOG for pre.5.

closes #308
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant