Generating a cylinder to represent HSB colour space

While we have generated the “top” of the HSB cylinder, generating the whole cylinder might be trickier. I mean we could create a cylinder just fine, but wrapping the colour space around it might be more challenging. But there is a slight-of-hand trick that can be used.

Basically, some ways of viewing a cylinder make the top of the cylinder appear as an ellipse. That shows the top surface as the 360 degrees of hue, and the saturation component, going from 100% along the edges to 0% in the centre. What we want to do is show the side of the cylinder, which represents the hue in combination with the brightness (100% at the top, 0% at the bottom). We don’t really care about the hidden portion of the cylinder.

The HSB colour space represented as a cylinder.

So the easiest way of creating this is actually stacking 100 ellipses. The bottom ellipse will be generated using all the hues, the saturation going from 100% on the periphery to 0% in the middle, and a brightness value of 0%. Each ellipse stacked on top will have the brightness incremented by 1%, until we hit the topmost ellipse with a brightness of 100%.

The first thing to do is set up the environment, setting up an 800×800 sketch space, and setting up the colour space to HSB.

void setup() {
  size(800, 800);
  noStroke();
  colorMode(HSB, 360, 100, 100);
  background(255,0,100);
  noLoop();
}

Next we create the draw() procedure:

void draw() {
   float y = 400;
   int totalsteps = 100;
   int stepcount = 0;
   int z, b = 1;

   strokeWeight(5);
   y = 500;
   while (stepcount < totalsteps){
      drawellipse(200,50,400,y,100,b);
      y = y - 2;
      stepcount = stepcount + 1;
      b = b + 1;
   }
   
   z = 100;
   for (int i=200; i>=1; i=i-2){
      drawellipse(i,i/4,400,y,z,100);
      z = z - 1;
   }
}

Lines 8-14 generates the 100 different ellipses, using the procedure drawellipse(). The parameters of the procedure set the major-axis (200), and minor-axis (50) of the ellipse, and the x- (400), and y- coordinates, the latter of which is modified in each iteration of the loop. The last two values are the saturation (100), and brightness (b). After the ellipse has been drawn, the position (y) is modified, and the brightness (b) is incremented. Lines 16-20 generates the top of the cylinder. It makes progressively smaller ellipses, and reduces the saturation (z) of each ellipse while maintaining brightness.

Finally there is the drawellipse() procedure. The procedure uses polar coordinates to draw the edge of the ellipse with the appropriate hue. Each of 360 degrees are processed, with each having a particular hue.

void drawellipse(float rx, float ry, float xc, float yc, int s, int b) {
   float step = 1;
   float dx, dy, r;
   int hue = 0;
   
   for (int theta=0; theta<=360; theta=theta+1){
      r = radians(theta);
      dx = xc + rx * cos(r);
      dy = yc - ry * sin(r);  
      stroke(hue, s, b);
      point(dx,dy);
      hue = hue + 1;
   }
}

where the parameters are:

rx = ellipse major-axis
ry = ellipse minor-axis
xc = x-coordinate
yc = y-coordinate
s = saturation (0-100)
b = brightness (0-100)
Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.