davbol
|
116's lerpColor(), HSB?
Oct 2nd, 2006, 9:22pm
First, thanks for lerpColor in 116, I'm often lerping colors and will be glad to retire my own code for it.
But.. lerping in RGB space frequently produces "mud" if you cross into low saturation territory between the two endpoints (common if hue difference is significant). Am just wondering if an HSB version, or a version that respected the current colorMode() setting, would be a useful addition?
Something like this perhaps?: (edited to replace original buggy sample code)
// lerpColorHSB demo
// the original colors from lerpColor() docs color from = color(204, 102, 0); color to = color(0, 102, 153);
void setup() { size(100,100); noLoop(); stroke(255); background(51); }
void draw() { // original lerpColor in RGB space // use more steps to illustrate the "mud" near 0.5 for (int t=0; t<=10; t++) { color c = lerpColor(from, to, t/10.0); fill(c); rect(t*10, 0, 9, 40); } // lerpColor in HSB space, no "mud" for (int t=0; t<=10; t++) { color c = lerpColorHSB(from, to, t/10.0); fill(c); rect(t*10, 50, 9, 40); } }
// linear interpolate two colors in HSB space color lerpColorHSB(color c1, color c2, float amt) { amt = min(max(0.0,amt),1.0); float h1 = hue(c1), s1 = saturation(c1), b1 = brightness(c1); float h2 = hue(c2), s2 = saturation(c2), b2 = brightness(c2); // figure out shortest direction around hue float z = g.colorModeZ; float dh12 = (h1>=h2) ? h1-h2 : z-h2+h1; float dh21 = (h2>=h1) ? h2-h1 : z-h1+h2; float h = (dh21 < dh12) ? h1 + dh21 * amt : h1 - dh12 * amt; if (h < 0.0) h += z; else if (h > z) h -= z; colorMode(HSB); return color(h, lerp(s1,s2,amt), lerp(b1,b2,amt)); }
|