get correct ::distance() and ::delta() implementations for cases involving achromatics
This commit is contained in:
parent
137425faf1
commit
6edd81e4f6
@ -19,6 +19,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <cfloat>
|
||||||
|
|
||||||
#include "canvas/colors.h"
|
#include "canvas/colors.h"
|
||||||
#include "canvas/colorspace.h"
|
#include "canvas/colorspace.h"
|
||||||
@ -365,9 +366,16 @@ HSV
|
|||||||
HSV::delta (const HSV& other) const
|
HSV::delta (const HSV& other) const
|
||||||
{
|
{
|
||||||
HSV d;
|
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.h = h - other.h;
|
||||||
d.s = s - other.s;
|
d.s = s - other.s;
|
||||||
d.v = v - other.v;
|
d.v = v - other.v;
|
||||||
|
}
|
||||||
/* do not clamp - we are returning a delta */
|
/* do not clamp - we are returning a delta */
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
@ -375,6 +383,28 @@ HSV::delta (const HSV& other) const
|
|||||||
double
|
double
|
||||||
HSV::distance (const HSV& other) const
|
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 */
|
/* Use CIE94 definition for now */
|
||||||
|
|
||||||
double sL, sA, sB;
|
double sL, sA, sB;
|
||||||
@ -454,7 +484,7 @@ void
|
|||||||
HSV::print (std::ostream& o) const
|
HSV::print (std::ostream& o) const
|
||||||
{
|
{
|
||||||
if (!is_gray()) {
|
if (!is_gray()) {
|
||||||
o << '(' << s << ',' << v << ',' << a << ')';
|
o << '(' << h << ',' << s << ',' << v << ',' << a << ')';
|
||||||
} else {
|
} else {
|
||||||
o << "gray(" << v << ')';
|
o << "gray(" << v << ')';
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user