chore: refactor the texture size constants
This commit is contained in:
parent
3d0f2acea3
commit
0c6dae0d04
|
@ -1,3 +1,7 @@
|
|||
pub use crate::mandelbrot::Bounds;
|
||||
pub use crate::mandelbrot::Mandelbrot;
|
||||
|
||||
pub const TEXTURE_WIDTH: usize = 1280;
|
||||
pub const TEXTURE_HEIGHT: usize = 720;
|
||||
|
||||
mod mandelbrot;
|
||||
|
|
10
src/main.rs
10
src/main.rs
|
@ -1,5 +1,5 @@
|
|||
use bevy::{prelude::*, render::texture::TextureFormat};
|
||||
use mandelbrot::{Bounds, Mandelbrot};
|
||||
use mandelbrot::{Bounds, Mandelbrot, TEXTURE_HEIGHT, TEXTURE_WIDTH};
|
||||
use std::time::Instant;
|
||||
|
||||
fn main() {
|
||||
|
@ -110,12 +110,12 @@ fn startup(
|
|||
mut textures: ResMut<Assets<Texture>>,
|
||||
mut materials: ResMut<Assets<ColorMaterial>>,
|
||||
) {
|
||||
let img_size = Vec2::new(Mandelbrot::width() as f32, Mandelbrot::height() as f32);
|
||||
let img_buf = Mandelbrot::new().image().to_vec();
|
||||
let texture_size = Vec2::new(TEXTURE_WIDTH as f32, TEXTURE_HEIGHT as f32);
|
||||
let texture_data = Mandelbrot::new().image().to_vec();
|
||||
|
||||
let texture_handle = textures.add(Texture::new(
|
||||
img_size,
|
||||
img_buf,
|
||||
texture_size,
|
||||
texture_data,
|
||||
TextureFormat::Rgba8UnormSrgb,
|
||||
));
|
||||
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
use crate::{TEXTURE_HEIGHT, TEXTURE_WIDTH};
|
||||
use num_complex::Complex;
|
||||
use rayon::prelude::*;
|
||||
|
||||
const DEFAULT_ITERATION_LIMIT: u32 = 64;
|
||||
const DEFAULT_BOUNDS: Bounds = Bounds::new((-2.5, 1.0), (-1.0, 1.0));
|
||||
|
||||
pub struct Coordinate(usize, usize);
|
||||
|
||||
impl Coordinate {
|
||||
|
@ -36,73 +40,59 @@ impl Bounds {
|
|||
}
|
||||
}
|
||||
|
||||
const DEFAULT_MAX_ITERATIONS: u32 = 64;
|
||||
const DEFAULT_BOUNDS: Bounds = Bounds::new((-2.5, 1.0), (-1.0, 1.0));
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Mandelbrot {
|
||||
texture_buffer: Vec<u8>,
|
||||
frame_buffer: Box<[u8; (TEXTURE_WIDTH * TEXTURE_HEIGHT) * 4]>,
|
||||
}
|
||||
|
||||
impl Mandelbrot {
|
||||
const IMG_WIDTH: usize = 1280;
|
||||
const IMG_HEIGHT: usize = 720;
|
||||
|
||||
pub fn new() -> Self {
|
||||
Mandelbrot {
|
||||
texture_buffer: vec![0; (Self::IMG_WIDTH * Self::IMG_HEIGHT) * 4],
|
||||
frame_buffer: Box::new([0; (TEXTURE_WIDTH * TEXTURE_HEIGHT) * 4]),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn width() -> usize {
|
||||
Self::IMG_WIDTH
|
||||
}
|
||||
|
||||
pub fn height() -> usize {
|
||||
Self::IMG_HEIGHT
|
||||
}
|
||||
|
||||
pub fn image(&mut self) -> &[u8] {
|
||||
let max_iters = DEFAULT_MAX_ITERATIONS as f64;
|
||||
let limit_f64 = DEFAULT_ITERATION_LIMIT as f64;
|
||||
|
||||
self.texture_buffer
|
||||
self.frame_buffer
|
||||
.par_chunks_mut(4)
|
||||
.enumerate()
|
||||
.for_each(|(i, buf)| {
|
||||
let iters = Self::escape_time(i, DEFAULT_BOUNDS, DEFAULT_MAX_ITERATIONS);
|
||||
let normalized_iters = iters / max_iters;
|
||||
let iterations = Self::escape_time(i, DEFAULT_BOUNDS, DEFAULT_ITERATION_LIMIT);
|
||||
let normalized_iters = iterations / limit_f64;
|
||||
|
||||
let h = normalized_iters * 350.0;
|
||||
let v = if iters == max_iters { 0.0 } else { 1.0 };
|
||||
let v = if iterations == limit_f64 { 0.0 } else { 1.0 };
|
||||
buf.copy_from_slice(&Self::hsv_to_rgb(h, 1.0, v));
|
||||
});
|
||||
|
||||
&self.texture_buffer
|
||||
self.frame_buffer.as_ref()
|
||||
}
|
||||
|
||||
pub fn scaled_image(&mut self, bounds: Bounds, max_iterations: u32) -> &[u8] {
|
||||
self.texture_buffer
|
||||
pub fn scaled_image(&mut self, bounds: Bounds, limit: u32) -> &[u8] {
|
||||
self.frame_buffer
|
||||
.par_chunks_mut(4)
|
||||
.enumerate()
|
||||
.for_each(|(i, buf)| {
|
||||
let max_iters = max_iterations as f64;
|
||||
let limit_f64 = limit as f64;
|
||||
|
||||
let iters = Self::escape_time(i, bounds, max_iterations);
|
||||
let normalized_iters = iters / max_iters;
|
||||
let iterations = Self::escape_time(i, bounds, limit);
|
||||
let normalized_iters = iterations / limit_f64;
|
||||
|
||||
let h = normalized_iters * 350.0;
|
||||
let v = if iters == max_iters { 0.0 } else { 1.0 };
|
||||
let v = if iterations == limit_f64 { 0.0 } else { 1.0 };
|
||||
buf.copy_from_slice(&Self::hsv_to_rgb(h, 1.0, v))
|
||||
});
|
||||
|
||||
&self.texture_buffer
|
||||
self.frame_buffer.as_ref()
|
||||
}
|
||||
|
||||
fn escape_time(i: usize, bounds: Bounds, max_iterations: u32) -> f64 {
|
||||
let point = Coordinate::new(i % Self::IMG_WIDTH, i / Self::IMG_WIDTH);
|
||||
fn escape_time(i: usize, bounds: Bounds, iteration_limit: u32) -> f64 {
|
||||
let point = Coordinate::new(i % TEXTURE_WIDTH, i / TEXTURE_WIDTH);
|
||||
let c = Self::coords_to_complex(point, bounds);
|
||||
|
||||
Self::count_iterations(c, max_iterations)
|
||||
Self::count_iterations(c, iteration_limit)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -137,27 +127,27 @@ impl Mandelbrot {
|
|||
[r, g, b, a]
|
||||
}
|
||||
|
||||
fn count_iterations(c: Complex<f64>, max_iterations: u32) -> f64 {
|
||||
fn count_iterations(c: Complex<f64>, maximum: u32) -> f64 {
|
||||
let mut z: Complex<f64> = Complex::new(0.0, 0.0);
|
||||
let mut num_iters: u32 = 0;
|
||||
let mut count: u32 = 0;
|
||||
|
||||
loop {
|
||||
if z.norm_sqr() > 4.0 {
|
||||
break;
|
||||
}
|
||||
|
||||
if num_iters >= max_iterations {
|
||||
if count >= maximum {
|
||||
break;
|
||||
}
|
||||
|
||||
z = (z * z) + c;
|
||||
num_iters += 1;
|
||||
count += 1;
|
||||
}
|
||||
|
||||
if num_iters < max_iterations {
|
||||
(num_iters as f64 + 1.0) - z.norm().ln().ln() / 2f64.ln()
|
||||
if count < maximum {
|
||||
(count as f64 + 1.0) - z.norm().ln().ln() / 2f64.ln()
|
||||
} else {
|
||||
num_iters as f64
|
||||
count as f64
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -173,7 +163,7 @@ impl Mandelbrot {
|
|||
// const X_MIN: f64 = -2.5;
|
||||
// const X_MAX: f64 = 1.0;
|
||||
|
||||
bounds.0 + ((bounds.1 - bounds.0) * (x as f64 - 0.0)) / Self::IMG_WIDTH as f64 - 0.0
|
||||
bounds.0 + ((bounds.1 - bounds.0) * (x as f64 - 0.0)) / TEXTURE_WIDTH as f64 - 0.0
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -181,6 +171,6 @@ impl Mandelbrot {
|
|||
// const Y_MIN: f64 = -1.0;
|
||||
// const Y_MAX: f64 = 1.0;
|
||||
|
||||
bounds.0 + ((bounds.1 - bounds.0) * (y as f64 - 0.0)) / Self::IMG_HEIGHT as f64 - 0.0
|
||||
bounds.0 + ((bounds.1 - bounds.0) * (y as f64 - 0.0)) / TEXTURE_HEIGHT as f64 - 0.0
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue