research-toolpaths.rs
2.2 kB · rust · 73 lines
1use figures::{ink, save, Board};2use mrlyrs::core::error::Result;34const DIRS: [usize; 7] = [0, 5, 3, 4, 0, 0, 1];5const FLIPS: [bool; 7] = [false, true, true, false, false, false, true];6const LEVEL: usize = 4;7const STEPS: usize = 2401;8const COUNTS: [usize; 3] = [343, 1371, 686];9const MARGIN: f64 = 0.08;10const PATH: f64 = 2.2;11const DOT: f64 = 3.1;1213fn expand(seq: &[(usize, bool)]) -> Vec<(usize, bool)> {14 let mut out = Vec::with_capacity(seq.len() * 7);15 for &(d, r) in seq {16 for j in 0..7 {17 let i = if r { 6 - j } else { j };18 out.push(((d + DIRS[i]) % 6, FLIPS[i] != r));19 }20 }21 out22}2324fn main() -> Result<()> {25 let mut seq = vec![(0usize, false)];26 for _ in 0..LEVEL {27 seq = expand(&seq);28 }29 assert_eq!(seq.len(), STEPS);30 let unit: Vec<(f64, f64)> = (0..6)31 .map(|d| {32 let a = std::f64::consts::PI / 3.0 * d as f64;33 (a.cos(), a.sin())34 })35 .collect();36 let mut pts = vec![(0.0, 0.0)];37 for &(d, _) in &seq {38 let (x, y) = pts[pts.len() - 1];39 pts.push((x + unit[d].0, y + unit[d].1));40 }41 let mut counts = [0usize; 3];42 let mut sharp = Vec::new();43 for i in 1..seq.len() {44 let t = (seq[i].0 + 6 - seq[i - 1].0) % 6;45 let t = t.min(6 - t);46 counts[t] += 1;47 if t == 2 {48 sharp.push(pts[i]);49 }50 }51 assert_eq!(counts, COUNTS);52 let (mut x0, mut y0, mut x1, mut y1) = (f64::MAX, f64::MAX, f64::MIN, f64::MIN);53 for &(x, y) in &pts {54 x0 = x0.min(x);55 y0 = y0.min(y);56 x1 = x1.max(x);57 y1 = y1.max(y);58 }59 let mut board = Board::square();60 let area = board.frame(MARGIN);61 let (cx, cy) = area.center();62 let scale = 2.0 * area.radius() / (x1 - x0).max(y1 - y0);63 let (mx, my) = ((x0 + x1) / 2.0, (y0 + y1) / 2.0);64 let at = |(x, y): (f64, f64)| (cx + (x - mx) * scale, cy - (y - my) * scale);65 let path: Vec<(f64, f64)> = pts.iter().map(|&p| at(p)).collect();66 board.polyline(&path, PATH, ink::dim());67 for &p in &sharp {68 let (x, y) = at(p);69 board.disc(x, y, DOT, ink::orange());70 }71 save("research-toolpaths", &board)?;72 Ok(())73}