diff --git a/Cargo.toml b/Cargo.toml index 76b9c4b..df641c2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "myelin-geometry" description = "Basic linear and vector geometry for two-dimensional Euclidean geometry" -version = "2.4.1" +version = "2.4.2" authors = [ "Jan Nils Ferner ", "Mathias Fischler ", diff --git a/changelog.md b/changelog.md index 0325e9d..9ca0bfd 100644 --- a/changelog.md +++ b/changelog.md @@ -28,3 +28,6 @@ - Correct small typos in the documentation. - Remove an unnecessary check. - Remove direct dependency on `serde_derive`. + +## 2.4.2 +- Explicitly disallow NaN, +∞ and -∞ in polygons instead of looping forever (#36). diff --git a/src/polygon.rs b/src/polygon.rs index 4147be8..3588615 100644 --- a/src/polygon.rs +++ b/src/polygon.rs @@ -35,7 +35,9 @@ impl Polygon { pub fn try_new(vertices: Vec) -> Result { const MINIMUM_VERTICES_IN_EUCLIDEAN_GEOMETRY: usize = 3; - if vertices.len() >= MINIMUM_VERTICES_IN_EUCLIDEAN_GEOMETRY && is_convex_polygon(&vertices) + if vertices.len() >= MINIMUM_VERTICES_IN_EUCLIDEAN_GEOMETRY + && vertices.iter().all(is_finite) + && is_convex_polygon(&vertices) { Ok(Self { vertices }) } else { @@ -244,6 +246,10 @@ fn is_convex_polygon(vertices: &[Point]) -> bool { convex_hull_vertice_count == vertices.len() } +fn is_finite(vertice: &Point) -> bool { + vertice.x.is_finite() && vertice.y.is_finite() +} + /// The side that a [`Point`] lies on, from the /// point of view of a line #[derive(Eq, PartialEq, Debug)] @@ -561,6 +567,84 @@ mod tests { ); } + #[test] + fn try_new_does_not_work_when_x_value_of_vertice_is_positive_infinity() { + let vertices = vec![ + Point { + x: f64::INFINITY, + y: 0.0, + }, + Point { x: 1.0, y: 0.0 }, + Point { x: 0.0, y: 1.0 }, + ]; + assert!(Polygon::try_new(vertices).is_err()); + } + + #[test] + fn try_new_does_not_work_when_x_value_of_vertice_is_negative_infinity() { + let vertices = vec![ + Point { + x: f64::NEG_INFINITY, + y: 0.0, + }, + Point { x: 1.0, y: 0.0 }, + Point { x: 0.0, y: 1.0 }, + ]; + assert!(Polygon::try_new(vertices).is_err()); + } + + #[test] + fn try_new_does_not_work_when_x_value_of_vertice_is_nan() { + let vertices = vec![ + Point { + x: f64::NAN, + y: 0.0, + }, + Point { x: 1.0, y: 0.0 }, + Point { x: 0.0, y: 1.0 }, + ]; + assert!(Polygon::try_new(vertices).is_err()); + } + + #[test] + fn try_new_does_not_work_when_y_value_of_vertice_is_positive_infinity() { + let vertices = vec![ + Point { + x: 0.0, + y: f64::INFINITY, + }, + Point { x: 1.0, y: 0.0 }, + Point { x: 0.0, y: 1.0 }, + ]; + assert!(Polygon::try_new(vertices).is_err()); + } + + #[test] + fn try_new_does_not_work_when_y_value_of_vertice_is_negative_infinity() { + let vertices = vec![ + Point { + x: 0.0, + y: f64::NEG_INFINITY, + }, + Point { x: 1.0, y: 0.0 }, + Point { x: 0.0, y: 1.0 }, + ]; + assert!(Polygon::try_new(vertices).is_err()); + } + + #[test] + fn try_new_does_not_work_when_y_value_of_vertice_is_nan() { + let vertices = vec![ + Point { + x: 0.0, + y: f64::NAN, + }, + Point { x: 1.0, y: 0.0 }, + Point { x: 0.0, y: 1.0 }, + ]; + assert!(Polygon::try_new(vertices).is_err()); + } + #[test] fn can_be_created_from_aabb() { let aabb = Aabb::try_new(Point { x: 10.0, y: 15.0 }, Point { x: 20.0, y: 30.0 }).unwrap();