tourbillon.rs
2.9 kB · rust · 79 lines
1use crate::Fault;2use mrlycore::{json, Json};3use mrlynum::tourbillon as spun;4use wasm_bindgen::prelude::*;56const EYE_CAP: usize = 60;78/// Spins the odd parity carpets at the scales one, three, five up to the top into one stack on a square of the size, every layer turned about the centre by its own angle and masked to the inscribed disc, so every pixel sees every layer.9///10/// The schedule is unspun, degrees, golden, primes, random or gaussian, the layer set is odd, primes, squarefree or prime powers, the weights are plain, mobius or harmonic, the render mode is cells, edges or corners and the blend is mean, sum, union, meet, parity or difference. The weights are scaled to average magnitude one and apply only under the linear blends, so mean is paper coverage and sum is the inked layer count. Sites outside the disc are NaN.11#[wasm_bindgen]12#[allow(clippy::too_many_arguments)]13pub fn tourbillon(14 top: usize,15 size: usize,16 schedule: &str,17 increment: f64,18 set: &str,19 weights: &str,20 mode: &str,21 blend: &str,22 seed: u32,23) -> Result<Vec<f32>, Fault> {24 Ok(spun::field(25 top, size, schedule, increment, set, weights, mode, blend, seed,26 )?)27}2829/// Reads a spun stack: the layer count, the first eight scales and angles, the mean and RMS contrast over the disc, that contrast times the root of the layer count, the exact centre value, whether the blend carries the weights, the span the raster covers and the brightest three sites, as JSON.30#[wasm_bindgen]31#[allow(clippy::too_many_arguments)]32pub fn tourbillon_stats(33 field: &[f32],34 size: usize,35 top: usize,36 schedule: &str,37 increment: f64,38 set: &str,39 weights: &str,40 blend: &str,41 seed: u32,42) -> Result<String, Fault> {43 let read = spun::stats(44 field, size, top, schedule, increment, set, weights, blend, seed,45 )?;46 Ok(json!({47 "layers": read.layers,48 "scales": read.scales,49 "angles": read.angles,50 "mean": read.mean,51 "rms": read.rms,52 "faded": read.faded,53 "centre": read.centre,54 "weighted": read.weighted,55 "low": read.low,56 "high": read.high,57 "inside": read.inside,58 "peaks": read.peaks,59 "period": read.period,60 "classes": read.classes,61 "pairs": read.pairs,62 })63 .to_string())64}6566/// Lists the angles a quarter turn shares with itself up to the denominator cap: each one's degrees, its numerator over ninety times a and its denominator, sorted, as JSON.67#[wasm_bindgen]68pub fn tourbillon_eyes(qmax: usize) -> Result<String, Fault> {69 if !(1..=EYE_CAP).contains(&qmax) {70 return Err(Fault::new(format!(71 "the denominator cap must be between 1 and {EYE_CAP}."72 )));73 }74 let list: Vec<Json> = spun::eyes(qmax)75 .iter()76 .map(|eye| json!([eye.angle, eye.numer, eye.denom]))77 .collect();78 Ok(Json::Array(list).to_string())79}