use crate::{LabelFormat,LabelU16}; use avl_tree::*; #[derive(Debug)] pub struct Data { pub label: u16, pub area: usize, pub perimeter: usize, pub neighboring: usize, pub non_neighboring: usize, } impl Data { const fn new(label: u16, area: usize, perimeter: usize, neighboring: usize, non_neighboring: usize) -> Self { Self { label, area, perimeter, neighboring, non_neighboring, } } } fn any(a: &[bool]) -> bool { for value in a.iter() { if *value { return true; } } false } impl LabelFormat { pub fn get_tree(&self) -> AVLTree { let mut avt = avl_tree::AVLTree::::new(); for y in 0..self.height { for x in 0..self.width { let index = x + y * self.width; let key = self.buffer[index]; if key.is_zero() { continue; } let mut new_data = Data::new( key, 0, 0, 0, 0); match avt.get(key) { Some(data) => { new_data.area = data.area; new_data.perimeter = data.perimeter; new_data.neighboring = data.neighboring; new_data.non_neighboring = data.non_neighboring; }, None => { }, } let neighbors: [Option;4] = [ self.get_up(x,y), self.get_right(x,y), self.get_down(x,y), self.get_left(x,y), ]; let perimeter_slice = neighbors.map(|x| match x { Some(y) => (y.is_zero()) || (y != new_data.label), None => false, }); let add_perimeter = any(&perimeter_slice); let neighboring_slice = neighbors.map(|x| match x { Some(y) => (y != new_data.label) && (!y.is_zero()), None => false, }); let add_neighboring = any(&neighboring_slice); let non_neighboring_slice = neighbors.map(|x| match x { Some(y) => y.is_zero(), None => false, }); let add_non_neighboring = any(&non_neighboring_slice); // Always increase area new_data.area += 1; // Increase perimeter if there is a neighbor that is not the same cell if add_perimeter { new_data.perimeter += 1; } if add_non_neighboring { new_data.non_neighboring += 1; } if add_neighboring { new_data.neighboring += 1; } avt.insert(key, new_data); } } avt } } #[cfg(test)] mod tests { use super::*; #[test] fn get_areas_test() { const DIM: usize = 6; let mut test_data = LabelFormat:: { buffer: vec![0u16; DIM*DIM], width: DIM, height: DIM, }; test_data.buffer[2+3*DIM] = 1; test_data.buffer[3+3*DIM] = 1; test_data.buffer[4+3*DIM] = 2; test_data.idilate(); test_data.display(); for (key,val) in test_data.get_tree().iter() { println!("{} -> {:?}",key,val) } } }