distance_transform/
grid.rs

1//! This module contains type definitions for two-dimensional grids
2//! that are used in the distance transform methods.
3
4use std::slice::{Iter,IterMut};
5
6/// A two-dimensional grid of an arbitrary type `T`
7#[derive(Debug,Clone)]
8pub struct GenericGrid<T> {
9    data: Vec<T>,
10    width: usize,
11    height: usize,
12}
13
14impl<T: Default+Clone> GenericGrid<T> {
15    /// Constructs a new two-dimensional `GenericGrid<T>`
16    /// of size `width`x`height` with default values of type `T`.
17    pub fn new(width: usize, height: usize) -> GenericGrid<T> {
18        GenericGrid { data: vec![T::default(); height*width], width, height }
19    }
20
21    /// Returns the width of the grid
22    pub fn height(&self) -> usize {
23        self.height
24    }
25
26    /// Returns the height of the grid
27    pub fn width(&self) -> usize {
28        self.width
29    }
30
31    /// Returns the element at position (x, y), or `None` if the position
32    /// is out of bounds.
33    pub fn get(&self, x: usize, y: usize) -> Option<&T> {
34        if x >= self.width || y >= self.height {
35            return None;
36        }
37        Some(self.get_unchecked(x, y))
38    }
39
40    /// Returns a pointer to the element at position (x, y), without doing
41    /// bounds checking.
42    pub fn get_unchecked(&self, x: usize, y: usize) -> &T {
43        &self.data[y*self.width+x]
44    }
45
46    /// Sets the value of the grid at position (x,y)
47    pub fn set(&mut self, x: usize, y: usize, value: T) {
48        self.data[y*self.width+x] = value;
49    }
50
51    /// Converts the `GenericGrid<T>` to a `Vec<T>` with indexing
52    /// `grid[x, y] == vec[y*grid.width + x]`
53    pub fn to_vec(self) -> Vec<T> {
54        self.data
55    }
56
57    /// Returns an iterator over the nodes of the grid.
58    /// An item of the iterator contains the position
59    /// and a reference to the node: `(x, y, value)`
60    pub fn iter(&self) -> GridIter<T> {
61        GridIter {
62            data_it: self.data.iter(),
63            width: self.width,
64            pos: 0,
65        }
66    }
67
68    /// Returns an iterator over the nodes of the grid.
69    /// An item of the iterator contains the position
70    /// and a mutable reference to the node: `(x, y, value)`
71    pub fn iter_mut(&mut self) -> GridIterMut<T> {
72        GridIterMut {
73            data_it: self.data.iter_mut(),
74            width: self.width,
75            pos: 0,
76        }
77    }
78}
79
80/// Iterate over the nodes of a grid.
81#[derive(Debug)]
82pub struct GridIter<'a, T: 'a> {
83    data_it: Iter<'a, T>,
84    width: usize,
85    pos: usize,
86}
87
88impl<'a, T> Iterator for GridIter<'a, T> {
89    type Item = (usize, usize, &'a T);
90
91    fn next(&mut self) -> Option<Self::Item> {
92        match self.data_it.next() {
93            Some(val) => {
94                let res = (self.pos % self.width, self.pos/self.width, val);
95                self.pos += 1;
96                Some(res)
97            },
98            None => None,
99        }
100    }
101}
102
103/// Iterate mutably over the nodes of a grid.
104#[derive(Debug)]
105pub struct GridIterMut<'a, T: 'a> {
106    data_it: IterMut<'a, T>,
107    width: usize,
108    pos: usize,
109}
110
111impl<'a, T> Iterator for GridIterMut<'a, T> {
112    type Item = (usize, usize, &'a mut T);
113
114    fn next(&mut self) -> Option<Self::Item> {
115        match self.data_it.next() {
116            Some(val) => {
117                let res = (self.pos % self.width, self.pos/self.width, val);
118                self.pos += 1;
119                Some(res)
120            },
121            None => None,
122        }
123    }
124}
125
126/// two-dimensional grid of `f64` values
127pub type FloatGrid = GenericGrid<f64>;
128
129/// two-dimensional grid of `bool` values
130pub type BoolGrid  = GenericGrid<bool>;