~raph/bezoid

84eb1839caa4ca9cfeb5c911615df5b059d644fd — Raph Levien 1 year, 6 months ago 53554c0
Better calibration

The bias value calculation feels better. It might not be perfect, but
is probably good enough.
2 files changed, 30 insertions(+), 5 deletions(-)

M src/bez.rs
M src/solve.rs
M src/bez.rs => src/bez.rs +23 -4
@@ 6,6 6,7 @@ use druid::widget::prelude::*;
use druid::Data;

use crate::appdata::AppData;
use crate::bezoid::CurveParams;
use crate::grapher;

#[derive(Default)]


@@ 41,7 42,7 @@ impl Widget<AppData> for Bez {
                        data.px2 = p.x;
                        data.py2 = p.y;
                    }
                    println!("dragging {}", g);
                    self.set_params(data);
                }
            }
            Event::MouseUp(_e) => {


@@ 78,15 79,14 @@ impl Widget<AppData> for Bez {
    }

    fn paint(&mut self, ctx: &mut PaintCtx, data: &AppData, _env: &Env) {
        let a2 = Affine::translate(Vec2::new(OFFSET_X, OFFSET_Y)) * Affine::FLIP_Y * Affine::scale(SCALE);
        let solver = crate::solve::Solver;
        let a2 = self.affine();
        let p1 = Point::new(data.px1, data.py1);
        let p2 = Point::new(data.px2, data.py2);
        let l1 = Line::new(Point::ORIGIN, p1);
        ctx.stroke(a2 * l1, &Color::WHITE, 1.0);
        let l2 = Line::new(Point::new(1.0, 0.0), p2);
        ctx.stroke(a2 * l2, &Color::WHITE, 1.0);
        let params = solver.solve(p1, p2);
        let params: CurveParams = data.into();
        let curve = params.compute();
        grapher::plot_xy(ctx, &curve.pts, Point::new(OFFSET_X, OFFSET_Y), SCALE);
    }


@@ 103,4 103,23 @@ impl Bez {
        let a = Affine::translate(Vec2::new(OFFSET_X, OFFSET_Y)) * Affine::FLIP_Y * Affine::scale(SCALE);
        a.inverse() * design
    }

    fn affine(&self) -> Affine {
        Affine::translate(Vec2::new(OFFSET_X, OFFSET_Y)) * Affine::FLIP_Y * Affine::scale(SCALE)
    }

    fn determine_params(&self, data: &AppData) -> CurveParams {
        let solver = crate::solve::Solver;
        let p1 = Point::new(data.px1, data.py1);
        let p2 = Point::new(data.px2, data.py2);
        solver.solve(p1, p2)
    }

    fn set_params(&self, data: &mut AppData) {
        let params = self.determine_params(data);
        data.k0 = params.k0;
        data.bias0 = params.bias0;
        data.k1 = params.k1;
        data.bias1 = params.bias1;
    }
}

M src/solve.rs => src/solve.rs +7 -1
@@ 16,7 16,13 @@ impl Solver {
        fn inv_arm_len(h: f64, chord: f64) -> f64 {
            let a = h * 3.0 * chord.powf(BEZ_CHORD_EXP);
            let bias = 2.0 - a.powf(1.0 / BEZ_BIAS_EXP);
            bias.max(-1.0)
            // Note: with the correction below, it no longer matches
            // arm_len in infer_bezier.
            if bias > 0.0 {
                bias
            } else {
                (0.5 * bias).tanh()
            }
        }
        let v1 = p1.to_vec2();
        let v2 = Point::new(1.0, 0.0) - p2;