Hue angle to RGB
The hue angle H is the coordinate shared by HSV and HLS. Turning the angle into RGB is the first step of converting both models back to RGB. You first compute the pure color of that hue, and only then add saturation and brightness.
The color wheel as a hexagon
In HSV and HLS the color wheel is really a hexagon: every 60° there is one corner of the RGB cube. Between corners one component rises or falls linearly while the others stay fixed:
| H | R | G | B | What changes |
|---|---|---|---|---|
| 0°..60° | 1 | rises 0 → 1 | 0 | red → yellow |
| 60°..120° | falls 1 → 0 | 1 | 0 | yellow → green |
| 120°..180° | 0 | 1 | rises 0 → 1 | green → cyan |
| 180°..240° | 0 | falls 1 → 0 | 1 | cyan → blue |
| 240°..300° | rises 0 → 1 | 0 | 1 | blue → magenta |
| 300°..360° | 1 | 0 | falls 1 → 0 | magenta → red |
A formula without branches
The whole table fits into three absolute-value formulas. Let h = H / 60°, and let clamp cut the result to 0..1 (see helper functions):
For H = 15°: h = 0.25, so P = (clamp(1.75), clamp(0.25), clamp(-1.75)) = (1, 0.25, 0), i.e. RGB (255, 64, 0).
| H | RGB of the pure color | |
|---|---|---|
| 0° | 255, 0, 0 | |
| 30° | 255, 128, 0 | |
| 60° | 255, 255, 0 | |
| 90° | 128, 255, 0 | |
| 120° | 0, 255, 0 | |
| 180° | 0, 255, 255 | |
| 200° | 0, 170, 255 | |
| 240° | 0, 0, 255 | |
| 300° | 255, 0, 255 | |
| 330° | 255, 0, 128 |
Adding saturation and brightness
With the pure color P, any HSV or HSL color follows from one formula:
For HSV (15°, 80%, 78.4%):
For HSL (15°, L 47.1%, S 66.7%): C = 0.9412 · 0.6667 = 0.6275, and RGB = 0.4706 + 0.6275 · (0.5, -0.25, -0.5) = (0.7843, 0.3137, 0.1569). The same color.
Code
const clamp = (x) => Math.min(1, Math.max(0, x));
// pure color for hue h in degrees
function hueToRgb(h) {
const t = (((h % 360) + 360) % 360) / 60;
return {
r: clamp(Math.abs(t - 3) - 1),
g: clamp(2 - Math.abs(t - 2)),
b: clamp(2 - Math.abs(t - 4)),
};
}
function hsvToRgb(h, s, v) {
const p = hueToRgb(h);
const f = (c) => v * (1 - s + s * c);
return { r: f(p.r), g: f(p.g), b: f(p.b) };
}
The reverse conversion, from RGB to a hue angle, is on the RGB to hue angle page.