terrain_forge/algorithms/
fractal.rs1use crate::{Algorithm, Grid, Rng, Tile};
2
3pub struct Fractal;
4
5impl Default for Fractal {
6 fn default() -> Self { Self }
7}
8
9impl Algorithm<Tile> for Fractal {
10 fn generate(&self, grid: &mut Grid<Tile>, seed: u64) {
11 let mut rng = Rng::new(seed);
12 if rng.chance(0.5) {
13 generate_mandelbrot(grid);
14 } else {
15 generate_julia(grid, &mut rng);
16 }
17 }
18
19 fn name(&self) -> &'static str { "Fractal" }
20}
21
22fn generate_mandelbrot(grid: &mut Grid<Tile>) {
23 let (w, h) = (grid.width(), grid.height());
24 let max_iter = 100;
25
26 for y in 0..h {
27 for x in 0..w {
28 let cx = (x as f64 / w as f64 - 0.5) * 4.0 - 0.5;
29 let cy = (y as f64 / h as f64 - 0.5) * 4.0;
30
31 let mut zx = 0.0;
32 let mut zy = 0.0;
33 let mut iter = 0;
34
35 while zx * zx + zy * zy < 4.0 && iter < max_iter {
36 let temp = zx * zx - zy * zy + cx;
37 zy = 2.0 * zx * zy + cy;
38 zx = temp;
39 iter += 1;
40 }
41
42 if iter < max_iter / 3 {
43 grid.set(x as i32, y as i32, Tile::Floor);
44 }
45 }
46 }
47}
48
49fn generate_julia(grid: &mut Grid<Tile>, rng: &mut Rng) {
50 let (w, h) = (grid.width(), grid.height());
51 let max_iter = 100;
52 let cx = rng.random() * 2.0 - 1.0;
53 let cy = rng.random() * 2.0 - 1.0;
54
55 for y in 0..h {
56 for x in 0..w {
57 let mut zx = (x as f64 / w as f64 - 0.5) * 3.0;
58 let mut zy = (y as f64 / h as f64 - 0.5) * 3.0;
59 let mut iter = 0;
60
61 while zx * zx + zy * zy < 4.0 && iter < max_iter {
62 let temp = zx * zx - zy * zy + cx;
63 zy = 2.0 * zx * zy + cy;
64 zx = temp;
65 iter += 1;
66 }
67
68 if iter < max_iter / 2 {
69 grid.set(x as i32, y as i32, Tile::Floor);
70 }
71 }
72 }
73}