Skip to content

Commit

Permalink
improved docs
Browse files Browse the repository at this point in the history
  • Loading branch information
JeroenGar committed Feb 28, 2024
1 parent d78276e commit 6e0a364
Show file tree
Hide file tree
Showing 8 changed files with 63 additions and 38 deletions.
17 changes: 10 additions & 7 deletions jagua-rs/src/collision_detection/hazard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@ use crate::entities::placed_item::PlacedItemUID;
use crate::geometry::geo_enums::GeoPosition;
use crate::geometry::primitives::simple_polygon::SimplePolygon;

/// Defines a certain spatial constraint that affects the feasibility of placed items
/// Hazards are defined by a certain entity, have a shape and can be active or inactive
/// Defines a certain spatial constraint that affects the feasibility of an item placement.
#[derive(Clone, Debug)]
pub struct Hazard {
/// The entity inducing the hazard
pub entity: HazardEntity,
/// The shape of the hazard
pub shape: Arc<SimplePolygon>,
/// Whether the hazard is currently active or not
/// Hazards can be either active or inactive, inactive hazards are not considered during collision detection
pub active: bool,
}

Expand All @@ -27,16 +26,20 @@ impl Hazard {
}

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
/// Entity inducing a hazard, every hazard entity must be unique
/// Entity inducing the `Hazard`. All entities are uniquely identified.
pub enum HazardEntity {
/// An item placed in the layout.
PlacedItem(PlacedItemUID),
/// Represents all regions outside the bin
BinExterior,
/// Represents a hole in the bin.
BinHole { id: usize },
/// Represents a zone in the bin with a specific quality level that is inferior to the base quality.
QualityZoneInferior { quality: usize, id: usize },
}

impl HazardEntity {
/// Whether the entity induces an Interior or Exterior hazard
/// Whether the entity induces an `Interior` or `Exterior` hazard
pub fn position(&self) -> GeoPosition {
match self {
HazardEntity::PlacedItem(_) => GeoPosition::Interior,
Expand All @@ -46,7 +49,7 @@ impl HazardEntity {
}
}

/// True if the hazard is dynamic in nature, i.e. it can be modified by the optimizer
/// Whether the entity is dynamic in nature, i.e. it can be modified in the layout
pub fn dynamic(&self) -> bool {
match self {
HazardEntity::PlacedItem(_) => true,
Expand All @@ -56,7 +59,7 @@ impl HazardEntity {
}
}

/// Returns true if the hazard is universally applicable, i.e. all items are affected by it
/// Whether the entity universally applicable, i.e. all items need to be checked against it
pub fn universal(&self) -> bool {
match self {
HazardEntity::PlacedItem(_) => true,
Expand Down
20 changes: 10 additions & 10 deletions jagua-rs/src/collision_detection/hazard_filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ use itertools::Itertools;
use crate::collision_detection::hazard::Hazard;
use crate::collision_detection::hazard::HazardEntity;

/// Trait that allows for filtering out irrelevant hazards depending on the context.
/// Enables ignoring certain hazards when querying the CDE.
/// Trait that allows for ignoring out specific hazards.
/// Enables querying the `CDEngine` only for relevant hazards.
pub trait HazardFilter {
fn is_irrelevant(&self, entity: &HazardEntity) -> bool;
}

/// Returns the entities that are deemed irrelevant by the given filter from a set of `Hazard`s
/// Returns the entities that are deemed irrelevant by the specified `HazardFilter`.
pub fn generate_irrelevant_hazards<'a>(
filter: &impl HazardFilter,
hazards: impl Iterator<Item = &'a Hazard>,
Expand All @@ -26,22 +26,22 @@ pub fn generate_irrelevant_hazards<'a>(
#[derive(Clone)]
pub struct BinHazardFilter;

/// Deems hazards induced by `QualityZone`s above a certain quality as irrelevant
/// Deems hazards induced by `QualityZone`s above a certain quality as irrelevant.
#[derive(Clone, Debug)]
pub struct QZHazardFilter {
pub cutoff_quality: usize,
}

/// Combines multiple `HazardFilter`s into a single filter
pub struct CombinedHazardFilter<'a> {
pub filters: Vec<Box<&'a dyn HazardFilter>>,
}

/// Deems hazards induced by specific entities as irrelevant
/// Deems hazards induced by specific entities as irrelevant.
pub struct EntityHazardFilter {
pub entities: Vec<HazardEntity>,
}

/// Combines multiple `HazardFilter`s into a single filter.
pub struct CombinedHazardFilter<'a> {
pub filters: Vec<Box<&'a dyn HazardFilter>>,
}

impl HazardFilter for BinHazardFilter {
fn is_irrelevant(&self, entity: &HazardEntity) -> bool {
match entity {
Expand Down
3 changes: 1 addition & 2 deletions jagua-rs/src/geometry/primitives/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
pub mod aa_rectangle;
pub mod circle;
pub mod edge;
pub mod point;
pub mod simple_polygon;

pub mod circle;
7 changes: 6 additions & 1 deletion jagua-rs/src/geometry/primitives/simple_polygon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,16 @@ use crate::util::f64a::F64A;
/// Geometric primitive representing a simple polygon: <https://en.wikipedia.org/wiki/Simple_polygon>
#[derive(Clone, Debug)]
pub struct SimplePolygon {
/// Set of bounds describing the polygon
pub points: Vec<Point>,
/// Bounding box
pub bbox: AARectangle,
pub area: f64,
/// Maximum distance between any two points in the polygon
pub diameter: f64,
/// Pole of inaccessibility
pub poi: Circle,
/// Surrogate representation (subset of the simple polygon)
pub surrogate: Option<SPSurrogate>,
}

Expand Down Expand Up @@ -129,7 +134,7 @@ impl SimplePolygon {
}

//https://en.wikipedia.org/wiki/Shoelace_formula
//counter clockwise = positive area, clockwise = negative area
//counterclockwise = positive area, clockwise = negative area
pub fn calculate_area(points: &[Point]) -> f64 {
let mut sigma: f64 = 0.0;
for i in 0..points.len() {
Expand Down
17 changes: 11 additions & 6 deletions jagua-rs/src/io/json_instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ pub struct JsonInstance {
/// Set of items to be produced
#[serde(rename = "Items")]
pub items: Vec<JsonItem>,
/// Set of bins where the items are to be placed (for Bin Packing problems)
/// Containers for a Bin Packing Problem
#[serde(rename = "Objects")]
#[serde(skip_serializing_if = "Option::is_none")]
pub bins: Option<Vec<JsonBin>>,
/// A strip where the items are to be placed (for Strip Packing problems)
/// Container for a Strip Packing Problem
#[serde(rename = "Strip")]
#[serde(skip_serializing_if = "Option::is_none")]
pub strip: Option<JsonStrip>,
Expand All @@ -34,7 +34,7 @@ pub struct JsonBin {
pub zones: Vec<JsonQualityZone>,
}

/// The JSON representation of a strip
/// The JSON representation of a strip with fixed height and variable width
#[derive(Serialize, Deserialize, Clone)]
#[serde(rename_all = "PascalCase")]
pub struct JsonStrip {
Expand All @@ -47,7 +47,7 @@ pub struct JsonStrip {
pub struct JsonItem {
/// Number of times this item should be produced
pub demand: u64,
/// List of allowed orientations angles (in degrees), if not present, any orientation is allowed
/// List of allowed orientations angles (in degrees). If none any orientation is allowed
#[serde(skip_serializing_if = "Option::is_none")]
pub allowed_orientations: Option<Vec<f64>>,
/// Polygon shape of the item
Expand All @@ -58,13 +58,18 @@ pub struct JsonItem {
pub base_quality: Option<usize>,
}

/// An enum containing all the possible possibilities to define a shape
/// All possible ways to represent a shape
#[derive(Serialize, Deserialize, Clone)]
#[serde(tag = "Type", content = "Data")]
#[serde(rename_all = "PascalCase")]
pub enum JsonShape {
/// Axis-aligned rectangle
Rectangle { width: f64, height: f64 },
/// Polygon with a single outer boundary
SimplePolygon(JsonSimplePoly),
/// Polygon with a single outer boundary and a list of holes
Polygon(JsonPoly),
/// Multiple disjoint polygons
MultiPolygon(Vec<JsonPoly>),
}

Expand All @@ -75,7 +80,7 @@ pub struct JsonPoly {
/// The outer boundary of the polygon
pub outer: JsonSimplePoly,
/// A list of holes in the polygon
#[serde(skip_serializing_if = "Vec::is_empty", default)]
#[serde(default)]
pub inner: Vec<JsonSimplePoly>,
}

Expand Down
4 changes: 2 additions & 2 deletions jagua-rs/src/io/json_solution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ pub enum JsonContainer {
index: usize,
},
Strip {
/// The length of the strip (variable)
#[serde(rename = "Length")]
/// The width of the strip (variable)
#[serde(rename = "Width")]
width: f64,
/// The height of the strip (fixed)
#[serde(rename = "Height")]
Expand Down
15 changes: 14 additions & 1 deletion jagua-rs/src/io/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use crate::entities::solution::Solution;
use crate::geometry::d_transformation::DTransformation;
use crate::geometry::geo_enums::AllowedRotation;
use crate::geometry::geo_traits::{Shape, Transformable};
use crate::geometry::primitives::aa_rectangle::AARectangle;
use crate::geometry::primitives::point::Point;
use crate::geometry::primitives::simple_polygon::SimplePolygon;
use crate::geometry::transformation::Transformation;
Expand Down Expand Up @@ -62,6 +63,10 @@ impl Parser {
for (item_id, json_item) in json_instance.items.iter().enumerate() {
let handle = s.spawn(move |_| {
let (shape, centering_transf) = match &json_item.shape {
JsonShape::Rectangle{ width, height } => {
let shape = SimplePolygon::from(AARectangle::new(0.0, 0.0, *width, *height));
(shape, Transformation::empty())
}
JsonShape::SimplePolygon(sp) => convert_json_simple_poly(
sp,
self.center_polygons,
Expand Down Expand Up @@ -118,6 +123,10 @@ impl Parser {
for (bin_id, json_bin) in json_bins.iter().enumerate() {
let handle = s.spawn(move |_| {
let (bin_outer, centering_transf) = match &json_bin.shape {
JsonShape::Rectangle {width, height} => {
let shape = SimplePolygon::from(AARectangle::new(0.0, 0.0, *width, *height));
(shape, Transformation::empty())
}
JsonShape::SimplePolygon(jsp) => convert_json_simple_poly(
jsp,
self.center_polygons,
Expand All @@ -136,7 +145,7 @@ impl Parser {
};

let bin_holes = match &json_bin.shape {
JsonShape::SimplePolygon(_) => vec![],
JsonShape::SimplePolygon(_) | JsonShape::Rectangle {..} => vec![],
JsonShape::Polygon(jp) => jp
.inner
.iter()
Expand Down Expand Up @@ -172,6 +181,10 @@ impl Parser {
.filter(|zone| zone.quality == quality)
.map(|zone| {
let (zone_shape, _) = match &zone.shape {
JsonShape::Rectangle { width, height } => {
let shape = SimplePolygon::from(AARectangle::new(0.0, 0.0, *width, *height));
(shape, Transformation::empty())
}
JsonShape::SimplePolygon(jsp) => convert_json_simple_poly(
jsp,
false,
Expand Down
18 changes: 9 additions & 9 deletions lbf/src/samplers/ls_sampler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,19 @@ impl LSSampler {
sd_transl_range: (f64, f64),
sd_rot_range: (f64, f64),
) -> Self {
let stddev_transl = sd_transl_range.0;
let stddev_rot = sd_rot_range.0;
let sd_transl = sd_transl_range.0;
let sd_rot = sd_rot_range.0;

let normal_x = Normal::new(ref_transform.translation().0, stddev_transl).unwrap();
let normal_y = Normal::new(ref_transform.translation().1, stddev_transl).unwrap();
let normal_r = NormalRotDistr::from_item(item, ref_transform.rotation(), stddev_rot);
let normal_x = Normal::new(ref_transform.translation().0, sd_transl).unwrap();
let normal_y = Normal::new(ref_transform.translation().1, sd_transl).unwrap();
let normal_r = NormalRotDistr::from_item(item, ref_transform.rotation(), sd_rot);

Self {
normal_x,
normal_y,
normal_r,
sd_transl: stddev_transl,
sd_rot: stddev_rot,
sd_transl,
sd_rot,
sd_transl_range,
sd_rot_range,
}
Expand All @@ -58,8 +58,8 @@ impl LSSampler {
/// Creates a new sampler with default standard deviation ranges: [SD_TRANSL] and [SD_ROT].
pub fn from_defaults(item: &Item, ref_transform: &DTransformation, bbox: &AARectangle) -> Self {
let max_dim = f64::max(bbox.width(), bbox.height());
let stddev_transl_range = (SD_TRANSL.0 * max_dim, SD_TRANSL.1 * max_dim);
Self::new(item, ref_transform, stddev_transl_range, SD_ROT)
let sd_transl_range = (SD_TRANSL.0 * max_dim, SD_TRANSL.1 * max_dim);
Self::new(item, ref_transform, sd_transl_range, SD_ROT)
}

/// Shifts the mean of the normal distributions to the given reference transformation.
Expand Down

0 comments on commit 6e0a364

Please sign in to comment.