Should the default distance method for cylindrical color spaces use polar coordinates? #493
Replies: 3 comments 20 replies
-
I'm not sure I understand the concern. The default ∆E is 76, and it uses Lab, not a cylindrical space, to perform the distance calculation. https://github.com/color-js/color.js/blob/main/src/deltaE/deltaE76.js#L6. > new Color('red').deltaE(new Color('blue'))
184.01904862099684
> new Color('red').to('hsluv').deltaE(new Color('blue').to('hsluv'))
184.0190486209965 |
Beta Was this translation helpful? Give feedback.
-
Yup, I'm just talking about the geometric distance in the color space. To be pedantic, this is a kind of perceptual distance, in the same way that geometric distance in jzazbz or lab is meant to be perceptually meaningful.
Since it's cylindrical, it should be handled the same way; distance should be calculated using cylindrical coordinates.
It looks like there's already a method on ColorSpaces that identifies spaces as being polar or not! eg, > Color.space.srgb.isPolar
false
> Color.space.hsluv.isPolar
true Behind the scenes it's just checking if a given coord has is of type this.coords[id].type === "angle" So, the distance method could just sort coords into angular and cartesian, then do the distance calculation appropriately. The "right" way to do this would be to also allow for spherical color spaces, ie spaces where two out of the three coordinates are angular — while I don't think any color spaces fit this description today, it's not outside the realm of possibility. It'd be extremely right to also allow for arbitrary numbers of coordinates (2, 3, 4, ...n), and I'm sure there's a generalized formula for distance in n-dimensions (where some of them can be angular), but I'm not a mathematician so I think we'll have to punt on that one :) |
Beta Was this translation helpful? Give feedback.
-
@LeaVerou @svgeesus what do y'all think? Should the |
Beta Was this translation helpful? Give feedback.
-
When when working in cylindrical color spaces like hsl, hsluv, lch, etc (essentially anything with a "hue" component that goes from 0 → 360) the default "euclidian" distance$\sqrt{(x_1 - x_2)^2 + (y_1 - y_2)^2 + (z_1 - z_2)^2}$ doesn't make much sense. For example, the euclidian distance between hsl(0, 50%, 50%) and hsl(360, 50%, 50%) is calculated as $\sqrt{(0 - 360)^2 + (0.5 - 0.5)^2 + (0.5 - 0.5)^2} = 360$ , even though hsl(0, 50%, 50%) and hsl(360, 50%, 50%) are the same color!
Instead, I think we should first convert the polar coordinates to cartesian ones before calculating the euclidean distance:
where r and z are the normal/orthogonal coordinates — in hsl, for example, they would be s and l — and θ is the radial coordinate, in radians — in hsl, this would be$h*\frac{\pi}{180}$ .
This would mean that the euclidian distance between hsl(0, 50%, 50%) and hsl(360, 50%, 50%) would be correctly calculated as 0.
I think the key concern here is that for each cylindrical space, we'd need to indicate which coordinate is the radial one and which are the normal ones. But with that information, euclidian distances would be much more logical.
Beta Was this translation helpful? Give feedback.
All reactions