paper-design-dirichlet-inverse.rs

4.0 kB · rust · 133 lines

1use mrlycore::errors::Result;2use mrlycore::Color;3use mrlyfig::{ink, plot, save, Board, Frame};45const RE_WIDTH: f64 = 1.00;6const IM_REACH: f64 = 60.0;7const RHO: (f64, f64) = (0.720790, 28.605680);8const BOX_RE: (f64, f64) = (0.72074, 0.72084);9const BOX_IM: (f64, f64) = (28.60563, 28.60573);10const BANDS: [(f64, f64); 2] = [(22.01, 24.01), (56.00, 58.00)];11const BAND_RE: f64 = 3.02;12const OVER: f64 = 22.0;1314fn at(rect: Frame, abscissa: f64, re: f64, im: f64) -> (f64, f64) {15    (16        rect.x + rect.w * (re - abscissa) / RE_WIDTH,17        rect.y + rect.h * (1.0 - im / IM_REACH),18    )19}2021fn stroke_box(board: &mut Board, rect: Frame, thick: f64, color: Color) {22    let pts = [23        (rect.x, rect.y),24        (rect.x + rect.w, rect.y),25        (rect.x + rect.w, rect.y + rect.h),26        (rect.x, rect.y + rect.h),27        (rect.x, rect.y),28    ];29    board.polyline(&pts, thick, color);30}3132fn half_plane(board: &mut Board, rect: Frame) {33    board.rect(rect.x, rect.y, rect.w, rect.h, ink::panel());34    board.segment(35        (rect.x - OVER, rect.y + rect.h),36        (rect.x + rect.w, rect.y + rect.h),37        1.6,38        ink::line(),39    );40    board.segment(41        (rect.x, rect.y - OVER),42        (rect.x, rect.y + rect.h + OVER),43        2.8,44        ink::fade(ink::indigo(), 0.5),45    );46}4748fn band(board: &mut Board, rect: Frame, abscissa: f64, span: (f64, f64)) {49    let (_, low) = at(rect, abscissa, abscissa, span.0);50    let (_, high) = at(rect, abscissa, abscissa, span.1);51    let run = rect.w + OVER;52    board.rect(53        rect.x,54        high,55        run,56        low - high,57        ink::fade(ink::yellow(), 0.16),58    );59    board.segment(60        (rect.x, high),61        (rect.x + run, high),62        1.8,63        ink::fade(ink::yellow(), 0.5),64    );65    board.segment(66        (rect.x, low),67        (rect.x + run, low),68        1.8,69        ink::fade(ink::yellow(), 0.5),70    );71}7273fn comb(abscissa: f64, period: f64, reach: f64) -> Vec<(f64, f64)> {74    let mut poles = Vec::new();75    let mut j = 0;76    while j as f64 * period <= reach {77        poles.push((abscissa, j as f64 * period));78        j += 1;79    }80    poles81}8283fn main() -> Result<()> {84    let alpha = 2f64.ln() / 3f64.ln();85    let period = 2.0 * std::f64::consts::PI / 3f64.ln();86    let poles = comb(alpha, period, IM_REACH);87    let integers = 1.0f64;8889    assert_eq!((IM_REACH / period).floor() as usize, 10);90    assert_eq!(poles.len(), 11);91    assert_eq!(BANDS.len(), 2);92    assert!(poles.iter().all(|p| p.0 == alpha));93    assert!(RHO.0 > alpha && RHO.0 < alpha + RE_WIDTH);94    assert!(RHO.0 > BOX_RE.0 && RHO.0 < BOX_RE.1);95    assert!(RHO.1 > BOX_IM.0 && RHO.1 < BOX_IM.1);96    assert!(BANDS97        .iter()98        .all(|b| b.1 > b.0 && b.0 > 0.0 && b.1 < IM_REACH));99    const { assert!(BAND_RE > RE_WIDTH) };100    assert!((alpha - 0.6309297536).abs() < 1e-9);101    assert!((period - 5.7192017348).abs() < 1e-9);102103    let mut board = Board::square();104    let work = board.frame(0.08).inset(OVER + 2.0);105    let pw = work.w * 0.455;106    let ph = work.h * 0.865;107    let design = Frame::new(work.x, work.y, pw, ph);108    let control = Frame::new(work.x + work.w - pw, work.y + work.h - ph, pw, ph);109110    half_plane(&mut board, control);111    let (ix, iy) = at(control, integers, integers, 0.0);112    plot::dots(&mut board, &[(ix, iy)], 6.0, ink::fade(ink::indigo(), 0.92));113114    half_plane(&mut board, design);115    for span in &BANDS {116        band(&mut board, design, alpha, *span);117    }118    let marks: Vec<(f64, f64)> = poles.iter().map(|p| at(design, alpha, p.0, p.1)).collect();119    plot::dots(&mut board, &marks, 6.0, ink::fade(ink::indigo(), 0.92));120121    let emblem = at(design, alpha, RHO.0, RHO.1);122    let half = design.w * 0.057;123    stroke_box(124        &mut board,125        Frame::new(emblem.0 - half, emblem.1 - half, 2.0 * half, 2.0 * half),126        2.0,127        ink::fade(ink::yellow(), 0.85),128    );129    plot::dots(&mut board, &[emblem], 12.0, ink::yellow());130131    save("paper-design-dirichlet-inverse", &board)?;132    Ok(())133}