Help! saturation() function seems wacky!

edited February 2015 in Questions about Code

Here is a snipet of node:

 colorMode(HSB, 255);
  color c = color(200, 230, 20); 
  println("sat: " + saturation(c));
  println("hue: " + hue(c));
  println("bright: " + brightness(c));

which returns the value of (242, 199, 20).

This should NOT be the case.

I wrote a function unsaturate, which behaves even stranger:

color unsaturate(color c, float s) {
  println("old sat:  " + saturation(c) + ", s: " + s);
  color newc = color(currHue, saturation(c) - s, brightness(c));
  println("curr sat:  " + saturation(newc));
  return newc ;
}

color mycolor = color(200, 200, 100); when unsaturate(mycolor, 10) is ran, the saturation goes from 255 to 255 - the kicker is, my original saturation is not even 255!

Completely confused, been on it all day.

Tagged:

Answers

  • @ miaomiao==

    Not really sure about that but i guess that color c = color(200,230,20) when compiling is translated into a color which is no more something like you have written but some negative value obtained through complex operations, binary + two'sComplements, without any immediate sense for us. Then, when you call the saturation() method with c, c is this pointed color and saturation is recalculated from that, not "got" from your initial code. Yet the result, for us, is the same screen color. Try this :: you can see that the 2 rects have the same color. Same result if instead of your hardcoded value for B you put my var nbre...Though i repeat i am not sure...Furthermore i dont know wether the human eye is able to diffrenciate 2 colors which are only separated by 1 or 2% of saturation...

        int nbre = 0;
    
        void setup(){
    
          size(400,400);
          background(255,255,0);
        };
    
        void draw(){
          frameRate(5);
        noStroke();
        colorMode(HSB, 360,100,100 );
        color c = color(360,nbre,100);
        println(c);
    
        fill(c);
        rect(15, 20, 35, 60);
    
    
        float value = saturation(c);  
        println(nbre + "   value====" + value);
        fill(360,value,100);
        rect(150, 200, 350, 400);
    
        nbre = nbre+1;
    
        if(nbre==100){
          noLoop();
        }
        };
    
  • edited February 2015

    Although it is possible to convert RGB to HSB it is not always possible to reverse the process and get the same RGB values that you started with.

    For instance if the saturation is zero then you get a shade of grey from black (b=0) to white (b=255) for ALL values of hue so

    h = 255  s = 0  b = 128
    h = 128  s = 0  b = 128
    h = 0  s = 0  b = 128
    

    all produce the same colour, a mid grey. So there is no way we can get the original hue value because it could be anything between 0-255

    If the colour is fully saturated then it is possible to recalculate the original hue and brightness values. BUT the algorithms used mean the recalculated hue and brightness will be close, but not exactly the same as the originals.

    You can test this with the following code

    size(300,200);
    background(255);
    noStroke();
    int h = 128, s = 0, b = 128;
    colorMode(HSB, 255);
    int c = color(h, s, b);
    fill(c);
    rect(0,0,width,100);
    colorMode(RGB, 255);
    fill(0);
    text("hue:    " + h + " >>> " + hue(c), 20, 130); 
    text("sat:    " + s + " >>> " + saturation(c), 20, 160); 
    text("bright: "  + b + " >>> " + brightness(c), 20, 190);
    
  • @quark:: you said "not exactly the same as the originals" & i agree as well as i understand that setting s to 0 make every hue becoming grey scaled according to brightness; what i cannot understand is that the values returned for s does not seem to be only "approximative" with little % difference but obeying to some kind of logic i dont understand: given some hue and brightness the s varies by multiplying *2 each 12 values, like a cycle. See the console:

            int nbre = 0;
    
            void setup(){
    
              size(600,600);
              background(255,255,0);
            };
    
            void draw(){
              frameRate(5);
            stroke(0,0,0);
            colorMode(HSB, 255);
            color c = color(200,nbre,20);
            //println(c);
            //println( "brighness     " + brightness(c));
            //println("hue      " + hue(c));
            fill(c);
            rect(150, 180, 35, 20);
    
            noStroke();
            float value = saturation(c);  
            println(nbre + "   value====" + value);
            fill(200,value,20);
    
            rect(150, 205, 350, 300);
            nbre = nbre+1;
            if(nbre==100){
              noLoop();
            }
            };
    
Sign In or Register to comment.