wiki-spirograph.rs

1.2 kB · rust · 39 lines

1use mrlycore::errors::Result;2use mrlyfig::{ink, save, Board};3use mrlynum::spirograph::{frame as bounds, point, track, Kind, Pencil};45const RING: usize = 7;6const WHEEL: usize = 3;7const REACH: f64 = 0.8;8const SAMPLES: usize = 4000;910fn main() -> Result<()> {11    let path = track("in", RING, WHEEL, 4, 1)?;12    assert_eq!((path.ratio, path.orbits, path.fold), ((RING, WHEEL), 3, 7));13    let pen = Pencil {14        x: REACH,15        y: 0.0,16        seat: (0, 0),17        kind: Kind::Fill,18    };19    let curve: Vec<(f64, f64)> = (0..SAMPLES)20        .map(|k| {21            let s = path.total * k as f64 / (SAMPLES - 1) as f64;22            point(&path, &pen, s)23        })24        .collect();25    assert_eq!(curve.len(), SAMPLES);26    let mut board = Board::square();27    let frame = board.frame(0.08);28    let [x0, y0, x1, y1] = bounds(&path, &[pen]);29    let scale = (frame.w / (x1 - x0)).min(frame.h / (y1 - y0));30    let (cx, cy) = frame.center();31    board.ring(cx, cy, RING as f64 * scale, 1.5, ink::dim());32    let pts: Vec<(f64, f64)> = curve33        .iter()34        .map(|&(x, y)| (cx + x * scale, cy - y * scale))35        .collect();36    board.polyline(&pts, 2.4, ink::blue());37    save("wiki-spirograph", &board)?;38    Ok(())39}