jagua_rs/geometry/fail_fast/
sp_surrogate.rs1use crate::geometry::Transformation;
2use crate::geometry::convex_hull;
3use crate::geometry::fail_fast::{piers, pole};
4use crate::geometry::geo_traits::{Transformable, TransformableFrom};
5use crate::geometry::primitives::Circle;
6use crate::geometry::primitives::Edge;
7use crate::geometry::primitives::SPolygon;
8use itertools::Itertools;
9use serde::{Deserialize, Serialize};
10
11use anyhow::Result;
12
13#[derive(Clone, Debug)]
14pub struct SPSurrogate {
18 pub poles: Vec<Circle>,
20 pub piers: Vec<Edge>,
22 pub convex_hull_indices: Vec<usize>,
24 pub convex_hull_area: f32,
26 pub config: SPSurrogateConfig,
28}
29
30impl SPSurrogate {
31 pub fn new(simple_poly: &SPolygon, config: SPSurrogateConfig) -> Result<Self> {
34 let convex_hull_indices = convex_hull::convex_hull_indices(simple_poly);
35 let convex_hull_points = convex_hull_indices
36 .iter()
37 .map(|&i| simple_poly.vertices[i])
38 .collect_vec();
39 let convex_hull_area = SPolygon::calculate_area(&convex_hull_points);
40 let poles = pole::generate_surrogate_poles(simple_poly, &config.n_pole_limits)?;
41 let n_ff_poles = usize::min(config.n_ff_poles, poles.len());
42 let relevant_poles_for_piers = &poles[0..n_ff_poles]; let piers =
44 piers::generate_piers(simple_poly, config.n_ff_piers, relevant_poles_for_piers)?;
45
46 Ok(Self {
47 convex_hull_indices,
48 poles,
49 piers,
50 convex_hull_area,
51 config,
52 })
53 }
54
55 pub fn ff_poles(&self) -> &[Circle] {
56 &self.poles[0..self.config.n_ff_poles]
57 }
58
59 pub fn ff_piers(&self) -> &[Edge] {
60 &self.piers
61 }
62}
63
64impl Transformable for SPSurrogate {
65 fn transform(&mut self, t: &Transformation) -> &mut Self {
66 let Self {
68 convex_hull_indices: _,
69 poles,
70 piers,
71 convex_hull_area: _,
72 config: _,
73 } = self;
74
75 poles.iter_mut().for_each(|c| {
77 c.transform(t);
78 });
79
80 piers.iter_mut().for_each(|p| {
82 p.transform(t);
83 });
84
85 self
86 }
87}
88
89impl TransformableFrom for SPSurrogate {
90 fn transform_from(&mut self, reference: &Self, t: &Transformation) -> &mut Self {
91 debug_assert!(self.poles.len() == reference.poles.len());
92 debug_assert!(self.piers.len() == reference.piers.len());
93
94 let Self {
96 convex_hull_indices: _,
97 poles,
98 piers,
99 convex_hull_area: _,
100 config: _,
101 } = self;
102
103 for (pole, ref_pole) in poles.iter_mut().zip(reference.poles.iter()) {
104 pole.transform_from(ref_pole, t);
105 }
106
107 for (pier, ref_pier) in piers.iter_mut().zip(reference.piers.iter()) {
108 pier.transform_from(ref_pier, t);
109 }
110
111 self
112 }
113}
114
115const N_POLE_LIMITS: usize = 3;
117
118#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq)]
120pub struct SPSurrogateConfig {
121 pub n_pole_limits: [(usize, f32); N_POLE_LIMITS],
127 pub n_ff_poles: usize,
129 pub n_ff_piers: usize,
131}
132
133impl SPSurrogateConfig {
134 pub fn none() -> Self {
135 Self {
136 n_pole_limits: [(0, 0.0); N_POLE_LIMITS],
137 n_ff_poles: 0,
138 n_ff_piers: 0,
139 }
140 }
141}