Add spatial predicates API with fixed-scale support#56
Add spatial predicates API with fixed-scale support#56NailxSharipov merged 8 commits intoiShape-Rust:mainfrom
Conversation
|
Implements #50 |
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
Add FloatPredicateOverlay and FloatRelate trait for efficient spatial relationship testing (intersects, touches, within, covers, disjoint). Features: - PredicateOverlay for integer-space predicate evaluation with early-exit - FloatPredicateOverlay wrapper handling float-to-int conversion - FloatRelate trait for ergonomic predicate methods on ShapeResource types - FixedScaleFloatRelate trait for fixed-scale precision predicates - with_adapter() and with_adapter_custom() constructors for custom adapters - with_subj_and_clip_fixed_scale() for fixed-scale precision
b15a9a8 to
b145cbb
Compare
…cates Add tests for: - FixedScaleFloatRelate: disjoint_with_fixed_scale, covers_with_fixed_scale - FloatOverlay: with_subj_and_clip_fixed_scale_custom - FloatPredicateOverlay: with_adapter, with_adapter_custom, with_subj_and_clip_custom, clear - Error handling for invalid scale values across all fixed-scale methods
Add add_path_iter, add_contour, add_contours, add_shape, and add_shapes methods to match Overlay's public API. This enables external crates to use PredicateOverlay directly without accessing internal fields. Refactored FloatPredicateOverlay to use the new public methods. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
Thanks for the pr. |
NailxSharipov
left a comment
There was a problem hiding this comment.
Great work.
I like how this is implemented.
iOverlay/src/build/builder.rs
Outdated
|
|
||
| #[inline(always)] | ||
| fn handle(&mut self, index: usize, fill: SegmentFill) -> ControlFlow<()> { | ||
| self.fills[index] = fill; |
There was a problem hiding this comment.
It's better to use unsafe here.
The compiler doesn't see this as safe and won't optimize it. But the algorithm guarantees that it return an index less than the vector's length.
| }; | ||
| use core::ops::ControlFlow; | ||
|
|
||
| /// Handler that checks if subject and clip shapes intersect (share any point). |
There was a problem hiding this comment.
We can not handle point <-> point case with this logic.
┌──┐
│S │
┌──●──┘
│C │
└──┘
… indexing - Use unsafe unchecked indexing in StoreFillsHandler for performance - Add point coincidence detection for single-vertex touches between shapes - Refactor TouchesHandler to return (boundary_contact, interior_overlap) tuple with early-exit on interior overlap - Make evaluate() generic over output type to support tuple returns - Add tests for point-to-point and segment endpoint touch scenarios
0b94dcb to
430a64e
Compare
… access Change FillHandler trait to receive segment reference, enabling handlers to access segment data during sweep for point coincidence detection. Key changes: - FillHandler<C> now passes &Segment<C> to handle() method - Add PointCoincidenceChecker helper struct with optimizations: - Uses IntPoint (8 bytes) vs (i32,i32,bool,bool) (16 bytes) = 2x memory reduction - Collects into separate subj/clip Vecs, sorts with sort_by_two_keys - Dedup removes ~50% duplicate endpoints from adjacent segments - Binary search from shorter array into longer for O(min(S,C) * log(max(S,C))) - Skips interior segments (SUBJ_BOTH/CLIP_BOTH fill) that can't contribute - IntersectsHandler and TouchesHandler now collect points during sweep - Remove standalone has_point_coincidence function from relate.rs - Add integration tests for doughnut+diamond hole boundary scenarios
|
@NailxSharipov added those optimisations you suggested here: c4e52dc |
…on detection Add a new spatial predicate that returns true only when shapes touch by vertex coincidence without any edge overlap. This fills the gap between touches() (which includes edge contact) and interiors_intersect(). - Add PointIntersectsHandler with early exit on interior/boundary overlap - Add point_intersects() to PredicateOverlay and FloatPredicateOverlay - Add point_intersects() to FloatRelate trait
…r array - Sort and dedup only the shorter array (binary search target) - Iterate the longer array doing binary searches into the shorter - Reduces complexity from O(n log n + m log m) to O(n log n + m log n) - Fix test to expect false for shared segments (line, not point intersection)
Summary
FloatPredicateOverlayandFloatRelatetrait for efficient spatial relationship testingFixedScaleFloatRelatetrait for fixed-scale precision predicatesintersects,disjoint,interiors_intersect,touches,within,coversSweepRunnerstruct that owns scan structures and runs sweeps with any handlerGraphBuilderandPredicateOverlayFillHandlertrait for early-exit during sweep (used by predicates)Test plan
cargo test -p i_overlay)relate.rsandscale.rscargo clippyandcargo fmtpass