cantor_set/
cantor_set.rs

1use image::{ImageBuffer, Rgb};
2
3use dcc_lsystem::image::fill_mut;
4use dcc_lsystem::LSystemBuilder;
5
6fn main() {
7    let mut builder = LSystemBuilder::new();
8
9    let a = builder.token("A");
10    let b = builder.token("B");
11
12    builder.axiom(vec![a]);
13    builder.transformation_rule(a, vec![a, b, a]);
14    builder.transformation_rule(b, vec![b, b, b]);
15
16    let mut system = builder.finish();
17
18    // the total number of states (including the initial state!) to render
19    let step_limit = 6;
20
21    // At state number `step_limit`, our diagram has 3^(step_limit - 1) bars,
22    // so we make the width of our image an integer multiple of this number.
23    let width = 3_u32.pow(step_limit - 1) * 2;
24
25    // the vertical spacing between each bar in the render
26    let vertical_spacing = 5;
27
28    let mut lines = Vec::new();
29
30    for index in 0..step_limit {
31        let state = system.get_state();
32        let bar_width: u32 = width / state.len() as u32;
33
34        let mut x: u32 = 0;
35        let y = vertical_spacing * index;
36
37        for token in state {
38            if *token == a {
39                // draw a line
40                lines.push((x, y, x + bar_width, y));
41            }
42            x += bar_width;
43        }
44
45        system.step();
46    }
47
48    let padding: u32 = 5;
49    let render_width = 2 * padding + width as u32;
50    let render_height = 2 * padding + vertical_spacing * (step_limit - 1);
51
52    let mut buffer = ImageBuffer::new(render_width, render_height);
53
54    // Make the buffer entirely white
55    fill_mut(&mut buffer, Rgb([255u8, 255u8, 255u8]));
56
57    // Draw the lines
58    for (x1, y1, x2, y2) in lines.into_iter() {
59        for x in x1..=x2 {
60            for y in y1..=y2 {
61                let pixel = buffer.get_pixel_mut(x + padding, y + padding);
62                *pixel = Rgb([0u8, 0u8, 0u8]);
63            }
64        }
65    }
66
67    buffer
68        .save("cantor_set.png")
69        .expect("Failed to save to cantor_set.png");
70}