Skip to content

Commit 0a168b3

Browse files
committed
Fix coordinate position on vertical boundary
Inspired by @wwaltersdavis in #1465
1 parent 240f203 commit 0a168b3

File tree

2 files changed

+28
-4
lines changed

2 files changed

+28
-4
lines changed

geo/CHANGES.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changes
22

3+
## Unreleased
4+
5+
- Fix `CoordinatePosition` for `Triangle` to correctly return `CoordPos::OnBoundary` for coordinate within vertical segment.
6+
37
## 0.32.0 - 2025-12-05
48

59
- Move `PreparedGeometry` into a new `indexed` module intended to provide index-backed geometries. `relate::PreparedGeometry` has been deprecated.

geo/src/algorithm/coordinate_position.rs

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,12 @@ where
192192
let orientation = T::Ker::orient2d(l.start, l.end, *coord);
193193
if orientation == Orientation::Collinear
194194
&& point_in_rect(*coord, l.start, l.end)
195-
&& coord.x != l.end.x
195+
// If a coordinate falls *on* one of the triangle's vertices,
196+
// it will appear both as the `end` of one segment and the `start` of the next.
197+
// We only want to count one boundary crossing in that case,
198+
// so we ignore it if it falls on `l.end`,
199+
// knowing that we'll count it on some other segments `l.start`
200+
&& *coord != l.end
196201
{
197202
*boundary_count += 1;
198203
}
@@ -445,10 +450,8 @@ where
445450

446451
#[cfg(test)]
447452
mod test {
448-
use geo_types::coord;
449-
450453
use super::*;
451-
use crate::{line_string, point, polygon};
454+
use crate::{coord, line_string, point, polygon, wkt};
452455

453456
#[test]
454457
fn test_empty_poly() {
@@ -708,12 +711,29 @@ mod test {
708711
triangle.coordinate_position(&coord! { x: 2.5, y: 5.0 }),
709712
CoordPos::OnBoundary
710713
);
714+
assert_eq!(
715+
triangle.coordinate_position(&coord! { x: 5.0, y: 10.0 }),
716+
CoordPos::OnBoundary
717+
);
711718
assert_eq!(
712719
triangle.coordinate_position(&coord! { x: 2.49, y: 5.0 }),
713720
CoordPos::Outside
714721
);
715722
}
716723

724+
#[test]
725+
fn test_right_triangle() {
726+
let triangle: Triangle = wkt!(TRIANGLE(0. 0.,10. 0.,10. 10.));
727+
assert_eq!(
728+
triangle.coordinate_position(&coord!(x: 0., y: 0.)),
729+
CoordPos::OnBoundary
730+
);
731+
assert_eq!(
732+
triangle.coordinate_position(&coord!(x: 10., y: 5.)),
733+
CoordPos::OnBoundary
734+
);
735+
}
736+
717737
#[test]
718738
fn test_collection() {
719739
let triangle = Triangle::new((0.0, 0.0).into(), (5.0, 10.0).into(), (10.0, 0.0).into());

0 commit comments

Comments
 (0)