wiki-fractal-dimension.rs

3.1 kB · rust · 88 lines

1use mrlycore::errors::Result;2use mrlycore::Color;3use mrlyfig::{ink, save, Board, Frame, Grid};4use mrlymath::two::designs;56const BOXES: usize = 3;7const GUTTER: f64 = 52.0;8const SAMPLES: usize = 1000;910fn outline(board: &mut Board, frame: Frame, thick: f64, color: Color) {11    board.rect(frame.x, frame.y, frame.w, thick, color);12    board.rect(frame.x, frame.y + frame.h - thick, frame.w, thick, color);13    board.rect(frame.x, frame.y, thick, frame.h, color);14    board.rect(frame.x + frame.w - thick, frame.y, thick, frame.h, color);15}1617fn main() -> Result<()> {18    let mut board = Board::square();19    let area = board.frame(0.08);20    let tile = (area.w - 2.0 * GUTTER) / 3.0;21    let top = area.y + (area.h - tile) / 2.0;22    let carpet = designs::create(495, 3, 3, 0, 3)?;23    let side = carpet.width();24    assert_eq!(side, 27);2526    let mut lit = [0usize; 3];27    for panel in 0..3usize {28        let x = area.x + panel as f64 * (tile + GUTTER);29        let frame = Frame::new(x, top, tile, tile);30        let mut on = [[false; BOXES]; BOXES];31        match panel {32            0 => {33                board.rect(frame.x, frame.y, frame.w, frame.h, ink::blue());34                on = [[true; BOXES]; BOXES];35            }36            1 => {37                Grid::new(frame, side, side, 0.0).paint(&mut board, &carpet, |kind| {38                    (kind != 0).then_some(ink::blue())39                });40                let block = side / BOXES;41                for row in 0..BOXES {42                    for col in 0..BOXES {43                        for r in row * block..(row + 1) * block {44                            for c in col * block..(col + 1) * block {45                                if carpet.types().get(&[r, c]) != 0 {46                                    on[row][col] = true;47                                }48                            }49                        }50                    }51                }52            }53            _ => {54                board.segment(55                    (frame.x, frame.y + frame.h),56                    (frame.x + frame.w, frame.y),57                    tile * 0.03,58                    ink::blue(),59                );60                for i in 0..SAMPLES {61                    let u = (i as f64 + 0.5) / SAMPLES as f64;62                    let col = (u * BOXES as f64) as usize;63                    let row = ((1.0 - u) * BOXES as f64) as usize;64                    on[row.min(BOXES - 1)][col.min(BOXES - 1)] = true;65                }66            }67        }68        let step = tile / BOXES as f64;69        for row in 0..BOXES {70            for col in 0..BOXES {71                let cell = Frame::new(72                    frame.x + col as f64 * step,73                    frame.y + row as f64 * step,74                    step,75                    step,76                );77                outline(&mut board, cell, 1.5, ink::line());78                if on[row][col] {79                    outline(&mut board, cell.inset(step * 0.07), 6.0, ink::yellow());80                    lit[panel] += 1;81                }82            }83        }84    }85    assert_eq!(lit, [9, 8, 3]);86    save("wiki-fractal-dimension", &board)?;87    Ok(())88}