237 double operator()(
const ColorType1& c1,
const ColorType2& c2)
const
239 using namespace detail;
243 double L_hat_prime = (x.l() + y.
l()) / 2.0;
244 double C1 = std::hypot(x.a(), x.b());
245 double C2 = std::hypot(y.
a(), y.
b());
246 double C_hat = (C1 + C2) / 2.0;
247 double G = 0.5 * (1 - std::sqrt(std::pow(C_hat, 7) /
248 (std::pow(C_hat, 7) + std::pow(25.0, 7))));
249 double a1_prime = x.a() * (1.0 + G);
250 double a2_prime = y.
a() * (1.0 + G);
251 double C1_prime = std::hypot(a1_prime, x.b());
252 double C2_prime = std::hypot(a2_prime, y.
b());
253 double C_hat_prime = (C1_prime + C2_prime) / 2.0;
255 double h1_prime = atan2d(x.b(), a1_prime);
261 double h2_prime = atan2d(y.
b(), a2_prime);
267 double H_hat_prime = std::abs(h1_prime - h2_prime) > 180
268 ? (h1_prime + h2_prime + 360) / 2.0
269 : (h1_prime + h2_prime) / 2.0;
271 double T = 1.0 - 0.17 * cosd(H_hat_prime - 30) +
272 0.24 * cosd(2 * H_hat_prime) + 0.32 * cosd(3 * H_hat_prime + 6) -
273 0.20 * cosd(4 * H_hat_prime - 63);
275 double delta_h_prime = h2_prime - h1_prime;
276 if (std::abs(delta_h_prime) > 180) {
277 if (h2_prime <= h1_prime)
278 delta_h_prime += 360;
280 delta_h_prime -= 360;
283 double delta_L_prime = y.
l() - x.l();
284 double delta_C_prime = C2_prime - C1_prime;
286 double delta_H_prime =
287 2 * std::sqrt(C1_prime * C2_prime) * sind(delta_h_prime / 2.0);
288 double S_L = 1 + (0.015 * std::pow(L_hat_prime - 50, 2)) /
289 std::sqrt(20 + std::pow(L_hat_prime - 50, 2));
291 double S_C = 1 + 0.045 * C_hat_prime;
292 double S_H = 1 + 0.015 * C_hat_prime * T;
294 double delta_theta = 30 * std::exp(-std::pow((H_hat_prime - 275) / 25, 2));
296 double R_C = 2 * std::sqrt(std::pow(C_hat_prime, 7) /
297 (std::pow(C_hat_prime, 7) + std::pow(25.0, 7)));
299 double R_T = -R_C * sind(2 * delta_theta);
300 double out = std::sqrt(square(delta_L_prime / (K_L * S_L)) +
301 square(delta_C_prime / (K_C * S_C)) +
302 square(delta_H_prime / (K_H * S_H)) +
303 R_T * (delta_C_prime / (K_C * S_C)) *
304 (delta_H_prime / (K_H * S_H)));
306 assert(out >= 0 &&
"CIEDE2000 color difference must be non-negative");
307 assert(std::isfinite(out) &&
308 "CIEDE2000 color difference must not be finite");