demo-snail.rs

2.3 kB · rust · 70 lines

1use mrlycore::errors::Result;2use mrlyfig::{ink, save, Board};3use mrlymath::two;4use mrlynum::spiral::{snail, Growth};56const TOP: u64 = 300;7const BASE: u64 = 2;8const CODE: u128 = 7;9const MARGIN: f64 = 0.07;1011fn main() -> Result<()> {12    let mut board = Board::square();13    let frame = board.area(MARGIN);14    let shell = snail(BASE, TOP, Growth::Every);15    assert_eq!(shell.tiles.len(), 300);16    assert_eq!(shell.primes, 62);17    assert_eq!(shell.levels, vec![1, 2, 4, 8, 16, 32, 64, 128, 45]);18    assert_eq!(shell.area, 5_345_865);19    let wide = (shell.high.0 - shell.low.0) as f64;20    let tall = (shell.high.1 - shell.low.1) as f64;21    assert_eq!((wide, tall), (4608.0, 4352.0));22    let unit = (frame.w / wide).min(frame.h / tall);23    let left = frame.x + (frame.w - wide * unit) / 2.0;24    let foot = frame.y + (frame.h + tall * unit) / 2.0;25    let at = |x: f64, y: f64| {26        (27            left + (x - shell.low.0 as f64) * unit,28            foot - (y - shell.low.1 as f64) * unit,29        )30    };31    let path: Vec<(f64, f64)> = shell32        .tiles33        .iter()34        .map(|tile| {35            let half = tile.side as f64 / 2.0;36            at(tile.x as f64 + half, tile.y as f64 + half)37        })38        .collect();39    board.polyline(&path, 1.6, ink::line());40    let mut art = Vec::new();41    for level in 0..shell.levels.len() {42        art.push(match level {43            0 => None,44            _ => Some(two::create(CODE, BASE as usize, level, 0, 2)?),45        });46    }47    let mut drawn = 0usize;48    for tile in shell.tiles.iter().filter(|tile| tile.level > 0) {49        let cell = art[tile.level as usize].as_ref().expect("a grown level");50        let types = cell.types();51        let side = cell.width();52        let tone = if tile.prime { ink::blue() } else { ink::dim() };53        for row in 0..side {54            for col in 0..side {55                if types.get(&[row, col]) == 0 {56                    continue;57                }58                let (x, y) = at(59                    tile.x as f64 + col as f64,60                    tile.y as f64 + (side - row) as f64,61                );62                board.rect(x, y, unit, unit, tone);63                drawn += 1;64            }65        }66    }67    assert_eq!(drawn, 631_167);68    save("demo-snail", &board)?;69    Ok(())70}