feat: pure software generation of mandelbrot

This commit is contained in:
Rekai Nyangadzayi Musuka 2020-11-26 12:58:14 -06:00
parent e8e31ad5b1
commit 8a2a5bd108
2 changed files with 44 additions and 38 deletions

View File

@ -6,10 +6,10 @@ fn main() {
// Mandelbrot::escape_time_image();
App::build()
.add_plugins(DefaultPlugins)
.add_startup_system(startup.system())
.add_resource(SpriteScale::default())
.add_startup_system(png_startup.system())
.add_system(mandelbrot_render_system.system())
.add_system(mandelbrot_input_scale_system.system())
.add_system(transform_mandelbrot_system.system())
.run();
}
@ -31,7 +31,7 @@ impl Default for SpriteScale {
}
}
fn mandelbrot_input_scale_system(
fn transform_mandelbrot_system(
input: Res<Input<KeyCode>>,
mut scale: ResMut<SpriteScale>,
// camera: Res<Camera>,
@ -52,9 +52,6 @@ fn mandelbrot_input_scale_system(
}
}
const X_BOUNDS: (f64, f64) = (-2.5, 1.0);
const Y_BOUNDS: (f64, f64) = (-1.0, 1.0);
fn mandelbrot_render_system(
materials: Res<Assets<ColorMaterial>>,
mut textures: ResMut<Assets<Texture>>,
@ -75,21 +72,31 @@ fn mandelbrot_render_system(
((-1.0 * z) - v, (1.0 * z) - v),
);
let diff = Instant::now() - start;
dbg!(z);
dbg!(diff);
println!(
"Frametime: {:?} Framerate: {:.2}",
diff,
1.0 / diff.as_secs_f32()
);
}
}
}
}
}
fn png_startup(
fn startup(
mut commands: Commands,
asset_server: Res<AssetServer>,
mut textures: ResMut<Assets<Texture>>,
mut materials: ResMut<Assets<ColorMaterial>>,
) {
let texture_handle = asset_server.load("test.png");
let img_size = Vec2::new(Mandelbrot::width() as f32, Mandelbrot::height() as f32);
let img_buf = Mandelbrot::new().generate_image();
let texture_handle = textures.add(Texture::new(
img_size,
img_buf,
TextureFormat::Rgba8UnormSrgb,
));
commands
.spawn(Camera2dComponents::default())
.spawn(SpriteComponents {
@ -98,10 +105,3 @@ fn png_startup(
})
.with(Mandelbrot::new());
}
fn fractal_startup(mut commands: Commands) {
commands
.spawn(Camera2dComponents::default())
.spawn(SpriteComponents::default())
.with(Mandelbrot::new());
}

View File

@ -3,8 +3,6 @@ use num_complex::Complex;
use rayon::prelude::*;
const MAX_ITERATIONS: u16 = 256;
const IMG_WIDTH: usize = 1280;
const IMG_HEIGHT: usize = 720;
#[derive(Debug, Clone)]
pub struct Mandelbrot {
@ -18,18 +16,29 @@ enum Colour {
}
impl Mandelbrot {
const IMG_WIDTH: usize = 1280;
const IMG_HEIGHT: usize = 720;
pub fn new() -> Self {
Mandelbrot {
iterations: vec![0; IMG_WIDTH * IMG_HEIGHT],
iterations: vec![0; Self::IMG_WIDTH * Self::IMG_HEIGHT],
}
}
pub fn width() -> usize {
Self::IMG_WIDTH
}
pub fn height() -> usize {
Self::IMG_HEIGHT
}
pub fn generate_image(&mut self) -> Vec<u8> {
// Create the image
// Pixel Format can be Rgba8UnormSrgb
self.escape_time();
let mut texture_buffer = vec![0; (IMG_WIDTH * IMG_HEIGHT) * 4];
let mut texture_buffer = vec![0; (Self::IMG_WIDTH * Self::IMG_HEIGHT) * 4];
for i in 0..texture_buffer.len() {
if i % 4 == 0 {
@ -61,13 +70,13 @@ 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; (IMG_WIDTH * IMG_HEIGHT) * 4];
let mut texture_buffer = vec![0; (Self::IMG_WIDTH * Self::IMG_HEIGHT) * 4];
self.iterations
.par_iter_mut()
.enumerate()
.for_each(|(i, value)| {
let px = i % IMG_WIDTH;
let py = i / IMG_WIDTH;
let px = i % Self::IMG_WIDTH;
let py = i / Self::IMG_WIDTH;
let c = Self::coords_to_complex(px, py, x_bounds, y_bounds);
@ -108,8 +117,8 @@ impl Mandelbrot {
.par_iter_mut()
.enumerate()
.for_each(|(i, value)| {
let px = i % IMG_WIDTH;
let py = i / IMG_WIDTH;
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));
@ -118,18 +127,15 @@ impl Mandelbrot {
}
pub fn escape_time_image() {
const IMG_WIDTH: usize = 1280;
const IMG_HEIGHT: usize = 720;
let mut img: RgbImage = ImageBuffer::new(IMG_WIDTH as u32, IMG_HEIGHT as u32);
let mut mandelbrot: Vec<u16> = vec![0; IMG_HEIGHT * IMG_WIDTH];
let mut img: RgbImage = ImageBuffer::new(Self::IMG_WIDTH as u32, Self::IMG_HEIGHT as u32);
let mut mandelbrot: Vec<u16> = vec![0; Self::IMG_HEIGHT * Self::IMG_WIDTH];
mandelbrot
.par_iter_mut()
.enumerate()
.for_each(|(i, value)| {
let px = i % IMG_WIDTH;
let py = i / IMG_WIDTH;
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));
@ -137,7 +143,7 @@ impl Mandelbrot {
});
for (px, py, pixel) in img.enumerate_pixels_mut() {
let i = px as usize + IMG_WIDTH * py as usize;
let i = px as usize + Self::IMG_WIDTH * py as usize;
let num_iterations = mandelbrot[i];
match Self::find_colour(num_iterations) {
@ -193,13 +199,13 @@ impl Mandelbrot {
// const X_MIN: f64 = -2.5;
// const X_MAX: f64 = 1.0;
x_bounds.0 + ((x_bounds.1 - x_bounds.0) * (px as f64 - 0.0)) / IMG_WIDTH as f64 - 0.0
x_bounds.0 + ((x_bounds.1 - x_bounds.0) * (px as f64 - 0.0)) / Self::IMG_WIDTH as f64 - 0.0
}
fn scale_height(py: usize, y_bounds: (f64, f64)) -> f64 {
// const Y_MIN: f64 = -1.0;
// const Y_MAX: f64 = 1.0;
y_bounds.0 + ((y_bounds.1 - y_bounds.0) * (py as f64 - 0.0)) / IMG_HEIGHT as f64 - 0.0
y_bounds.0 + ((y_bounds.1 - y_bounds.0) * (py as f64 - 0.0)) / Self::IMG_HEIGHT as f64 - 0.0
}
}