From f2d0de6607e5b3670bf742990d35b1cf62c9113b Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Wed, 10 Apr 2024 03:01:16 +0000 Subject: [PATCH] geometry: implement checking if point is contained in shape --- src/geometry/mod.rs | 1 + src/geometry/polygon.rs | 11 +++++++++++ src/geometry/primitive.rs | 28 +++++++++++++++++++++++++--- src/geometry/shape.rs | 9 +++++++++ 4 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 src/geometry/polygon.rs create mode 100644 src/geometry/shape.rs diff --git a/src/geometry/mod.rs b/src/geometry/mod.rs index a5a46d4..405c06d 100644 --- a/src/geometry/mod.rs +++ b/src/geometry/mod.rs @@ -1,6 +1,7 @@ #[macro_use] mod geometry; pub mod primitive; +mod shape; pub mod with_rtree; pub use geometry::*; diff --git a/src/geometry/polygon.rs b/src/geometry/polygon.rs new file mode 100644 index 0000000..7eb803c --- /dev/null +++ b/src/geometry/polygon.rs @@ -0,0 +1,11 @@ +use enum_dispatch::enum_dispatch; + +pub struct PolygonShape { + pub polygon: Polygon, +} + +impl ShapeTrait for PolygonShape { + fn contains_point(&self, p: Point) -> bool { + self.polygon.contains(p) + } +} diff --git a/src/geometry/primitive.rs b/src/geometry/primitive.rs index d331182..7179f45 100644 --- a/src/geometry/primitive.rs +++ b/src/geometry/primitive.rs @@ -1,8 +1,11 @@ use enum_dispatch::enum_dispatch; -use geo::{point, polygon, EuclideanDistance, Intersects, Point, Polygon, Rotate}; +use geo::{point, polygon, Contains, EuclideanDistance, Intersects, Point, Polygon, Rotate}; use rstar::{RTreeObject, AABB}; -use crate::math::{self, Circle}; +use crate::{ + geometry::shape::ShapeTrait, + math::{self, Circle}, +}; #[enum_dispatch] pub trait PrimitiveShapeTrait { @@ -35,7 +38,7 @@ pub trait PrimitiveShapeTrait { } } -#[enum_dispatch(PrimitiveShapeTrait)] +#[enum_dispatch(ShapeTrait, PrimitiveShapeTrait)] #[derive(Debug, Clone, Copy, PartialEq)] pub enum PrimitiveShape { // Intentionally in different order to reorder `self.intersects(...)` properly. @@ -49,6 +52,12 @@ pub struct DotShape { pub c: Circle, } +impl ShapeTrait for DotShape { + fn contains_point(&self, p: Point) -> bool { + p.euclidean_distance(&self.c.pos) <= self.c.r + } +} + impl PrimitiveShapeTrait for DotShape { fn priority(&self) -> u64 { 3 @@ -143,6 +152,12 @@ impl SegShape { } } +impl ShapeTrait for SegShape { + fn contains_point(&self, p: Point) -> bool { + self.polygon().contains(&p) + } +} + impl PrimitiveShapeTrait for SegShape { fn priority(&self) -> u64 { 2 @@ -252,6 +267,13 @@ impl BendShape { } } +impl ShapeTrait for BendShape { + fn contains_point(&self, p: Point) -> bool { + let d = p.euclidean_distance(&self.c.pos); + self.between_ends(p) && d >= self.inner_circle().r && d <= self.outer_circle().r + } +} + impl PrimitiveShapeTrait for BendShape { fn priority(&self) -> u64 { 1 diff --git a/src/geometry/shape.rs b/src/geometry/shape.rs new file mode 100644 index 0000000..a95bd48 --- /dev/null +++ b/src/geometry/shape.rs @@ -0,0 +1,9 @@ +use enum_dispatch::enum_dispatch; +use geo::Point; + +use crate::geometry::primitive::PrimitiveShape; + +#[enum_dispatch] +pub trait ShapeTrait { + fn contains_point(&self, p: Point) -> bool; +}