Skip to content
Snippets Groups Projects
Commit 55d28541 authored by Finn Bear's avatar Finn Bear
Browse files

Mosaic WIP edge detector.

parent 2b058171
No related branches found
No related tags found
No related merge requests found
......@@ -49,12 +49,16 @@ enum MosaicState {
actual_color: bool,
},
/// Automatically add triangles.
Triangles,
Triangles {
/// When we started fading in and using the edge detector.
edges: Option<(f64, Grid)>,
},
}
impl Default for Mosaic {
fn default() -> Self {
let grid = Grid {
name: "mosaic",
size_pixels: 512.0,
size_cells: 256,
alpha: 1.0,
......@@ -118,10 +122,44 @@ impl Slide for Mosaic {
let (points, color) = triangle.polygon(self.grid.size_cells as u32).unwrap();
draw_polygon_mut(&mut self.grid, &points, color);
} else {
self.state = MosaicState::Triangles;
self.state = MosaicState::Triangles { edges: None };
}
}
MosaicState::Triangles { edges } => {
if edges.is_none() {
const EDGE_RESOLUTION: usize = 180;
let mut grid = Grid {
name: "edges",
position: WindowPosition::FromCenter(Vec2::new(-170.0, 130.0)),
size_cells: EDGE_RESOLUTION,
size_pixels: EDGE_RESOLUTION as f32,
stroke_width: 0.0,
margin: 8.0,
background: Color32::BLACK,
..Grid::default()
};
for (x, y, c) in grid.iter_mut() {
// Edge detection kernel.
let image_x = x * self.image.width() / EDGE_RESOLUTION;
if image_x == 0 {
// Oops, we're at the edge.
continue;
}
let image_y = y * self.image.height() / EDGE_RESOLUTION;
let center = self.image[(image_x, image_y)];
let side = self.image[(image_x - 1, image_y)];
let (diff, max_diff) = color_diff(center, side);
*c = set_alpha(Color32::WHITE, diff as f32 / max_diff as f32);
}
*edges = Some((ctx.input().time, grid));
} else {
// Done with slide.
return true;
}
}
MosaicState::Triangles => return true,
}
false
}
......@@ -141,15 +179,14 @@ impl Slide for Mosaic {
let mut max_error = 0;
for (x, y, est) in self.grid.iter() {
let truth = self.image[(x, y)];
for c in 0..4 {
error += truth.to_array()[c].abs_diff(est.to_array()[c]) as usize;
max_error += truth.to_array()[c] as usize;
}
let (e, me) = color_diff(truth, est);
error += e;
max_error += me;
}
let error_text =
format!("{:.1}% error", 100.0 * error as f32 / max_error as f32);
match &self.state {
MosaicState::Triangles => {
MosaicState::Triangles { .. } => {
ui.label(format!("{} triangles ➡ {}", self.count, error_text))
}
_ => ui.label(error_text),
......@@ -171,15 +208,6 @@ impl Slide for Mosaic {
let mut rng = thread_rng();
/*
match &self.state {
&MosaicState::Triangle {actual_color, ..} => {
}
_ => {}
}
*/
while self.triangles.len() > 10 {
// De-queue triangles to CPU rasterize them.
let triangle = self.triangles.pop_front().unwrap();
......@@ -192,8 +220,8 @@ impl Slide for Mosaic {
self.grid.show_with_overlays(ui.ctx(), |ui, to_screen| {
ui.ctx().request_repaint();
match &self.state {
&MosaicState::Point { fade_start } => {
match &mut self.state {
&mut MosaicState::Point { fade_start } => {
fade_in_manual(ui, fade_start, |ui, alpha| {
let center = to_screen * Self::RANDOM_POINT;
ui.painter().add(Shape::Circle(CircleShape {
......@@ -214,7 +242,7 @@ impl Slide for Mosaic {
.show(ui);
});
}
&MosaicState::Triangle {
&mut MosaicState::Triangle {
fade_start,
actual_color,
} => {
......@@ -248,7 +276,7 @@ impl Slide for Mosaic {
}));
}
}
&MosaicState::Triangles => {
MosaicState::Triangles { edges } => {
for _ in 0..(self.count / 8 + 10).min(537) {
let x: f32 = rng.gen();
let y: f32 = rng.gen();
......@@ -271,6 +299,13 @@ impl Slide for Mosaic {
self.triangles.push_back(triangle);
}
if let Some((fade_start, edges)) = edges.as_mut() {
fade_in_manual(ui, *fade_start, |ui, alpha| {
edges.alpha = alpha;
edges.show(ui.ctx());
});
}
}
_ => {}
}
......@@ -287,6 +322,16 @@ impl Slide for Mosaic {
}
}
fn color_diff(a: Color32, b: Color32) -> (usize, usize) {
let mut error = 0;
let mut max_error = 0;
for c in 0..4 {
error += a.to_array()[c].abs_diff(b.to_array()[c]) as usize;
max_error += a.to_array()[c] as usize;
}
(error, max_error)
}
/// Gets the color from the image at the fractional position.
fn image_lookup(image: &ColorImage, pos: Pos2) -> Color32 {
let image_x = ((pos.x * image.width() as f32) as usize).min(image.width() - 1);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment