The Interactive Color Wheel has been my pet project, on and off, for over
12 years now. For the really curious, here is a history of its
-- Rich Franzen
- 0.80: 7 Sep 98
First operational version. Drew the wheel with 16 saturation levels
and 60 hues. A TestField and [Intensity] button allowed the user
to alter intensities. Saturation ring width was fixed at 16
pixels. Intensity was calculated in accordance with "Touslah's pie":
power = 2.0 / pi;
ratio = 255.0 / pow(70, power);
int255[i] = ratio * pow((double)i, power);
- 1.00: 8 Sep 98
First posted version. Had a label next to the intensity button
letting the user know the range was 0..70. No error checking in
text field, though, and user could type anything. SIHCanvas would
protect itself and bound the intensity between 0 and 70, however.
Saturation ring width was lowered to 15.
- 1.10: 9 Sep 98
Added [-i] and [+i] buttons to make intensity changes easier. Also
added the [-] [Rings][+] buttons. "Rings" would toggle the
saturation ring delineation circles on and off. The minus and plus
buttons would resize the saturation ring width from between 10 and 16.
Default ring width was 12. The intensity controls were made smart
enough not to try to send out-of-bounds values to SIHCanvas.
- 1.20: 12 Sep 98
Added the concept of augmentation for the hues. Looking at the
wheel, it was obvious that 6 degrees per hue wedge was not enough.
The wheel naturally divides into 6 domains, each 60 degrees apart.
The domains are red, yellow. green, cyan, blue, and magenta.
All the domains except yellow and green could be augmented to
5 degrees per hue wedge. The wedges can still be discerned,
but maximum hue error was cut to 2.5 degrees. And in the 16-bit
SIH color space, there were a maximum of 8 augmenting wedges;
fortunately the yellow and green domains don't need any.
- 1.30: 14 Sep 98
- Added the intensity wedge and activated the mouse within the
SIHCanvas. Clicking on the intensity wedge changes the wheel,
and clicking on the wheel changes the color (sat:hue combination)
of the intensity wedge. Default ring width was raised to 14, which
corresponds to the height of the wedge.
- Added a validator for the TextField controlling intensity so that
it would only allow input of numbers. AWT could really use a
- 1.31: 16 Sep 98
Stopped using Touslah's Pie for intensity mapping. Intensity is
now treated linearly: i = (255.0 / 70.0) * i;
- 1.35: 19 Sep 98
Made new method getSIHColor(). It greatly simplifies the paintWheel()
and paintWedge() methods. Since SIH colorspace supports at least
256 levels of grey, I de-quantized the wedge when desaturation is
100%. Also, now when the wheel wedge is 12 or less, color wedge
height is 5, otherwise it is 6. (It had been constant at 6 before.)
- 1.36: 24 Sep 98
Moved triagonal drawing ahead of grey filled-circle drawing of
wheel. I think it looks better to have the grey wheels without the
- 1.37: 26 Sep 98
Made the background for the wedge label the same color as the
selected wedge point. Made the background and foreground colors
fixed. Changed default augmentation to __MR, which will be the
normal SIH condition. Changed scaling of deSat parameter of
getSIHColors() to [0.0, 1.0]. Various clean-ups.
- 1.40: 26 Oct 98
- Implemented the 'Pale Parables', which sacrifice the palest hues for
an extra saturation level when the intensity is at least 17. So for
most hue:intensity combinations, there are 16 saturations rather than
15. It also adds 5.5 extra intensities, increasing this to 76.5 total.
(Intensities 6 thru 16 give up hues to build intensities 1 thru 5.
Intensity 1 goes further, and gives up 12 hues to create intensity 1/2.
From 17 and up the hues are traded for the extra saturation level.)
- Because of the extra saturation level, I reduced the max ring width
from 16 to 15. Otherwise the whole applet would have needed to
be made larger.
- Changed the default augmentation from __MR to C__R. This will be
the normal state for SIH images. Now the 240 degrees that contain
green as a color-determinant are optimized.
- The intensity wedge was modified to be a kind of "intensity cone".
This was to give some additional feedback to the user of what the
entire color space is like. I also "topped" the cone with a rounded
- Added the lumaBars to show the relative luma level wrt grey level.
These helped me find a bug in calculating hues; it was being
miscalculated for the hue wedges immediately clockwise from the
RGB primary hue wedges.
- Deleted NumericValidator class. It was too simplistic to the
point of being obnoxious, and it didn't handle intensity = "0.5"
- 1.41: 27 October 1998
- Factored GetEweUp() and GetEweDown() functions from getSIHColor(),
which greatly improved readability.
- Changed default tileWidth to 12 so that applet would fit well on
- Explicitly defined the font for applet to use. It appears that the
first time it is used is in the labelWedge() procedure, which is
counter-intuitive. I would have thought it would be defined first
in update() or paint().
- Handled "dot on wheel" issues better for intensities 0 and 1/2. There
was a buglet at these intensities that annoyed to me.
- 1.42: 27 October 1998
- Fixed bug in GetEweDown() that showed up in 1.40 when I limited inner
ring to 12 hues total. The hue wedges for yellow, cyan, and magenta
had had their hues calculated badly when paleState was 2.
- Modified lumaBars a bit; the height of the grey bar is no longer a
constant 200 pixels. It varies from 115 to 200, getting bigger
as intensity gets brighter. This really has nothing to do with luma;
I just thought it was more aesthetically pleasing to do this. The
actual luma bar has always been a %height of the grey bar, so there
is no real change, and the displayed luma% value is not affected.
- Allowed Color Wedge to move a bit inward. Basically, the smaller
the circle (and wedge height), the closer the wedge is to the center.
There are three increments, controlled by whether wedgeHeight is
4, 5, or 6 (which is controlled by the thickness of the saturation
- Added a bit of order to the class variables of SIHCanvas. This should
help interpretability and maintainability of the code.
- 1.43: 14 November 1998
- The wedge label now shows the previous wedge color in its upper
left-hand corner. This is useful in detecting small changes.
- I reduced the maxI to 73 from 75 to match what can be accomplished
with the Pale Parables and condensed Shadow Soup. I originally
thought that the Pale Parables could give me 5 1/2 new intensities,
but I now realize they only give 1 1/2. So I condensed the Soup
a bit to still have at least 73 saturated intensity levels.
- The condensed Shadow Soup means implimenting a more complex scheme
for determining number of rings. Some of the ring counts below
16 are repeated now.
- Began adding infrastructure to enable this applet to be used as
an interactive color blindness aid. I'm running on ignorance now,
but something needs to be there so that when a color blind person
begins testing it, he can manipulate the color balance.
- 1.44: 18 November 1998
- Slightly offset the "previous wedge color" location so that it stands
out a bit.
- Added explicit display of absolute r:g:b and h:s:b values. These
are inset into a background of the luma value of wedgeColor.
- 1.45: 22 November 1998
- Raised saturated intensity levels to 74. Raised applet height to 636.
- Began writing HSB and RGB values to console.
- Calculate width of luma printout every time (varies by platform).
- Made the last color wedge a little bigger. Added luma recthangle
and intensity square.
- 1.46: 22 November 1998
Repositioned luma rectangle a bit so as to geometrically be cropped
a bit by the intensity square.
- 1.47: 24 November 1998
- Added a saturation bar at the bottom of the color wedge. Because the
control pane's bright white interfered with seeing this, I added a
black line to separate the two panes, and darkened the background
of the control pane.
- Made the RGB:HSB wedge a bit wider. Well, not really; the string used
to compute its maximum width is now defined properly. It had
intentionally been defined with some missing spaces, because under
jdk 1.1.x of win32 platform, the stringWidth() method treats spaces
as too wide. But the Solaris platform properly can compute the width
of a string, so I chose to write the code properly and hope that in
jdk 1.2, this win32 problem will be fixed.
- 1.48: 30 November 1998
- Added the lumaSnake to show the 3x3x3 array of colors "closest"
to the selected color. The colors are sorted by luma, and
drawn in a rectSnake pattern.
- Added class RectSnake. This allows easy drawing of spiralling
rectangular regions within a larger region.
- 1.49: 6 December 1998
- Worked on the button panel colors. Color inheritance is handled
differently between Win95 and Solaris. In Solaris, the buttons
receive the background color of their panel, but in Win95, they
do not. So now I explicitly set the colors on the buttons so that
the applet (hopefully) behaves the same, and has readable buttons,
in all environments.
- Fixed oversight in RectSnake class. I had meant from the
beginning to handle an overflow case, but this did not make
it into the class. It's there now. I also handle the case
of a null rectangle in the getNext() method (although when
I use the class, I supply my own rect from outside).
- 1.50: 17 December 1998
Added the "wheel of saturn" (satSnake). It is an 8x8 rectsnake
containing the full set of hues in one saturation ring. They are
ordered by luma.
- 1.60 31 December 1998
Switched positions of the sat and luma snakes. Deleted the
[Intensity] button after finally fixing the intensity text
field so that typing Enter within the field causes an update
- 1.61 7 January 1999
Defaulted the satSnake to luma-only mode. It is kind of ugly and
garrish, and probably meaningless to most people as a set of
saturated colors sorted by luma. But in luma-only mode, it shows
the brightness range of the current saturation level in a nice-looking
way. If the satSnake is clicked, it toggles between luma-only and
- 1.62 18 July 1999
Tweaked intensity to be 7/255 when 3 is selected. This was
always in the design, but I overlooked it until I began
coding the png16 library.
0 -> 0, ½ -> 2, 1 -> 4, 2 -> 7, 3 -> 10
from 3 on, the formula is: out = in * 255 / 74
- 1.63 19 July 1999
Added pseudo-grey support. This is active when no more
than 2 color domains are augmented. In png-16, red and
cyan are always augmented. Blue and Magenta are treated
as a pair; if you need 4096 greys, then these two domains
are not augmented, otherwise they are. The SIHwheel applet
is more flexible in this regard, but an image format should
limit its feature set to really useful stuff.
- 1.64 19 July 1999
Put pseudoGrey logic in its own method, getPseudoGrey().
Don't ask why I didn't do this in the first place...
- 1.65 14 April 2000
Added infrastructure to toggle between luma ("luma"),
luminance ("Luma"), and average ("ave"). Clicking the
word luma in lower left of window does the switch, and
the graphics update as appropriate.
- 1.66 20 April 2000
Placed brackets around text "luma", "Luma" and "ave" to better
indicate that this text item is a button.
- 1.67 27 May 2000
Modified rgb printout from decimal components to HTML-style hex.
- 1.70 6 June 2000
Modified display of brightness wedge so that it followed the
'lumaOnly' mode flag. Until now, the wedge was always in color
even if the wheel were forced to grey.
- 1.80 24 Sep 2010
- Fixed two items so code would compile with modern JDK.
- Added window listener so as a program, the windows close gadget functions.
- Eliminated CBMR string; replaced with changing foreground color on buttons.
- Increased canvas size from (630, 640) to (640, 700).
- 2.00 28 Sep 2010
- Converted ntc.js (Name-That-Color) to java, and added color name
- No extra control widgets at this point. Converted
GetSnake() into GetRectangle() and expanded its scope to supply
most areas of interest, in one place.
- 2.01 1 Oct 2010
- Added an enum (AoI) to give names to the area of interest.
- Fixed both the Last Color box and the Hueborhood, which v2.00 broke.
- 2.02 5 Oct 2010
Activated the Last Color and Exact Color blocks to set in their
- 2.03 7 Oct 2010
Added the [-G] control to reign-in the green mass and provide more
yellows and cyans.
- 2.04 9 Oct 2010
- Implemented display of quantization error. To activate, click the small,
square brightness box in LLC of wedge label. Deactivate the same way.
- Wasn't going to publish, but also fixed a small display defect. When
the line would be cleared for the "[Luma] = " text, and the wheel
was full size, it would chop a small bit from the wheel upon clearing.
Narrowing the rect width from 120 to 110 fixed it.
- 2.10 15 Oct 2010
Switched GUI toolkit from awt to Swing. Added toolTips to GUI items
at bottom. (Posted in Junk folder to get feedback on screen
- 2.11 16 Oct 2010
- Remembered lastDot location on wheel so can usually show
current and last colorwheel dots even on a full paint.
- Cleaned up classes a bit by making what can be private, private.
- Moved the display of date and version from paintComponent() to miscLabels().
- 2.20 18 Oct 2010
- Achieved full, sortable, color list functionality. Added list widget,
radio buttons for sorting, and a hex-color entry field. Abandoned
attempt to component-level updates via partialOnly(). (Oops, just
noticed the method itself did not get deleted or commented out. It's
not used, though.)
- Remember and display last two wheel-dot locations.
- Adopted a contentPane and invokeLater:run() paradigm for launching.
- 2.21 18 Oct 2010
- Fixed invisible cursor problem.
- Renamed one of the two "Red Violet"s.
- Added support for 3-digit CSS hex color entry.
- Forced display of name selected from list widget. Mismatch can occur
from the time one clicks a name from the list, until the internal logic
calls NTC.name(), sometimes yielding a different name than the one clicked.
- 2.22 19 Oct 2010
- Got rid of an unnecessary large array, sortedList.
- Hard wired list cell height to 20. It defaulted to 18 on my system,
but varied on other systems. One person had it at 17. I went two bigger
than my default, hoping it will work for everyone. This caused me to
change the number of visible rows from 32 to 29.
- Fixed almost-invisible title above the
sort buttons, and extended that panal's toolTip to each of the buttons.
- 2.23 20 Oct 2010
- Fixed the slow sort mode it would go into after a selection from list
- Added complementary color feature.
- Changed display of
QE so it is always above the color name.
- 2.24 22 Oct 2010
- Renamed GetRectangle() to getRectangle().
- Toggled off sort buttons during sort.
- Handled smarter the writing on colored backgrounds so
the text/dots could be seen better.
- Fiexed oversight in primary mouse handler that prevented mouse clicks
from being seen near right edge.
- Removed the commented-out partialOnly() method.
- 2.25 23 Oct 2010
- Made so would compile with Java target 1.4.
- Added sextant labels to hue-sorted list.
- 2.26 25 Oct 2010
- Added 2-pixel wide black borders around the two control panels.
- This led to reducing the visble row count of list from 29 to 27, and
increasing each cell height from 20 to 21.
- Drew the bulb level 2 pixels
to the left, allowing natural border.
- 2.27 27 Oct 2010
Implemented the Motif Look and Feel. With the default Swing L&F,
the program/app wanted to be 300 pixels wider than it needed to
be on a Mac. I've had verifcation now with the Motif L&F that
windows, Mac, and Unix are all displaying the app the same way.
- 2.28 31 Oct 2010
Added five more sorts, but only two more sort buttons. The two
buttons in the second row are "over-loaded" with extra choices on
Not officially released.
- 2.29 2 Nov 2010
Enhanced clicking Exact Color square; not it also selects that color
in the color list, and scrolls list to make it visible.
- 2.30 6 Nov 2010
- Revised several GUI items, including replacing the 5 sort buttons
with a single JComboBox.
- Added "Spot, the Magic Color Dog" auto-play feature.
- Fixed bug in the display of the colored luma bar in lower left
- 2.31 7 Nov 2010
- Added active display of msec while dragging slider, and modified
the toolTip to include msec when done dragging.
- Deleted a lot of commented out GUI code from before v2.30.
- 2.32 8 Nov 2010
Fixed minor bug concerning rollover of the name list as Spot plays.
- 2.33 9 Nov 2010
- Allowed text fields to cut/copy/paste.
- ColorName.java modified so hue sort will always be in same order.
- 2.34 10 Nov 2010
- Shifted the 3x3 wheel dot 1 pixel NW so actual dot is centered.
- Modified calls to ColorName.getHSI() to match new subdivisions.
- 2.40 15 Nov 2010
Added menu allowing choice of various color name dictionaries,
and offering help (stub), log (stub), and about.
- 2.41 19 Nov 2010
- Prettied-up the about box, and changed a couple of error println's
to dialog error boxes.
- NTC.class modified to use Lab+HSB searching.
- Added cnd_crayola.properties dictionary.
- 2.42 20 Nov 2010
Fixed applet quick-restart bug; old instance not dead before new
one started if left page and re-came back quickly. Moved NTC
data initialization to a "static initializer".
- 2.43 26 Nov 2010
- Fleshed out the "SIHwheel Help" window.
- Kludged bug relating to redisplay of HTML within old JVM.
- Added HelpBox class to generalize a help window.
- 2.44 30 Nov 2010
Fleshed out the "Show Log" window. Still have bells and whistles to
add, but it is already way ahead of the previous stdout report lines.
- 2.45 3 Dec 2010
Added toolTips and colored elements to the "Show Log" window.
- 2.50 4 Dec 2010
Factored out the HelpBox, ColorTable, and ColorBGText classes
into their own files (latter with ColorTable.java).
- 2.51 5 Dec 2010
Allowed copying of Show Log rows to clipboard by moving its
creation up above the declaring of Motif L&F.
- 2.52 6 Dec 2010
- Moved version history from SIHwheel.java to this HTML file.
- Added "SIHwheel Versions" menu item to Help Menu to display this file.
- Unable to get the [Copy QE] button within the logBox to write to the
clipboard when running as an applet. So changed its functionality to
copy the statistics info to within the table, where row(s) can be selected
and copied to the clipboard via Ctrl+C.
- Adding a row to the Color Log now deselects any previously selected rows.
- Left some code in, commented-out, that were attempts to override
applet security and allow button to write to clipboard.
- Made ColorTable class more flexible by not forcing each column to
contain ColorBGText elements.
- 2.53 10 Dec 2010
- Added menu option allowing Spot auto-play to be random.
- Converted QE statistics display to use a table instead of a number of
- Began target compiling for Java 1.5.
- 2.54 11 Dec 2010
- Enhanced ColorTable class to support editing of color columns.
- Made final column editable of top Color Log table.
- Added entry to Color Log when user sorts by hue, showing
named-colors/sextant. This information had been going to System.out.
- 2.55 14 Dec 2010
- Placed the primary classes in package us.r0k.sihwheel
- Placed the ntc support classes in package us.r0k.ntc
- Began using a non-null frame parameter when launching JDialogs.
- 2.56 5 Jan 2011
Added Help for the Color Log.