use crate::{Edge, ForegroundColor};
pub struct NeighborInfo {
pub filled: u8,
pub neighbors: u8,
pub edge_status: [Edge; 8],
}
impl NeighborInfo {
pub fn transitions(&self) -> u8 {
let [p2, p3, p4, p5, p6, p7, p8, p9] = self.edge_status;
let mut transitions = 0;
for pair in [p2, p3, p4, p5, p6, p7, p8, p9, p2].windows(2) {
if pair[0] == Edge::Empty && pair[1] == Edge::Filled {
transitions += 1;
}
}
transitions
}
}
pub fn get_neighbor_info<F: ForegroundColor>(
img: &image::GrayImage,
width: u32,
height: u32,
x: u32,
y: u32,
) -> NeighborInfo {
let mut filled = 0;
let mut neighbors = 0;
let p9 = if y > 0 && x > 0 {
neighbors += 1;
if img.get_pixel(x - 1, y - 1)[0] != F::BACKGROUND_COLOR {
filled += 1;
Edge::Filled
} else {
Edge::Empty
}
} else {
Edge::DoesNotExist
};
let p2 = if y > 0 {
neighbors += 1;
if img.get_pixel(x, y - 1)[0] != F::BACKGROUND_COLOR {
filled += 1;
Edge::Filled
} else {
Edge::Empty
}
} else {
Edge::DoesNotExist
};
let p3 = if y > 0 && x < u32::MAX && x + 1 < width {
neighbors += 1;
if img.get_pixel(x + 1, y - 1)[0] != F::BACKGROUND_COLOR {
filled += 1;
Edge::Filled
} else {
Edge::Empty
}
} else {
Edge::DoesNotExist
};
let p8 = if x > 0 {
neighbors += 1;
if img.get_pixel(x - 1, y)[0] != F::BACKGROUND_COLOR {
filled += 1;
Edge::Filled
} else {
Edge::Empty
}
} else {
Edge::DoesNotExist
};
let p4 = if x < u32::MAX && x + 1 < width {
neighbors += 1;
if img.get_pixel(x + 1, y)[0] != F::BACKGROUND_COLOR {
filled += 1;
Edge::Filled
} else {
Edge::Empty
}
} else {
Edge::DoesNotExist
};
let p7 = if x > 0 && y < u32::MAX && y + 1 < height {
neighbors += 1;
if img.get_pixel(x - 1, y + 1)[0] != F::BACKGROUND_COLOR {
filled += 1;
Edge::Filled
} else {
Edge::Empty
}
} else {
Edge::DoesNotExist
};
let p6 = if y < u32::MAX && y + 1 < height {
neighbors += 1;
if img.get_pixel(x, y + 1)[0] != F::BACKGROUND_COLOR {
filled += 1;
Edge::Filled
} else {
Edge::Empty
}
} else {
Edge::DoesNotExist
};
let p5 = if x < u32::MAX && x + 1 < width && y < u32::MAX && y + 1 < height {
neighbors += 1;
if img.get_pixel(x + 1, y + 1)[0] != F::BACKGROUND_COLOR {
filled += 1;
Edge::Filled
} else {
Edge::Empty
}
} else {
Edge::DoesNotExist
};
NeighborInfo {
filled,
neighbors,
edge_status: [p2, p3, p4, p5, p6, p7, p8, p9],
}
}