feat: pure software generation of mandelbrot
This commit is contained in:
parent
e8e31ad5b1
commit
8a2a5bd108
38
src/main.rs
38
src/main.rs
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue