microcad_core/geo3d/
align.rs1use cgmath::ElementWise;
7
8use crate::*;
9
10pub trait Align3D<T = Self> {
12 fn align_3d(&self, direction: Vec3, spacing: Length) -> T;
14}
15
16impl Align3D for Geometries3D {
17 fn align_3d(&self, direction: Vec3, spacing: Length) -> Self {
18 Geometries3D::from_iter(self.iter().scan(0.0_f64, |pos, geo3d| {
19 use cgmath::InnerSpace;
20
21 let bounds = geo3d.calc_bounds_3d();
22 let dir = if direction.magnitude() > f64::EPSILON {
23 direction.normalize()
24 } else {
25 Vec3::new(0.0, 0.0, 0.0)
26 };
27 let dist = *bounds.distance_center_to_boundary(dir);
28 let c = bounds.center();
29
30 let d = (*pos + dist) * dir - dir.mul_element_wise(c);
31 *pos += 2.0 * dist + *spacing;
32
33 Some(std::rc::Rc::new(
34 geo3d.transformed_3d(&Mat4::from_translation(d)),
35 ))
36 }))
37 }
38}