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}