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