diff --git a/jaguars/src/collision_detection/cd_engine.rs b/jaguars/src/collision_detection/cd_engine.rs index 76292cf..6bd02da 100644 --- a/jaguars/src/collision_detection/cd_engine.rs +++ b/jaguars/src/collision_detection/cd_engine.rs @@ -10,7 +10,7 @@ use crate::collision_detection::hazard::HazardEntity; use crate::collision_detection::quadtree::qt_node::QTNode; use crate::geometry::fail_fast::sp_surrogate::SPSurrogate; use crate::geometry::geo_enums::{GeoPosition, GeoRelation}; -use crate::geometry::geo_traits::{CollidesWith, Shape, Transformable}; +use crate::geometry::geo_traits::{CollidesWith, Shape, Transformable, TransformableFrom}; use crate::geometry::primitives::aa_rectangle::AARectangle; use crate::geometry::primitives::circle::Circle; use crate::geometry::primitives::edge::Edge; @@ -230,6 +230,18 @@ impl CDEngine { } //QUERY ---------------------------------------------------------------------------------------- + pub fn surrogate_or_shape_collides(&self, reference_shape: &SimplePolygon, buffer_shape : &mut SimplePolygon, transform: &Transformation, irrelevant_hazards: &[HazardEntity]) -> bool { + //Begin with checking the surrogate for collisions + match self.surrogate_collides(reference_shape.surrogate(), transform, irrelevant_hazards){ + true => true, + false => { + //Transform the reference_shape and store the result in the buffer_shape + buffer_shape.transform_from(reference_shape, transform); + self.shape_collides(buffer_shape, irrelevant_hazards) + } + } + } + pub fn shape_collides(&self, shape: &SimplePolygon, irrelevant_hazards: &[HazardEntity]) -> bool { match self.bbox.relation_to(&shape.bbox()) { //Not fully inside bbox => definite collision diff --git a/jaguars/src/geometry/convex_hull.rs b/jaguars/src/geometry/convex_hull.rs index 2127b5a..e9e4286 100644 --- a/jaguars/src/geometry/convex_hull.rs +++ b/jaguars/src/geometry/convex_hull.rs @@ -1,6 +1,8 @@ use crate::geometry::primitives::point::Point; use crate::geometry::primitives::simple_polygon::SimplePolygon; +/// +/// Returns the indices of the points in the SimplePolygon that form the convex hull pub fn convex_hull_indices(shape: &SimplePolygon) -> Vec { let c_hull = convex_hull_from_points(shape.points().clone()); let mut indices = vec![]; @@ -10,9 +12,9 @@ pub fn convex_hull_indices(shape: &SimplePolygon) -> Vec { indices } +/// Returns the points that form the convex hull of the input points +/// Uses the Monotone chain algorithm : pub fn convex_hull_from_points(mut points: Vec) -> Vec { - // Monotone chain algorithm: - // https://en.wikibooks.org/wiki/Algorithm_Implementation/Geometry/Convex_hull/Monotone_chain //sort the points by x coordinate points.sort_by(|a, b| { diff --git a/jaguars/src/geometry/d_transformation.rs b/jaguars/src/geometry/d_transformation.rs index 11b083a..6b1aab9 100644 --- a/jaguars/src/geometry/d_transformation.rs +++ b/jaguars/src/geometry/d_transformation.rs @@ -5,7 +5,7 @@ use ordered_float::NotNan; use crate::geometry::transformation::Transformation; #[derive(Clone, Debug, PartialEq, Eq, Hash)] -///A proper rigid transformation, decomposed into a rotation followed by a translation +/// A proper rigid transformation, decomposed into a rotation followed by a translation. pub struct DTransformation { pub rotation: NotNan, pub translation: (NotNan, NotNan), diff --git a/jaguars/src/geometry/fail_fast/piers.rs b/jaguars/src/geometry/fail_fast/piers.rs index 98ef4c9..0ba6180 100644 --- a/jaguars/src/geometry/fail_fast/piers.rs +++ b/jaguars/src/geometry/fail_fast/piers.rs @@ -11,12 +11,11 @@ use crate::geometry::primitives::point::Point; use crate::geometry::primitives::simple_polygon::SimplePolygon; use crate::geometry::transformation::Transformation; -pub static RAYS_PER_ANGLE: usize = if cfg!(debug_assertions) { 10 } else { 200 }; -pub static N_ANGLES: usize = if cfg!(debug_assertions) { 4 } else { 90 }; -pub static N_POINTS_PER_DIMENSION: usize = if cfg!(debug_assertions) { 10 } else { 100 }; - -pub static CLIPPING_TRIM: f64 = 0.999; -pub static ACTION_RADIUS_RATIO: f64 = 0.10; +static RAYS_PER_ANGLE: usize = if cfg!(debug_assertions) { 10 } else { 200 }; +static N_ANGLES: usize = if cfg!(debug_assertions) { 4 } else { 90 }; +static N_POINTS_PER_DIMENSION: usize = if cfg!(debug_assertions) { 10 } else { 100 }; +static CLIPPING_TRIM: f64 = 0.999; +static ACTION_RADIUS_RATIO: f64 = 0.10; pub fn generate(shape: &SimplePolygon, n: usize, poles: &[Circle]) -> Vec { if n == 0 { diff --git a/jaguars/src/geometry/fail_fast/poi.rs b/jaguars/src/geometry/fail_fast/poi.rs index 43e2f9b..d9801d6 100644 --- a/jaguars/src/geometry/fail_fast/poi.rs +++ b/jaguars/src/geometry/fail_fast/poi.rs @@ -7,9 +7,10 @@ use crate::geometry::primitives::aa_rectangle::AARectangle; use crate::geometry::primitives::circle::Circle; use crate::geometry::primitives::simple_polygon::SimplePolygon; -//Based on Mapbox's "Polylabel" algorithm: https://github.com/mapbox/polylabel -//Generates the Pole of Inaccessibility, with a twist that poles are also seen as exterior. +/// Generates the Pole of Inaccessibility (PoI) +/// The interior is defined as the interior of the shape minus the interior of the poles +/// Based on Mapbox's "Polylabel" algorithm: pub fn generate_next_pole(shape: &SimplePolygon, poles: &[Circle]) -> Circle { let square_bbox = shape.bbox().inflate_to_square(); let root = POINode::new(square_bbox, MAX_POI_TREE_DEPTH, shape, &poles); @@ -33,7 +34,7 @@ pub fn generate_next_pole(shape: &SimplePolygon, poles: &[Circle]) -> Circle { best.expect("no pole present") } -//Creates a set of the largest possible non-overlapping circles in poly shape +///Generates additional poles for a shape alongside the PoI pub fn generate_additional_surrogate_poles(shape: &SimplePolygon, max_poles: usize, coverage_goal: f64) -> Vec { let mut all_poles = vec![shape.poi().clone()]; let pole_area_goal = shape.area() * coverage_goal; diff --git a/jaguars/src/geometry/geo_traits.rs b/jaguars/src/geometry/geo_traits.rs index 28c9295..cc3f9f1 100644 --- a/jaguars/src/geometry/geo_traits.rs +++ b/jaguars/src/geometry/geo_traits.rs @@ -3,19 +3,19 @@ use crate::geometry::primitives::aa_rectangle::AARectangle; use crate::geometry::primitives::point::Point; use crate::geometry::transformation::Transformation; -/// Trait for types that can detect collisions between itself and on object from type T +/// Trait for types that can detect collisions between itself and an object from type T. pub trait CollidesWith { fn collides_with(&self, other: &T) -> bool; } -/// Trait for types that can detect almost-collisions between itself and on object from type T -/// Useful in situations where fp arithmetic precision could be problematic -/// Leans towards false positives rather than false negatives +/// Trait for types that can detect almost-collisions between itself and an object from type T. +/// Useful in situations where fp arithmetic precision could be problematic. +/// Leans towards false positives rather than false negatives. pub trait AlmostCollidesWith { fn almost_collides_with(&self, other: &T) -> bool; } -/// Trait for geometric primitives that can calculate distances to other objects +/// Trait for geometric primitives that can calculate distances to other primitives. pub trait DistanceFrom { fn sq_distance(&self, other: &T) -> f64; fn distance(&self, other: &T) -> f64; @@ -23,7 +23,7 @@ pub trait DistanceFrom { fn sq_distance_from_border(&self, other: &T) -> (GeoPosition, f64); } -/// Trait for types that can be transformed by a Transformation +/// Trait for types that can be transformed by a Transformation. pub trait Transformable: Clone { fn transform(&mut self, t: &Transformation) -> &mut Self; @@ -34,18 +34,24 @@ pub trait Transformable: Clone { } } -/// Trait for types that can be transformed based on a reference object with a Transformation applied +/// Trait for types that can be transformed based on a reference object with a Transformation applied. +/// Used for repeated transformations on an identical reference shape without reallocating new memory each time. pub trait TransformableFrom: Transformable { fn transform_from(&mut self, reference: &Self, t: &Transformation) -> &mut Self; } -/// Trait for shared properties of geometric primitives +/// Trait for shared properties of geometric primitives. pub trait Shape { + + /// Geometric center of the shape fn centroid(&self) -> Point; + /// Area of the interior of the shape fn area(&self) -> f64; + /// Bounding box of the shape fn bbox(&self) -> AARectangle; + /// The distance between the two furthest points in the shape. fn diameter(&self) -> f64; } diff --git a/jaguars/src/geometry/primitives/aa_rectangle.rs b/jaguars/src/geometry/primitives/aa_rectangle.rs index 17084f8..7527a71 100644 --- a/jaguars/src/geometry/primitives/aa_rectangle.rs +++ b/jaguars/src/geometry/primitives/aa_rectangle.rs @@ -8,7 +8,7 @@ use crate::geometry::primitives::edge::Edge; use crate::geometry::primitives::point::Point; use crate::util::f64a::F64A; -//Axis-aligned Rectangle +///Geometric primitive representing an axis-aligned rectangle #[derive(Clone, Debug, PartialEq)] pub struct AARectangle { pub x_min: f64, @@ -69,6 +69,7 @@ impl AARectangle { ] } + /// Returns the relation between self and another AARectangle pub fn relation_to(&self, other: &AARectangle) -> GeoRelation { if self.collides_with(other) { if self.x_min <= other.x_min && self.y_min <= other.y_min && @@ -87,6 +88,8 @@ impl AARectangle { } } + /// Returns the relation between self and another AARectangle, with a tolerance for floating point precision. + /// Leaning towards `Surrounding` and `Enclosed` instead of `Intersecting` in edge cases. pub fn almost_relation_to(&self, other: &AARectangle) -> GeoRelation { if self.almost_collides_with(other) { if F64A::from(self.x_min) <= F64A::from(other.x_min) && F64A::from(self.y_min) <= F64A::from(other.y_min) && @@ -136,10 +139,10 @@ impl AARectangle { self } - //array quadrant layout: [nw, ne, sw, se] - //e.g. cell with index 0 is neighbored by cells 1 and 2 + /// For all quadrants, contains indices of the two neighbors of the quadrant at that index pub const QUADRANT_NEIGHBOR_LAYOUT: [[usize; 2]; 4] = [[1, 2], [0, 3], [0, 3], [1, 2]]; + /// Returns the 4 quadrants of the rectangle, in the order NW, NE, SW, SE pub fn quadrants(&self) -> [Self; 4] { let Point(x_mid, y_mid) = self.centroid(); diff --git a/jaguars/src/geometry/primitives/circle.rs b/jaguars/src/geometry/primitives/circle.rs index 198ae66..46aafec 100644 --- a/jaguars/src/geometry/primitives/circle.rs +++ b/jaguars/src/geometry/primitives/circle.rs @@ -7,7 +7,7 @@ use crate::geometry::primitives::aa_rectangle::AARectangle; use crate::geometry::primitives::edge::Edge; use crate::geometry::primitives::point::Point; use crate::geometry::transformation::Transformation; - +/// Geometric primitive representing a circle #[derive(Clone, Debug, PartialEq)] pub struct Circle { pub center: Point, diff --git a/jaguars/src/geometry/primitives/edge.rs b/jaguars/src/geometry/primitives/edge.rs index 9b59cb7..3a8daff 100644 --- a/jaguars/src/geometry/primitives/edge.rs +++ b/jaguars/src/geometry/primitives/edge.rs @@ -4,6 +4,7 @@ use crate::geometry::primitives::aa_rectangle::AARectangle; use crate::geometry::primitives::point::Point; use crate::geometry::transformation::Transformation; +/// Geometric primitive representing a line segment #[derive(Clone, Debug, PartialEq)] pub struct Edge { pub start: Point, diff --git a/jaguars/src/geometry/primitives/point.rs b/jaguars/src/geometry/primitives/point.rs index 5948dac..05892f7 100644 --- a/jaguars/src/geometry/primitives/point.rs +++ b/jaguars/src/geometry/primitives/point.rs @@ -3,6 +3,7 @@ use std::hash::{Hash, Hasher}; use crate::geometry::geo_traits::{CollidesWith, Transformable, TransformableFrom}; use crate::geometry::transformation::Transformation; +/// Geometric primitive representing a point #[derive(Debug, Clone, PartialEq, Copy)] pub struct Point(pub f64, pub f64); diff --git a/jaguars/src/geometry/primitives/simple_polygon.rs b/jaguars/src/geometry/primitives/simple_polygon.rs index 311bf40..d60732e 100644 --- a/jaguars/src/geometry/primitives/simple_polygon.rs +++ b/jaguars/src/geometry/primitives/simple_polygon.rs @@ -18,8 +18,7 @@ use crate::geometry::transformation::Transformation; use crate::util::config::SPSurrogateConfig; use crate::util::f64a::F64A; -//https://en.wikipedia.org/wiki/Simple_polygon - +/// Geometric primitive representing a simple polygon: #[derive(Clone, Debug)] pub struct SimplePolygon { points: Vec, diff --git a/lbf/src/lbf_optimizer.rs b/lbf/src/lbf_optimizer.rs index 0fc901a..005f07e 100644 --- a/lbf/src/lbf_optimizer.rs +++ b/lbf/src/lbf_optimizer.rs @@ -38,7 +38,7 @@ pub struct LBFOptimizer { instance: Arc, problem: ProblemEnum, config: Config, - /// SmallRng is a fast, non-crypographic PRNG https://rust-random.github.io/book/guide-rngs.html + /// SmallRng is a fast, non-cryptographic PRNG rng: SmallRng, }