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 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()
|
||||||
|
@ -79,60 +77,83 @@ impl Mandelbrot {
|
||||||
|
|
||||||
let c = Self::coords_to_complex(px, py, x_bounds, y_bounds);
|
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);
|
*value = Self::calc_num_iterations(c);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_colour(iteration: u16) -> Colour {
|
fn find_colour(iteration: u16) -> Colour {
|
||||||
match iteration {
|
if iteration == 1 {
|
||||||
MAX_ITERATIONS => Colour::Black,
|
return Colour::Black;
|
||||||
other => match other % 2 {
|
}
|
||||||
0 => Colour::White,
|
|
||||||
1 => Colour::Gray,
|
match iteration % 7 {
|
||||||
_ => unreachable!(),
|
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;
|
z = (z * z) + c;
|
||||||
}
|
}
|
||||||
|
|
||||||
num_iterations
|
num_iterations + 1 // account for off by one error
|
||||||
}
|
}
|
||||||
|
|
||||||
fn coords_to_complex(
|
fn coords_to_complex(
|
||||||
|
|
Loading…
Reference in New Issue