demo-cuts.rs

2.4 kB · rust · 75 lines

1use mrlycore::errors::Result;2use mrlyfig::board::{Board, Frame};3use mrlyfig::{ink, plot, save};4use mrlymath::three;56const CODE: u128 = 126;7const LEVEL: usize = 4;8const WIDE: usize = 4;910fn span(points: &[(f64, f64)]) -> ((f64, f64), (f64, f64)) {11    let mut lo = (f64::MAX, f64::MAX);12    let mut hi = (f64::MIN, f64::MIN);13    for (u, v) in points {14        lo.0 = lo.0.min(*u);15        lo.1 = lo.1.min(*v);16        hi.0 = hi.0.max(*u);17        hi.1 = hi.1.max(*v);18    }19    (lo, hi)20}2122fn panels(frame: Frame, gap: f64) -> Vec<Frame> {23    frame24        .rows(WIDE)25        .iter()26        .flat_map(|row| row.cols(WIDE))27        .map(|cell| cell.inset(gap))28        .collect()29}3031fn main() -> Result<()> {32    let counts = three::profile(CODE, 2, LEVEL, 2)?;33    let (low, high) = three::support(&counts).expect("the design fills some height");34    let cells = 3usize.pow(LEVEL as u32);35    assert_eq!((low, high), (15, 30));36    assert_eq!(high - low + 1, WIDE * WIDE);37    let mut cuts = Vec::new();38    for (height, count) in counts.iter().enumerate().take(high + 1).skip(low) {39        assert_eq!(*count, cells as u128);40        let points = three::diagonal_slice(CODE, 2, LEVEL, 2, height)?;41        assert_eq!(points.len(), cells);42        cuts.push(43            points44                .iter()45                .copied()46                .map(three::project)47                .collect::<Vec<_>>(),48        );49    }50    let flat: Vec<(f64, f64)> = cuts.iter().flatten().copied().collect();51    assert_eq!(flat.len(), WIDE * WIDE * cells);5253    let mut board = Board::square();54    let frame = board.frame(0.08);55    let stage = panels(frame, frame.w / WIDE as f64 * 0.05);56    let (lo, hi) = span(&flat);57    let mid = ((lo.0 + hi.0) / 2.0, (lo.1 + hi.1) / 2.0);58    let scale = (stage[0].w / (hi.0 - lo.0)).min(stage[0].h / (hi.1 - lo.1));59    let middle = [(low + high) / 2, (low + high).div_ceil(2)];60    for (i, cut) in cuts.iter().enumerate() {61        let (cx, cy) = stage[i].center();62        let dots: Vec<(f64, f64)> = cut63            .iter()64            .map(|(u, v)| (cx + (u - mid.0) * scale, cy - (v - mid.1) * scale))65            .collect();66        let color = if middle.contains(&(low + i)) {67            ink::yellow()68        } else {69            ink::blue()70        };71        plot::dots(&mut board, &dots, scale * 0.42, color);72    }73    save("demo-cuts", &board)?;74    Ok(())75}