20 February 08
After three weeks in development, here's how the HSL color cube came together.
HSL color cube: Behind the scenes

The HSL cube is by no means a revolutionary tool or phenominal exhibit of programming prowess — that was never the goal. The purpose of this project was to dive head first into programming. I had a finished product in my head, I just had to decipher how to get there. I utilized several resources to put it all together: other’s code, Wikipedia articles, and old techniques of my own. After three weeks in development, here’s how it all came together.
Creating
I had originally worked on a HSL color selection tool for an AVS . That version was a typical hue circle and luminance/saturation color square, similar to what you see in most color selection tools. I was able to handle hue and saturation values together, but adding in luminance was perplexing. My formula for luminance was off – just a linear formula with one conditional. That’s about as far as I got. I dropped the project and never got the actual color selection to work properly.
While this creation was somewhat crude, it provided the basis to tackle the HSL cube. I ported it over to the Processing environment to begin the project. I was initially thrilled when I managed to get the color panel to display. Imagine having the window completely gray, trying it again, and now I’m looking at a smooth red gradient, just as I envisioned. Now using a higher-resolution gradient I could easily see that the luminance formula was wrong. At this point, I was looking under the hood at Steven Wittens’ Farbtastic color picker. His tool is written in JavaScript – a language that is still mostly foreign to me. But I was able to decipher that he used the proper calculation for converting HSL to RGB. This matched with the formula on Wikipedia and the instructions from a fellow AVSer . Using Steven’s JavaScript code as a model, I was able to create my own HSL to RGB conversion method. Now that it was ablet to display the colors properly, it needed to be able to do something.
The first version of the HSL color picker had arbitrary GUI elements. Each button and slider was coded separately, fairly clunky, but it worked for the time being. This kludginess was the result of previous experience programming in AVS. In that environment, there was no such thing as classes (Which is a shame. Looking back I see that the majority of my visualizations were all basically playing on the concept of iterations of the same class). I was introduced to classes in a Ruby programming class I took a couple weeks ago. At that time, my understanding of it was especially clumsy. But I was able to wrap my head around methods, so classes were just an extension of that. Buttons were the easiest to experiment with, then the sliders. I built in GUI functionality where if you click on one element, and drag the cursor across the window, it should only effect that one element. This is one of those behaviors that seems obvious, since everyone is used to it in any GUI operating system, but you have to consider it when starting out tabula rasa. Once each slider was set up, I had the appropriate values (separate hue, sat and lum) to approach switching the color panel from a 2D square, into a pseudo 3D cube.

I say pseudo 3D simply because there’s no true 3D computation going on in this tool. It’s actually isometric pixel art , with a 1:2 pixel ratio (see “eboy“http://hello.eboy.com/eboy/index.php” for incredible examples). I worked out the formulas on paper, drawing each pixel on a grid and figuring out how to arrive at those values. There’s something easily accessible and approachable when physically writing down the problem at hand. It cuts right through any levels of abstraction that develop when working on a computer.
Next element was the cursor on the 2D color panel. Selecting a color was easy enough. Just point HSL values to the XY values of the mouse. The real task would be coordinating the cursor with the sliders and buttons, and visa versa. So that when you change the hue value on the slider, the position of the cursor changes, AND it works the other way as well. Surprisingly, this was relatively easy to implement and not nearly as frustrating as I originally expected. Last bit was rendering the color selected and adding text to display the numerical values of the color.
It worked. Just as I had first envisioned. Oh sweet delights, dream of dreams.
Perhaps the most worthwhile process in creating this tool was going back into the code and finding places where it could be improved or condensed. The color panel was originally rendered using a big clunky formula that was custom to the selection. Revisiting it, I was able to wipe out each formula and use the isometric-to-2D method I previously created for the lines. I then went back and used that method whenever I could. There was also some streamlining by creating a superclass for GUI elements.
Known Bugs and Items of Improvement
- Clicking outside a GUI element and dragging it on top of a GUI element will select that GUI element
- Sometimes when switching from the Luminance panel to the Hue Panel, there will be a missing row of pixels in the 3D color panel
- The white vertical line marking in the cube doesn’t move on the X axis with the color panel
- Buttons should have icons representing which panel you’d be selecting
- Color panels shouldn’t be re-rendered every frame. Only when the appropriate value changes
Further Discussion
I realize that a cube is not the ideal model for the HSL color space. Since the hue value is a loop (red, yellow, green, cyan, blue, magenta, back to red), it should be representened as a circle. The shape itself would then be a cylinder (like a color cheese wheel). Moreover, since there only one point necessary for both white and black, the top and bottom sides of the wheel should be condensed to a single point, thus forming a double cone. The discussion page of the HSL Wikipedia article address these models in detail . Some suggest that a sphere might be appropriate. For the sake of simplicity and my own sanity, I always intended for this to be a cube. I do have some sketches of making a double cone, but that’s for a possible future project.
Previous
You're looking at a post in the blog section.
Commenting is closed for this article.