jagua_rs/geometry/
original_shape.rs

1use crate::geometry::DTransformation;
2use crate::geometry::geo_traits::Transformable;
3use crate::geometry::primitives::{Point, Rect, SPolygon};
4use crate::geometry::shape_modification::{
5    ShapeModifyConfig, ShapeModifyMode, close_narrow_concavities, offset_shape,
6    shape_modification_valid, simplify_shape,
7};
8use anyhow::Result;
9
10#[derive(Clone, Debug)]
11/// A [`SPolygon`] exactly as is defined in the input file
12///
13/// Also contains all required operation to convert it to a shape that can be used internally.
14/// Currently, these are centering and simplification operations, but could be extended in the future.
15pub struct OriginalShape {
16    pub shape: SPolygon,
17    pub pre_transform: DTransformation,
18    pub modify_mode: ShapeModifyMode,
19    pub modify_config: ShapeModifyConfig,
20}
21
22impl OriginalShape {
23    pub fn convert_to_internal(&self) -> Result<SPolygon> {
24        // Apply the transformation
25        let mut internal = self.shape.transform_clone(&self.pre_transform.compose());
26
27        if let Some(offset) = self.modify_config.offset {
28            // Offset the shape
29            if offset != 0.0 {
30                internal = offset_shape(&internal, self.modify_mode, offset)?;
31            }
32        }
33        if let Some(tolerance) = self.modify_config.simplify_tolerance {
34            let pre_simplified = internal.clone();
35            // Simplify the shape
36            internal = simplify_shape(&internal, self.modify_mode, tolerance);
37            if let Some(narrow_concavity_cutoff) = self.modify_config.narrow_concavity_cutoff {
38                // Close narrow concavities
39                internal =
40                    close_narrow_concavities(&internal, self.modify_mode, narrow_concavity_cutoff);
41                // Do another simplification after closing concavities
42                internal = simplify_shape(&internal, self.modify_mode, tolerance / 10.0);
43            }
44            debug_assert!(shape_modification_valid(
45                &pre_simplified,
46                &internal,
47                self.modify_mode
48            ));
49        }
50
51        Ok(internal)
52    }
53
54    pub fn centroid(&self) -> Point {
55        self.shape.centroid()
56    }
57
58    pub fn area(&self) -> f32 {
59        self.shape.area
60    }
61
62    pub fn bbox(&self) -> Rect {
63        self.shape.bbox
64    }
65
66    pub fn diameter(&self) -> f32 {
67        self.shape.diameter
68    }
69}