proof_engine/fractal/
julia.rs1use super::mandelbrot::FractalPixel;
4
5#[derive(Debug, Clone)]
6pub struct JuliaParams {
7 pub c_re: f64, pub c_im: f64,
8 pub center_re: f64, pub center_im: f64,
9 pub zoom: f64, pub max_iter: u32,
10 pub escape_radius: f64,
11 pub width: u32, pub height: u32,
12}
13impl Default for JuliaParams {
14 fn default() -> Self {
15 Self { c_re: -0.7, c_im: 0.27015, center_re: 0.0, center_im: 0.0, zoom: 1.0, max_iter: 256, escape_radius: 4.0, width: 800, height: 600 }
16 }
17}
18
19pub struct JuliaRenderer;
20impl JuliaRenderer {
21 pub fn compute_pixel(z_re: f64, z_im: f64, c_re: f64, c_im: f64, max_iter: u32, escape_r2: f64) -> FractalPixel {
22 let mut zr = z_re; let mut zi = z_im;
23 for i in 0..max_iter {
24 let r2 = zr * zr; let i2 = zi * zi;
25 if r2 + i2 > escape_r2 {
26 let smooth = i as f64 + 1.0 - ((r2 + i2).ln() * 0.5 / 2.0_f64.ln()).ln() / 2.0_f64.ln();
27 return FractalPixel { iterations: i, smooth_iter: smooth, escaped: true, final_z_re: zr, final_z_im: zi };
28 }
29 zi = 2.0 * zr * zi + c_im;
30 zr = r2 - i2 + c_re;
31 }
32 FractalPixel { iterations: max_iter, smooth_iter: max_iter as f64, escaped: false, final_z_re: zr, final_z_im: zi }
33 }
34
35 pub fn render(params: &JuliaParams) -> Vec<FractalPixel> {
36 let (w, h) = (params.width, params.height);
37 let aspect = w as f64 / h as f64;
38 let scale = 2.0 / params.zoom;
39 let escape_r2 = params.escape_radius * params.escape_radius;
40 let mut pixels = Vec::with_capacity((w * h) as usize);
41 for py in 0..h { for px in 0..w {
42 let z_re = params.center_re + (px as f64 / w as f64 - 0.5) * scale * aspect;
43 let z_im = params.center_im + (py as f64 / h as f64 - 0.5) * scale;
44 pixels.push(Self::compute_pixel(z_re, z_im, params.c_re, params.c_im, params.max_iter, escape_r2));
45 }}
46 pixels
47 }
48}
49
50#[cfg(test)]
51mod tests {
52 use super::*;
53 #[test]
54 fn julia_renders() {
55 let params = JuliaParams { width: 10, height: 10, max_iter: 50, ..Default::default() };
56 let pixels = JuliaRenderer::render(¶ms);
57 assert_eq!(pixels.len(), 100);
58 }
59}