diff --git a/src/mandelbrot.rs b/src/mandelbrot.rs index 04d1138..1cd8477 100644 --- a/src/mandelbrot.rs +++ b/src/mandelbrot.rs @@ -1,7 +1,7 @@ use num_complex::Complex; use rayon::prelude::*; -const MAX_ITERATIONS: u16 = 1024; +const MAX_ITERATIONS: u16 = 512; #[derive(Debug, Clone)] pub struct Mandelbrot { @@ -9,9 +9,15 @@ pub struct Mandelbrot { } enum Colour { + Purple, + Violet, + Blue, + Green, + Yellow, + Orange, + Red, White, Black, - Gray, } impl Mandelbrot { @@ -33,35 +39,13 @@ impl Mandelbrot { } pub fn generate_image(&mut self) -> Vec { - // Create the image - // Pixel Format can be Rgba8UnormSrgb - self.escape_time(); + self.escape_time((-2.5, 1.0), (-1.0, 1.0)); let mut texture_buffer = vec![0; (Self::IMG_WIDTH * Self::IMG_HEIGHT) * 4]; - for i in 0..texture_buffer.len() { if i % 4 == 0 { let iter_i = i / 4; - match Self::find_colour(self.iterations[iter_i]) { - Colour::White => { - texture_buffer[i] = 0x00; - texture_buffer[i + 1] = 0x00; - texture_buffer[i + 2] = 0x00; - texture_buffer[i + 3] = 0xFF; - } - Colour::Black => { - texture_buffer[i] = 0xFF; - texture_buffer[i + 1] = 0xFF; - texture_buffer[i + 2] = 0xFF; - texture_buffer[i + 3] = 0xFF; - } - Colour::Gray => { - texture_buffer[i] = 0xAA; - texture_buffer[i + 1] = 0xAA; - texture_buffer[i + 2] = 0xAA; - texture_buffer[i + 3] = 0xFF; - } - } + self.assign_colour(i, iter_i, &mut texture_buffer); } } @@ -70,6 +54,20 @@ impl Mandelbrot { pub fn generate_scaled_image(&mut self, x_bounds: (f64, f64), y_bounds: (f64, f64)) -> Vec { let mut texture_buffer = vec![0; (Self::IMG_WIDTH * Self::IMG_HEIGHT) * 4]; + + self.escape_time(x_bounds, y_bounds); + + for i in 0..texture_buffer.len() { + if i % 4 == 0 { + let iter_i = i / 4; + self.assign_colour(i, iter_i, &mut texture_buffer); + } + } + + texture_buffer + } + + fn escape_time(&mut self, x_bounds: (f64, f64), y_bounds: (f64, f64)) { self.iterations .par_iter_mut() .enumerate() @@ -79,60 +77,83 @@ impl Mandelbrot { let c = Self::coords_to_complex(px, py, x_bounds, y_bounds); - *value = Self::calc_num_iterations(c); - }); - - for i in 0..texture_buffer.len() { - if i % 4 == 0 { - let iter_i = i / 4; - match Self::find_colour(self.iterations[iter_i]) { - Colour::White => { - texture_buffer[i] = 0x00; - texture_buffer[i + 1] = 0x00; - texture_buffer[i + 2] = 0x00; - texture_buffer[i + 3] = 0xFF; - } - Colour::Black => { - texture_buffer[i] = 0xFF; - texture_buffer[i + 1] = 0xFF; - texture_buffer[i + 2] = 0xFF; - texture_buffer[i + 3] = 0xFF; - } - Colour::Gray => { - texture_buffer[i] = 0xAA; - texture_buffer[i + 1] = 0xAA; - texture_buffer[i + 2] = 0xAA; - texture_buffer[i + 3] = 0xFF; - } - } - } - } - - texture_buffer - } - - fn escape_time(&mut self) { - self.iterations - .par_iter_mut() - .enumerate() - .for_each(|(i, value)| { - let px = i % Self::IMG_WIDTH; - let py = i / Self::IMG_WIDTH; - - let c = Self::coords_to_complex(px, py, (-2.5, 1.0), (-1.0, 1.0)); - *value = Self::calc_num_iterations(c); }); } fn find_colour(iteration: u16) -> Colour { - match iteration { - MAX_ITERATIONS => Colour::Black, - other => match other % 2 { - 0 => Colour::White, - 1 => Colour::Gray, - _ => unreachable!(), - }, + if iteration == 1 { + return Colour::Black; + } + + match iteration % 7 { + 0 => Colour::Purple, + 1 => Colour::Violet, + 2 => Colour::Blue, + 3 => Colour::Green, + 4 => Colour::Yellow, + 5 => Colour::Orange, + 6 => Colour::Red, + _ => unreachable!(), + } + } + + fn assign_colour(&self, i: usize, iter_i: usize, texture_buffer: &mut [u8]) { + match Self::find_colour(self.iterations[iter_i]) { + Colour::White => { + texture_buffer[i] = 0xFF; + texture_buffer[i + 1] = 0xFF; + texture_buffer[i + 2] = 0xFF; + texture_buffer[i + 3] = 0xFF; + } + Colour::Black => { + texture_buffer[i] = 0x00; + texture_buffer[i + 1] = 0x00; + texture_buffer[i + 2] = 0x00; + texture_buffer[i + 3] = 0xFF; + } + Colour::Purple => { + texture_buffer[i] = 0x94; + texture_buffer[i + 1] = 0x00; + texture_buffer[i + 2] = 0xD3; + texture_buffer[i + 3] = 0xFF; + } + Colour::Violet => { + texture_buffer[i] = 0x4B; + texture_buffer[i + 1] = 0x00; + texture_buffer[i + 2] = 0x82; + texture_buffer[i + 3] = 0xFF; + } + Colour::Blue => { + texture_buffer[i] = 0x00; + texture_buffer[i + 1] = 0x00; + texture_buffer[i + 2] = 0xFF; + texture_buffer[i + 3] = 0xFF; + } + Colour::Green => { + texture_buffer[i] = 0x00; + texture_buffer[i + 1] = 0xFF; + texture_buffer[i + 2] = 0x00; + texture_buffer[i + 3] = 0xFF; + } + Colour::Yellow => { + texture_buffer[i] = 0xFF; + texture_buffer[i + 1] = 0xFF; + texture_buffer[i + 2] = 0x00; + texture_buffer[i + 3] = 0xFF; + } + Colour::Orange => { + texture_buffer[i] = 0xFF; + texture_buffer[i + 1] = 0x7F; + texture_buffer[i + 2] = 0x00; + texture_buffer[i + 3] = 0xFF; + } + Colour::Red => { + texture_buffer[i] = 0xFF; + texture_buffer[i + 1] = 0x00; + texture_buffer[i + 2] = 0x00; + texture_buffer[i + 3] = 0xFF; + } } } @@ -149,7 +170,7 @@ impl Mandelbrot { z = (z * z) + c; } - num_iterations + num_iterations + 1 // account for off by one error } fn coords_to_complex(