color saturation() bug

Hi there, I think I'm onto a bug here: So I'm trying to tweak a color using the mouse wheel in specific regions of the canvas. If you scroll in the first 1/3 of the width, it changes hue, then from 1/3 to 2/3 it changes saturation and then brightness for the last 1/3 of the canvas width. I do this using some increments, well, it's easier to understand in the code:

color c;
float hueShift=0,satShift=0,brightShift=0;
void setup() {
  c = color (200,230,30);
  size (300,300);
  textAlign(CENTER);
  text("",0,0);

}
void draw () {
  background(c);
  colorMode(HSB,255,255,255);
  c=color(constrain(hue(c)+hueShift,0,255),
          constrain(saturation(c)+satShift,0,255),
          constrain(brightness(c)+brightShift,0,255));
  text(hue(c)+" "+saturation(c)+" "+brightness(c),0.5*width,0.3*height);
  text(red(c)+" "+green(c)+" "+blue(c),0.5*width,0.6*height);

  hueShift = 0;
  satShift = 0;
  brightShift = 0;
}

void mouseWheel(MouseEvent event) {
  float e = event.getCount();
  if (mouseX<(0.33*width)) hueShift = -int(e);
  if ((mouseX>(0.33*width))&&(mouseX<(0.66*width))) satShift = -int(e);
  if (mouseX>(0.66*width)) brightShift = -int(e);
}

the weird part is that is fails to DECREASE saturation, whatever i do. any ideas? thanks

Answers

  • in fact, i think the problem is when adding negative values for saturation, because i've also tried to change the "satShift=0" to -1 in draw() and nothing happens. What do you guys think? Is it a bug or am i doing something shady?

  • also tried with mouseDragged,just in case my mouse wheel was crazy, but it's still acting very strange:

    color c;
    int hueShift=0, satShift=0, brightShift=0;
    float c_hue, c_sat, c_bright;
    int shift =0;
    
    void setup() {
      c = color (200,230,30);
      colorMode(HSB,255,255,255);
      size (300,300);
      textAlign(CENTER);
      text("",0,0);
    
    }
    void draw () {
      background(c);
      c_hue=constrain(hue(c)+hueShift,0,255);
      c_sat=constrain(saturation(c)+satShift,0,255);
      c_bright=constrain(brightness(c)+brightShift,0,255);
      c = color (c_hue,c_sat,c_bright);
      text(hue(c)+" "+saturation(c)+" "+brightness(c),0.5*width,0.3*height);
      text(red(c)+" "+green(c)+" "+blue(c),0.5*width,0.6*height);
      hueShift = 0;
      satShift = 0;
      brightShift = 0;
    }
    
    void mouseDragged () {
      shift=0;
      if (mouseY-pmouseY>0) shift=-1; else if (mouseY-pmouseY<0) shift=1;
    
      if (mouseX<(0.33*width)) {hueShift = shift;}
      if ((mouseX>(0.33*width))&&(mouseX<(0.66*width))) {satShift = shift;}
      if (mouseX>(0.66*width)) {brightShift = shift;}
    }
    
  • I think this is caused by a combination of rounding and feedback loop. Also your code needs some cleanup. The simplest solution is to just have three variables (h, s, b) that you set and use in the mouse method. There is no need to have anything besides display in the draw() method.

    Adapted Code

    color c;
    float h, s, b;
    
    void setup() {
      size(300, 300);
      c = color(58, 133, 32);
      h = hue(c);
      s = saturation(c);
      b = brightness(c);
      textAlign(CENTER);
    }
    
    void draw () {
      background(c);
      text("hue: " + round(h) + " / sat: " + round(s) + " / bright: " + round(b), 0.5 * width, 0.3 * height);
      text("red: " + round(red(c)) + " / green: " + round(green(c)) + " / blue: " + round(blue(c)), 0.5 * width, 0.6 * height);
    }
    
    void mouseWheel(MouseEvent event) {
      float e = -event.getCount();
      if (mouseX < 0.33 * width) {
        h = constrain(h + e, 0, 255);
      } else if (mouseX < 0.66 * width) {
        s = constrain(s + e, 0, 255);
      } else {
        b = constrain(b + e, 0, 255);
      }
      colorMode(HSB);
      c = color(h, s, b);
      colorMode(RGB);
    }
    
  • huh, just checked this thread randomly, and I noticed the reply. No notification, nothing. Anyway, thank you kindly, Amnon, for the rewrite. I works perfectly. I've put them side by side to figure out what went wrong in my code, and it seems simplicity is not only important, but mandatory, for this to work. One more question, though, if you want to indulge me - when I want to store the values as HEX, to make color palettes that i can save and retrieve later - how does it work? If I do a data[i]=data[i]+"#"+hex(mycolor,6); WHILE in HSB colorMode, won't that store the hue/sat/br values instead, and upon reading that document within RGB colorMode I'll get different colors?

    Or, as good practice, should I always convert my colors to RGB,255 before hex-ing them?

  • edited November 2014
    • The # prefix is understood by Processing's pre-processor only. It's syntax sugar, not Java!
    • # means ARGB w/ A = 0xff. For example: #4080FF = 0xff4080FF.
    • And when we enter a color as a whole value, it's always treated as ARGB.
    • And PImage's pixels[] stores color pixels as ARGB always.

    https://processing.org/reference/color_datatype.html
    https://processing.org/reference/pixels.html

Sign In or Register to comment.