wiki-graph-laplacian.rs
2.2 kB · rust · 72 lines
1use mrlycore::errors::Result;2use mrlyfig::{ink, plot, save, Board, Color, Frame};3use std::f64::consts::PI;45const VERTICES: usize = 32;6const CEILING: f64 = 4.0;78fn path() -> Vec<f64> {9 (0..VERTICES)10 .map(|k| 2.0 - 2.0 * (PI * k as f64 / VERTICES as f64).cos())11 .collect()12}1314fn cycle() -> Vec<f64> {15 let mut out: Vec<f64> = (0..VERTICES)16 .map(|k| 2.0 - 2.0 * (2.0 * PI * k as f64 / VERTICES as f64).cos())17 .collect();18 out.sort_by(|a, b| a.partial_cmp(b).expect("a finite spectrum"));19 out20}2122fn distinct(values: &[f64]) -> usize {23 let mut count = 1;24 for pair in values.windows(2) {25 if pair[1] - pair[0] > 1e-9 {26 count += 1;27 }28 }29 count30}3132fn steps(board: &mut Board, frame: Frame, values: &[f64], thick: f64, paint: Color) {33 let slot = frame.w / values.len() as f64;34 let mut pts = Vec::with_capacity(values.len() * 2);35 for (index, value) in values.iter().enumerate() {36 let y = frame.y + frame.h * (1.0 - value / CEILING);37 pts.push((frame.x + index as f64 * slot, y));38 pts.push((frame.x + (index + 1) as f64 * slot, y));39 }40 board.polyline(&pts, thick, paint);41 for (index, value) in values.iter().enumerate() {42 let y = frame.y + frame.h * (1.0 - value / CEILING);43 board.disc(frame.x + (index as f64 + 0.5) * slot, y, thick * 0.9, paint);44 }45}4647fn main() -> Result<()> {48 let line = path();49 let ring = cycle();50 assert_eq!((line.len(), ring.len()), (VERTICES, VERTICES));51 assert_eq!((distinct(&line), distinct(&ring)), (32, 17));52 assert!(line[0].abs() < 1e-12 && ring[0].abs() < 1e-12);53 assert!((ring[VERTICES - 1] - CEILING).abs() < 1e-12);5455 let mut board = Board::square();56 let frame = board.frame(0.08);57 let stage = frame.inset(frame.w * 0.04);58 plot::baseline(&mut board, stage, ink::line());59 for k in 1..4 {60 let y = stage.y + stage.h * (1.0 - k as f64 / CEILING);61 board.segment(62 (stage.x, y),63 (stage.x + stage.w, y),64 1.5,65 ink::fade(ink::dim(), 0.7),66 );67 }68 steps(&mut board, stage, &ring, 7.0, ink::orange());69 steps(&mut board, stage, &line, 7.0, ink::blue());70 save("wiki-graph-laplacian", &board)?;71 Ok(())72}