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}