Skip to main content

conspire/geometry/segmentation/
mod.rs

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