Wierd HSB behaviour

edited January 2017 in Questions about Code

Hey guys, first time poster here. Slap me on the wrist if im doing anything wrong :)

I tried to write a fast and dirty hsb colorwheel, but its not behaving right, and i can't see the error outright. Anyone mind having a look at it?

void setup() {
  size(500,500);
}

void draw() {
    background(0);
    float ox = width/2;
    float oy = height/2;
    //float rad = 200;
    colorMode(HSB,360,200,100);
    for (int r = 100; r < 200; r++) {
      for (int ang = 0; ang < 359; ang++) {
        stroke(ang,r-100,100);
        strokeWeight(1);
        point(ox+(cos(ang)*r),oy+(sin(ang)*r));
      }
    }
    noLoop();
}

It creates a ring like this

Answers

  • (the output of your code looks a bit ugly - I'd use pixel level (or shaders, if you can) if I were you)

  • Cos and sin in Processing require their inputs in radians.
    So change line 15 to point(ox+(cos(radians(ang))*r),oy+(sin(radians(ang))*r));

  • edited January 2017

    I'm sorry. I was not clear enough on what went wrong. The thing I want to change is have the color gradient go from red to red around the circumference of the circle. Not repeating every 5 line or so.

    -Edit-

    Never mind. The radians thing did the trick. thanks! Last time i used cos and sin in a program it was GarrysMods Wire Expressions and they don't care x) Again thanks, and ill check out pixel levels

  • edited January 2017

    @Strix -- Now that your HSB is rendering correctly...

    ...if you also want "quick and dirty" to be just a little less dirty, change the angular loop on line 12 to a float loop that iterates through fractions of a degree. This will give a cleaner, less pixel-gapped look to the resulting color wheel.

    void setup() {
      size(500,500);
    }
    
    void draw() {
        background(0);
        float ox = width/2;
        float oy = height/2;
        //float rad = 200;
        colorMode(HSB,360,200,100);
        for (int r = 100; r < 200; r++) {
          for (float ang = 0; ang < 360; ang=ang+0.1) {
            stroke(ang,r-100,100);
            strokeWeight(1);
            point(ox+(cos(radians(ang))*r),oy+(sin(radians(ang))*r));
          }
        }
        noLoop();
    }
    

    Screen Shot 2017-01-22 at 3.58.30 PM

  • Or use shaders/pixel handling. Probably faster. Much faster if you use shaders.

    Directly in Processing-

    • Load all pixels.
    • Calculate distance (or distance squared, if you know how) of pixel from center.
    • If the distance (radius) is between lower limit (100) and upper limit (200), the pixel is in the ring. Othwise, skip to next pixel (use continue).
    • Calculate angle of pixel relative to center using atan2().
    • Set it's color according to the angle.

    Using shaders, process is effectively same, implementation is different.

Sign In or Register to comment.