wiki-spectral-radius.rs
2.1 kB · rust · 66 lines
1use mrlycore::errors::Result;2use mrlyfig::{ink, save, Board};34const ARROWS: usize = 8;5const MATRIX: [[f64; 2]; 2] = [[2.0, 1.0], [1.0, 3.0]];6const START: (f64, f64) = (1.0, -0.6);78fn push(v: (f64, f64)) -> (f64, f64) {9 (10 MATRIX[0][0] * v.0 + MATRIX[0][1] * v.1,11 MATRIX[1][0] * v.0 + MATRIX[1][1] * v.1,12 )13}1415fn main() -> Result<()> {16 let mut v = START;17 let mut angles = Vec::with_capacity(ARROWS);18 for _ in 0..ARROWS {19 angles.push(v.1.atan2(v.0));20 v = push(v);21 }22 let golden = (1.0 + 5f64.sqrt()) / 2.0;23 let settled = golden.atan2(1.0);24 assert_eq!(angles.len(), ARROWS);25 assert!(angles.windows(2).all(|pair| pair[1] > pair[0]));26 assert!((settled - angles[ARROWS - 1]).abs() < 0.10);27 assert!(angles[0] < 0.0);2829 let mut board = Board::square();30 let frame = board.frame(0.08);31 let (cx, cy) = frame.at(0.30, 0.59);32 let reach = frame.w * 0.62;33 let far = frame.w * 0.70;34 board.segment(35 (cx - far * settled.cos(), cy + far * settled.sin()),36 (cx + far * settled.cos(), cy - far * settled.sin()),37 3.0,38 ink::fade(ink::dim(), 0.8),39 );40 board.arc(41 (cx, cy),42 reach * 1.05,43 (-settled - 0.12, -angles[0] + 0.12),44 3.0,45 ink::fade(ink::dim(), 0.8),46 );47 for (index, angle) in angles.iter().enumerate() {48 let heat = index as f64 / (ARROWS - 1) as f64;49 let paint = ink::mix(ink::blue(), ink::yellow(), heat);50 let tip = (cx + reach * angle.cos(), cy - reach * angle.sin());51 let way = (angle.cos(), -angle.sin());52 let side = (-way.1, way.0);53 let head = frame.w * 0.045;54 let base = (tip.0 - way.0 * head, tip.1 - way.1 * head);55 board.segment((cx, cy), base, 7.0, paint);56 board.triangle(57 tip,58 (base.0 + side.0 * head * 0.5, base.1 + side.1 * head * 0.5),59 (base.0 - side.0 * head * 0.5, base.1 - side.1 * head * 0.5),60 paint,61 );62 }63 board.disc(cx, cy, frame.w * 0.018, ink::fg());64 save("wiki-spectral-radius", &board)?;65 Ok(())66}