Skip to main content

conspire/geometry/segmentation/
mod.rs

1#[cfg(test)]
2mod test;
3
4use crate::{
5    geometry::{Coordinate, grid::Grid},
6    math::Quantity,
7};
8use std::{
9    array::from_fn,
10    ops::{Deref, DerefMut, Range},
11};
12
13pub type Segmentation2D<T> = Segmentation<2, T>;
14pub type Segmentation3D<T> = Segmentation<3, T>;
15
16pub struct Segmentation<const D: usize, T> {
17    grid: Grid<D, T>,
18    scale: Coordinate<D>,
19    translate: Coordinate<D>,
20}
21
22impl<const D: usize, T> Segmentation<D, T> {
23    pub fn new(grid: Grid<D, T>, scale: Coordinate<D>, translate: Coordinate<D>) -> Self {
24        assert!(
25            (0..D).all(|axis| scale[axis] > Quantity::default()),
26            "scale must be positive in every direction"
27        );
28        Self {
29            grid,
30            scale,
31            translate,
32        }
33    }
34    pub fn grid(&self) -> &Grid<D, T> {
35        &self.grid
36    }
37    pub fn into_parts(self) -> (Grid<D, T>, Coordinate<D>, Coordinate<D>) {
38        (self.grid, self.scale, self.translate)
39    }
40    pub fn scale(&self) -> &Coordinate<D> {
41        &self.scale
42    }
43    pub fn translate(&self) -> &Coordinate<D> {
44        &self.translate
45    }
46}
47
48impl<const D: usize, T: Copy> Segmentation<D, T> {
49    pub fn extract(&self, ranges: [Range<usize>; D]) -> Self {
50        let translate = from_fn::<_, D, _>(|axis| {
51            self.translate[axis] + ranges[axis].start as f64 * self.scale[axis]
52        })
53        .into();
54        Self {
55            grid: self.grid.extract(ranges),
56            scale: self.scale.clone(),
57            translate,
58        }
59    }
60}
61
62impl<const D: usize, T> From<Grid<D, T>> for Segmentation<D, T> {
63    fn from(grid: Grid<D, T>) -> Self {
64        Self {
65            grid,
66            scale: [1.0; D].into(),
67            translate: [0.0; D].into(),
68        }
69    }
70}
71
72impl<const D: usize, T> Deref for Segmentation<D, T> {
73    type Target = Grid<D, T>;
74    fn deref(&self) -> &Self::Target {
75        &self.grid
76    }
77}
78
79impl<const D: usize, T> DerefMut for Segmentation<D, T> {
80    fn deref_mut(&mut self) -> &mut Self::Target {
81        &mut self.grid
82    }
83}