Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions geo/CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changes

## Unreleased

- Fix `CoordinatePosition` for `Triangle` to correctly return `CoordPos::OnBoundary` for coordinate within vertical segment.

## 0.32.0 - 2025-12-05

- Move `PreparedGeometry` into a new `indexed` module intended to provide index-backed geometries. `relate::PreparedGeometry` has been deprecated.
Expand Down
28 changes: 24 additions & 4 deletions geo/src/algorithm/coordinate_position.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,12 @@ where
let orientation = T::Ker::orient2d(l.start, l.end, *coord);
if orientation == Orientation::Collinear
&& point_in_rect(*coord, l.start, l.end)
&& coord.x != l.end.x
Copy link
Member Author

Choose a reason for hiding this comment

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

Previously we were only checking the x value - but that broke down for vertical lines.

// If a coordinate falls *on* one of the triangle's vertices,
// it will appear both as the `end` of one segment and the `start` of the next.
// We only want to count one boundary crossing in that case,
// so we ignore it if it falls on `l.end`,
// knowing that we'll count it on some other segments `l.start`
&& *coord != l.end
{
*boundary_count += 1;
}
Expand Down Expand Up @@ -445,10 +450,8 @@ where

#[cfg(test)]
mod test {
use geo_types::coord;

use super::*;
use crate::{line_string, point, polygon};
use crate::{coord, line_string, point, polygon, wkt};

#[test]
fn test_empty_poly() {
Expand Down Expand Up @@ -708,12 +711,29 @@ mod test {
triangle.coordinate_position(&coord! { x: 2.5, y: 5.0 }),
CoordPos::OnBoundary
);
assert_eq!(
triangle.coordinate_position(&coord! { x: 5.0, y: 10.0 }),
CoordPos::OnBoundary
);
assert_eq!(
triangle.coordinate_position(&coord! { x: 2.49, y: 5.0 }),
CoordPos::Outside
);
}

#[test]
fn test_right_triangle() {
let triangle: Triangle = wkt!(TRIANGLE(0. 0.,10. 0.,10. 10.));
assert_eq!(
triangle.coordinate_position(&coord!(x: 0., y: 0.)),
CoordPos::OnBoundary
);
assert_eq!(
triangle.coordinate_position(&coord!(x: 10., y: 5.)),
CoordPos::OnBoundary
);
}

#[test]
fn test_collection() {
let triangle = Triangle::new((0.0, 0.0).into(), (5.0, 10.0).into(), (10.0, 0.0).into());
Expand Down