feat: add more colours to mandelbrot visualization

This commit is contained in:
Rekai Nyangadzayi Musuka 2020-11-26 14:39:48 -06:00
parent c96bf45bff
commit 4a971e31c1
1 changed files with 97 additions and 76 deletions

View File

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