Rigid Rotation: A Free Mathematical Optimization
Rotation in the ab-plane doesn't change STRESS but halves the worst hue error. A free optimization at phi=-28.2 degrees.
In optimization work, a genuine "free lunch" is rare. Usually, improving one metric means sacrificing another. But sometimes mathematics hands you an unexpected gift: a meaningful gain at zero cost.
This post describes such a gift, discovered during Helmlab's development: rigid rotation in the ab-plane. This operation keeps color difference accuracy (COMBVD STRESS) exactly unchanged while dramatically improving hue angle alignment. We examine the mathematical proof, the practical results, and how it is integrated into Helmlab.
The Discovery
After Helmlab's 72-parameter pipeline was optimized on 64,000+ human observations, the resulting hue angles were examined. The sRGB primaries (red, green, blue, yellow, cyan, magenta) landed at specific hue angles in Helmlab coordinates -- but those angles deviated from intuitive expectations. For example, blue appeared at an angle well away from the expected ~270 degrees.
The first thought was to re-optimize the pipeline parameters to improve hue angles. But this risked degrading STRESS. Then a mathematical observation was made: rigid rotation in the ab-plane does not change Euclidean distance. But does this hold for Helmlab's distance formula too?
Mathematical Proof: Why COMBVD Does Not Change
Rigid rotation rotates all points in the ab-plane by the same angle. If a color's original coordinates are (L, a, b), then after rotation:
a' = a * cos(phi) - b * sin(phi)
b' = a * sin(phi) + b * cos(phi)
L' = L // lightness unchangedThe critical property of this transform: da^2 + db^2 = da'^2 + db'^2. The sum of squared differences in a and b between any two colors is unaffected by rotation. This is a well-known fact in linear algebra: rotation matrices are orthogonal and preserve the Euclidean norm.
Helmlab's Distance Formula
Unlike CIE Lab's simple Euclidean distance, Helmlab uses CIEDE2000-style pair-dependent weights:
DE = ((dL/SL)^2 + wC * ((da/SC)^2 + (db/SC)^2))^(p/2)Here SL and SC are pair-dependent weights:
- SL = 1 + sl * (L_avg - 0.5)^2 -- depends on average lightness
- SC = 1 + sc * C_avg -- depends on average chroma magnitude
The critical question: are SL and SC affected by rotation?
- SL: Depends only on L_avg. L does not change under rotation. SL is invariant.
- SC: Computed as C_avg = sqrt(a_avg^2 + b_avg^2). Since rotation preserves magnitude, C_avg is unchanged. SC is invariant.
Result: every component of the distance formula -- dL, da^2+db^2, SL, SC, and wC -- is unaffected by rotation. Therefore COMBVD STRESS remains exactly identical.
Empirical Verification
To verify the theory, STRESS was computed on all 3,813 color pairs in the COMBVD dataset: before and after rotation.
STRESS difference = 0.0000000000Literally zero. This is not an approximation; it is a mathematical necessity. Rotation is an isometry, and isometries preserve distance.
Minimax Optimization: phi = -28.2 Degrees
Knowing that rotation does not change STRESS, the question becomes: which angle gives the best hue alignment?
Using the expected hue angles of the sRGB primaries (red, yellow, green, cyan, blue, magenta) as reference, the "worst hue error" (hue_max) was computed for each rotation angle. The minimax optimization finds the angle that minimizes the worst case:
The results:
- Before rotation: hue_rms = 25.9 degrees, hue_max = 48.4 degrees
- After rotation (phi = -28.2 degrees): hue_rms = 16.1 degrees, hue_max = 20.2 degrees
- COMBVD STRESS difference: 0.0000000000
The worst hue error was nearly halved. The average hue error dropped by 38%. And the cost: exactly zero.
Why Is a "Free Lunch" Possible?
Under normal circumstances, improving hue angles requires changing pipeline parameters -- which degrades STRESS. In earlier Helmlab versions (v17), hue improvement using a lambda_hue weight increased STRESS substantially (from 23.2 to 31.35).
Rigid rotation is a different mechanism: it does not change pipeline parameters, it only rotates the output coordinates. Under this rotation:
- Lightness (L) is unchanged
- Chroma magnitude (C = sqrt(a^2+b^2)) is unchanged
- da^2+db^2 between any two colors is unchanged
- SL weight (depends on L) is unchanged
- SC weight (depends on C magnitude) is unchanged
Therefore no component of the distance formula is affected. The only thing that changes is the hue angle -- and that is exactly what we want to improve.
Caveat: Hue-Dependent Metrics
This invariance holds on the condition that the distance formula does not directly depend on hue angle. If hue-dependent terms were added to the distance formula (like CIEDE2000's SH term), rotation would change STRESS. Helmlab's current distance formula depends only on L, C magnitude, and da^2+db^2 -- this guarantees rotational invariance.
Comparison with Other Color Spaces
The way Helmlab obtains hue alignment "for free" via rigid rotation contrasts with how other color spaces handle the problem:
- CIE Lab: Hue angles are fixed, no improvement mechanism. The blue region is known to be distorted.
- Oklab: Matrix parameters are optimized to include hue alignment, but this creates a trade-off with STRESS.
- CIEDE2000: Has a hue-dependent SH term in its distance formula, but since the coordinate system is tied to CIE Lab, hue alignment cannot be performed.
- Helmlab: Pipeline optimization (STRESS) and hue alignment (rotation) are independent. Zero trade-off.
Code Example: The Effect of Rotation
npm install helmlabimport { Helmlab } from 'helmlab';
const hl = new Helmlab();
// Helmlab applies -28.2 degree rotation by default.
// Hue angles are aligned with intuitive positions.
// Hue angles of sRGB primaries
const colors = {
'Red': '#ff0000',
'Yellow': '#ffff00',
'Green': '#00ff00',
'Cyan': '#00ffff',
'Blue': '#0000ff',
'Magenta': '#ff00ff',
};
for (const [name, hex] of Object.entries(colors)) {
const info = hl.info(hex);
console.log(`${name}: H = ${info.H.toFixed(1)} degrees`);
}
// Color difference is unaffected by rotation:
const d = hl.deltaE('#e74c3c', '#3498db');
// This value is EXACTLY the same with or without rotation.
// Isometry: distance is preserved, angle changes.
// Palette generation is also identical:
const scale = hl.semanticScale('#3B82F6');
// Hue angles are more intuitive, palettes are exactly the sameTechnical Summary
Conclusion
Rigid rotation is one of those rare "free lunch" examples in mathematical optimization. A -28.2 degree rotation in the ab-plane dramatically improves hue angles without changing color difference accuracy by even a single digit.
This is possible because Helmlab's distance formula depends only on L, C magnitude, and da^2+db^2 -- not on hue angle. Rotation preserves these quantities (isometry), so the distance formula "does not notice" the rotation.
The result: Helmlab maintains its STRESS 23.2 accuracy while aligning hue angles with intuitive positions. The worst hue error drops from 48.4 degrees to 20.2 degrees -- entirely for free.
npm install helmlabSource code: GitHub | Package: npm
This is post 10 of 16 in the Helmlab blog series. Next up: Your color palette is wrong -- the perceptual uniformity problem in design systems.