203 double operator()(
const ColorType1& c1,
const ColorType2& c2)
const
205 using namespace detail;
209 double L_hat_prime = (x.l() + y.
l()) / 2.0;
210 double C1 = std::hypot(x.a(), x.b());
211 double C2 = std::hypot(y.
a(), y.
b());
212 double C_hat = (C1 + C2) / 2.0;
213 double G = 0.5 * (1 - std::sqrt(std::pow(C_hat, 7) /
214 (std::pow(C_hat, 7) + std::pow(25.0, 7))));
215 double a1_prime = x.a() * (1.0 + G);
216 double a2_prime = y.
a() * (1.0 + G);
217 double C1_prime = std::hypot(a1_prime, x.b());
218 double C2_prime = std::hypot(a2_prime, y.
b());
219 double C_hat_prime = (C1_prime + C2_prime) / 2.0;
221 double h1_prime = atan2d(x.b(), a1_prime);
227 double h2_prime = atan2d(y.
b(), a2_prime);
233 double H_hat_prime = std::abs(h1_prime - h2_prime) > 180
234 ? (h1_prime + h2_prime + 360) / 2.0
235 : (h1_prime + h2_prime) / 2.0;
237 double T = 1.0 - 0.17 * cosd(H_hat_prime - 30) +
238 0.24 * cosd(2 * H_hat_prime) + 0.32 * cosd(3 * H_hat_prime + 6) -
239 0.20 * cosd(4 * H_hat_prime - 63);
241 double delta_h_prime = h2_prime - h1_prime;
242 if (std::abs(delta_h_prime) > 180) {
243 if (h2_prime <= h1_prime)
244 delta_h_prime += 360;
246 delta_h_prime -= 360;
249 double delta_L_prime = y.
l() - x.l();
250 double delta_C_prime = C2_prime - C1_prime;
252 double delta_H_prime =
253 2 * std::sqrt(C1_prime * C2_prime) * sind(delta_h_prime / 2.0);
254 double S_L = 1 + (0.015 * std::pow(L_hat_prime - 50, 2)) /
255 std::sqrt(20 + std::pow(L_hat_prime - 50, 2));
257 double S_C = 1 + 0.045 * C_hat_prime;
258 double S_H = 1 + 0.015 * C_hat_prime * T;
260 double delta_theta = 30 * std::exp(-std::pow((H_hat_prime - 275) / 25, 2));
262 double R_C = 2 * std::sqrt(std::pow(C_hat_prime, 7) /
263 (std::pow(C_hat_prime, 7) + std::pow(25.0, 7)));
265 double R_T = -R_C * sind(2 * delta_theta);
266 double out = std::sqrt(square(delta_L_prime / (K_L * S_L)) +
267 square(delta_C_prime / (K_C * S_C)) +
268 square(delta_H_prime / (K_H * S_H)) +
269 R_T * (delta_C_prime / (K_C * S_C)) *
270 (delta_H_prime / (K_H * S_H)));
272 assert(out >= 0 &&
"CIEDE2000 color difference must be non-negative");
273 assert(std::isfinite(out) &&
274 "CIEDE2000 color difference must not be finite");