geometry_algorithm/
expand.rs1use geometry_model::Box as ModelBox;
8use geometry_strategy::{EnvelopeStrategy, EnvelopeStrategyForKind};
9use geometry_trait::{Box as BoxTrait, Geometry, IndexedAccess, PointMut, corner, fold_dims};
10
11#[inline]
23pub fn expand<B, G, P>(bounds: &mut B, geometry: &G)
24where
25 B: BoxTrait<Point = P>,
26 G: Geometry<Point = P>,
27 P: PointMut + Default,
28 G::Kind: EnvelopeStrategyForKind,
29 <G::Kind as EnvelopeStrategyForKind>::S: EnvelopeStrategy<G, Output = ModelBox<P>> + Default,
30{
31 expand_with(
32 bounds,
33 geometry,
34 <<G::Kind as EnvelopeStrategyForKind>::S as Default>::default(),
35 );
36}
37
38#[inline]
45#[allow(
46 clippy::needless_pass_by_value,
47 reason = "envelope strategies are zero-sized or small Copy values, matching the crate's other _with entry points"
48)]
49pub fn expand_with<B, G, P, S>(bounds: &mut B, geometry: &G, strategy: S)
50where
51 B: BoxTrait<Point = P>,
52 G: Geometry<Point = P>,
53 P: PointMut + Default,
54 S: EnvelopeStrategy<G, Output = ModelBox<P>>,
55{
56 let incoming = strategy.envelope(geometry);
57
58 fold_dims((), incoming.min(), |(), _, dimension| match dimension {
59 0 => expand_dimension::<B, P, 0>(bounds, &incoming),
60 1 => expand_dimension::<B, P, 1>(bounds, &incoming),
61 2 => expand_dimension::<B, P, 2>(bounds, &incoming),
62 3 => expand_dimension::<B, P, 3>(bounds, &incoming),
63 _ => unreachable!("fold_dims limits point dimensions to MAX_DIM"),
64 });
65}
66
67#[inline]
68fn expand_dimension<B, P, const D: usize>(bounds: &mut B, incoming: &ModelBox<P>)
69where
70 B: BoxTrait<Point = P>,
71 P: PointMut,
72{
73 let incoming_min = incoming.get_indexed::<{ corner::MIN }, D>();
74 let incoming_max = incoming.get_indexed::<{ corner::MAX }, D>();
75 let current_min = bounds.get_indexed::<{ corner::MIN }, D>();
76 let current_max = bounds.get_indexed::<{ corner::MAX }, D>();
77
78 if incoming_min < current_min {
79 bounds.set_indexed::<{ corner::MIN }, D>(incoming_min);
80 }
81 if incoming_max > current_max {
82 bounds.set_indexed::<{ corner::MAX }, D>(incoming_max);
83 }
84}