plotters icon indicating copy to clipboard operation
plotters copied to clipboard

[Feature Request] Fill Gradient [With Naive Impl Proposed]

Open DaMilyutin opened this issue 3 years ago • 0 comments

What is the feature ?

It would be nice to have gradient fill if I want more distiguishable background color. I wrote my version as a free function by now. Code is in the end of description.

(Optional) Why this feature is useful and how people would use the feature ?

Because it looks nicer: image Looks less dull than monocolor.

I've used this fill parameters

    fill_gradient(
        &root,
        (144.0, 89.0),
        (&HSLColor(0.0, 0.0, 0.05), &HSLColor(0.0, 0.0, 0.15)),
    );

(Optional) Additional Information

Code:

fn fill_gradient(
    root: &DrawingArea<BitMapBackend, plotters::coord::Shift>,
    dir: (f64, f64),
    colors: (&HSLColor, &HSLColor),
) {
    let dirn = {
        let n = dir.0.abs() + dir.1.abs();
        if n <= 1e-10 {
            (1f64, 0f64)
        } else {
            let n = 1f64 / ((dir.0.abs() + dir.1.abs()) as f64);
            (dir.0 as f64 * n, dir.1 as f64 * n)
        }
    };

    let orig = match dirn {
        (_x, _y) => (0.0, 0.0),
        (x, y) if x > 0.0 && y < 0.0 => (0.0, 1.0),
        (x, y) if x < 0.0 && y > 0.0 => (1.0, 0.0),
        (x, y) if x < 0.0 && y < 0.0 => (1.0, 1.0),
    };

    let (xx, yy) = root.get_pixel_range();
    let kx = 1f64 / ((xx.end - xx.start) as f64);
    let ky = 1f64 / ((yy.end - yy.start) as f64);
    let (from, to) = colors;
    for x in xx {
        for y in yy.clone() {
            let v = ((x as f64) * kx - orig.0) * dirn.0 + ((y as f64) * ky - orig.1) * dirn.1;
            root.draw_pixel((x, y), &lerp(from, to, v))
                .expect("error filling drawing area");
        }
    }
}


// Additionally it would be nice to have function lerp for any color.
// But for RGB it is better (but more expensive) to transform those to HSL then do lerp and then transform back to RGB.
// BTW, I havent found conversion RBG <=> HSL and had difficulties with conversions from the box.
fn lerp(l: &HSLColor, r: &HSLColor, v: f64) -> HSLColor {
    HSLColor(
        l.0 + (r.0 - l.0) * v,
        l.1 + (r.1 - l.1) * v,
        l.2 + (r.2 - l.2) * v,
    )
}

DaMilyutin avatar Jan 04 '22 03:01 DaMilyutin