feat: add more colours to mandelbrot visualization
This commit is contained in:
parent
c96bf45bff
commit
4a971e31c1
|
@ -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<u8> {
|
||||
// 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<u8> {
|
||||
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()
|
||||
|
@ -81,58 +79,81 @@ impl Mandelbrot {
|
|||
|
||||
*value = Self::calc_num_iterations(c);
|
||||
});
|
||||
}
|
||||
|
||||
for i in 0..texture_buffer.len() {
|
||||
if i % 4 == 0 {
|
||||
let iter_i = i / 4;
|
||||
fn find_colour(iteration: u16) -> Colour {
|
||||
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] = 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;
|
||||
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;
|
||||
}
|
||||
|
||||
texture_buffer
|
||||
Colour::Green => {
|
||||
texture_buffer[i] = 0x00;
|
||||
texture_buffer[i + 1] = 0xFF;
|
||||
texture_buffer[i + 2] = 0x00;
|
||||
texture_buffer[i + 3] = 0xFF;
|
||||
}
|
||||
|
||||
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);
|
||||
});
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
num_iterations
|
||||
num_iterations + 1 // account for off by one error
|
||||
}
|
||||
|
||||
fn coords_to_complex(
|
||||
|
|
Loading…
Reference in New Issue