~raph/bezoid

9dfe1841a11dedf8c24fefa3c5f96719dd2a1ee0 — Raph Levien 1 year, 6 months ago d5555fa
Update high-tension basis function

This one is simpler mathematically and closer to actual bezier behavior.
1 files changed, 22 insertions(+), 18 deletions(-)

M src/grapher.rs
M src/grapher.rs => src/grapher.rs +22 -18
@@ 1,7 1,5 @@
//! Custom widget for drawing stuff

use std::f64::consts::{FRAC_2_PI, FRAC_PI_2};

use druid::kurbo::{BezPath, Line, Point};
use druid::piet::Color;
use druid::widget::prelude::*;


@@ 14,30 12,36 @@ pub struct Grapher;
const N: usize = 1000;
const N_RECIP: f64 = 1.0 / (N as f64);

fn nonlinear(x: f64) -> f64 {
    if x > 1.0 {
        1.0 + FRAC_2_PI * ((x - 1.0) * FRAC_PI_2).tan()
    } else if x < -1.0 {
        -1.0 + FRAC_2_PI * ((x + 1.0) * FRAC_PI_2).tan()
    } else {
        x
    }
}

fn compute_basis(bias: f64) -> Vec<f64> {
    let mut sum = 0.0;
    let mut result = (0..=N)
        .map(|i| {
            let x = (i as f64 + 0.5) * N_RECIP;
            let y1 = 1.0 - x;
            let y0 = 6.0 * (y1.powi(2) - y1.powi(3));
            let y = y0 + bias * (y1 - y0);
            let y = nonlinear(y);
            sum += y * N_RECIP;
            sum
            let y = if bias > 1.0 {
                y1 / (1.0 - (bias - 1.0) * y1).powi(2)
            } else {
                let y0 = 6.0 * (y1.powi(2) - y1.powi(3));
                y0 + bias * (y1 - y0)
            };
            let result = sum;
            if i < N {
                sum += y * N_RECIP;
            }
            result
        })
        .collect::<Vec<_>>();
    println!("sum = {}", sum);
    //println!("sum = {}", sum);
    if bias > 1.0 {
        // This basis function can be integrated analytically:
        fn integral(x: f64, a: f64) -> f64 {
            (1.0 / (1.0 - a * x) + (1.0 - a * x).ln()) / (a * a)
        }
        let a = bias - 1.0;
        let _sum_computed = integral(1.0, a) - integral(0.0, a);
        let _sum2 = (1.0 / (1.0 - a) + (1.0 - a).ln() - 1.0) / (a * a);
        //println!("sum = {}, integral = {}, {}", sum, _sum_computed, _sum2)
    }
    let sum_recip = sum.recip();
    for x in &mut result {
        *x *= sum_recip;