+ HSV d;
+
+ if (is_gray() && other.is_gray()) {
+ d.h = 0.0;
+ d.s = 0.0;
+ d.v = v - other.v;
+ } else {
+ d.h = h - other.h;
+ d.s = s - other.s;
+ d.v = v - other.v;
+ }
+ d.a = a - other.a;
+ /* do not clamp - we are returning a delta */
+ return d;
+}
+
+double
+HSV::distance (const HSV& other) const
+{
+ if (is_gray() && other.is_gray()) {
+ /* human color perception of achromatics generates about 450
+ distinct colors. By contrast, CIE94 could give a maximal
+ perceptual distance of sqrt ((360^2) + 1 + 1) = 360. The 450
+ are not evenly spread (Webers Law), so lets use 360 as an
+ approximation of the number of distinct achromatics.
+
+ So, scale up the achromatic difference to give about
+ a maximal distance between v = 1.0 and v = 0.0 of 360.
+
+ A difference of about 0.0055 will generate a return value of
+ 2, which is roughly the limit of human perceptual
+ discrimination for chromatics.
+ */
+ return fabs (360.0 * (v - other.v));
+ }
+
+ if (is_gray() != other.is_gray()) {
+ /* no comparison possible */
+ return DBL_MAX;
+ }
+
+ /* Use CIE94 definition for now */
+
+ double sL, sA, sB;
+ double oL, oA, oB;
+ double r, g, b, alpha; // Careful, "a" is a field of this
+ Color c;
+
+ c = hsva_to_color (h, s, v, a);
+ color_to_rgba (c, r, g, b, alpha);
+ Rgb2Lab (&sL, &sA, &sB, r, g, b);
+
+ c = hsva_to_color (other.h, other.s, other.v, other.a);
+ color_to_rgba (c, r, g, b, alpha);
+ Rgb2Lab (&oL, &oA, &oB, r, g, b);
+
+ // Weighting factors depending on the application (1 = default)
+
+ const double whtL = 1.0;
+ const double whtC = 1.0;
+ const double whtH = 1.0;
+
+ const double xC1 = sqrt ((sA * sA) + (sB * oB));
+ const double xC2 = sqrt ((oA * oA) + (oB * oB));
+ double xDL = oL - sL;
+ double xDC = xC2 - xC1;
+ const double xDE = sqrt (((sL - oL) * (sL - oL))
+ + ((sA - oA) * (sA - oA))
+ + ((sB - oB) * (sB - oB)));
+
+ double xDH;
+
+ if (sqrt (xDE) > (sqrt (abs (xDL)) + sqrt (abs (xDC)))) {
+ xDH = sqrt ((xDE * xDE) - (xDL * xDL) - (xDC * xDC));