fast_sweeping/
obstacles.rs

1use crate::{Grid, SavePgm};
2use std::fs::File;
3use std::io::Write;
4use std::path::PathBuf;
5use std::slice::{from_raw_parts_mut, Iter, IterMut};
6
7/// Binary map of obstacles.
8pub struct Obstacles {
9    pub(crate) obstacles: Vec<bool>,
10    pub(crate) width: usize,
11    pub(crate) height: usize,
12}
13
14impl Obstacles {
15    pub fn new(width: usize, height: usize) -> Self {
16        Self {
17            obstacles: vec![false; width * height],
18            width,
19            height,
20        }
21    }
22
23    #[inline(always)]
24    pub fn iter(&self) -> Iter<'_, bool> {
25        self.obstacles.iter()
26    }
27
28    #[inline(always)]
29    pub fn iter_mut(&mut self) -> IterMut<'_, bool> {
30        self.obstacles.iter_mut()
31    }
32}
33
34impl Grid for Obstacles {
35    type Item = bool;
36
37    #[inline(always)]
38    fn get_at(&self, x: usize, y: usize) -> &Self::Item {
39        &self.obstacles[y * self.width + x]
40    }
41
42    #[inline(always)]
43    fn set_at(&mut self, x: usize, y: usize, value: Self::Item) {
44        self.obstacles[y * self.width + x] = value
45    }
46
47    #[inline(always)]
48    #[allow(dead_code)]
49    fn get_rows_mut(&mut self, y: usize) -> (&mut [Self::Item], &mut [Self::Item]) {
50        let top = y * self.width;
51        let bottom = (y + 1) * self.width;
52        let ptr = self.obstacles.as_mut_ptr();
53        unsafe {
54            (
55                from_raw_parts_mut(ptr.add(top), self.width),
56                from_raw_parts_mut(ptr.add(bottom), self.width),
57            )
58        }
59    }
60
61    #[inline(always)]
62    fn iter(&self) -> Iter<'_, Self::Item> {
63        self.iter()
64    }
65
66    #[inline(always)]
67    fn iter_mut(&mut self) -> IterMut<'_, Self::Item> {
68        self.iter_mut()
69    }
70}
71
72impl SavePgm for Obstacles {
73    fn save_pgm(&self, file_name: &PathBuf) -> std::io::Result<()> {
74        let mut file = File::create(file_name)?;
75
76        let max_value: u8 = 255;
77
78        // Write the header
79        let header = format!("P5\n{} {}\n{}\n", self.width, self.height, max_value);
80        file.write_all(header.as_bytes())?;
81
82        // Convert and write the pixel data as binary
83        for &is_obstacle in self.iter() {
84            let value = (!is_obstacle as u8) * max_value;
85            file.write_all(&[value])?;
86        }
87
88        Ok(())
89    }
90}