Antkeeper  0.0.1
xyz.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2023 Christopher J. Howard
3  *
4  * This file is part of Antkeeper source code.
5  *
6  * Antkeeper source code is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Antkeeper source code is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef ANTKEEPER_COLOR_XYZ_HPP
21 #define ANTKEEPER_COLOR_XYZ_HPP
22 
23 #include <engine/math/vector.hpp>
24 
25 namespace color {
26 
29 
36 template <class T>
37 [[nodiscard]] inline constexpr T xyz_to_luminance(const math::vec3<T>& x) noexcept
38 {
39  return x[1];
40 }
41 
48 template <class T>
49 [[nodiscard]] constexpr math::vec3<T> xyz_to_xyy(const math::vec3<T>& x) noexcept
50 {
51  const T sum = x[0] + x[1] + x[2];
52  return math::vec3<T>{x[0] / sum, x[1] / sum, x[1]};
53 }
54 
63 template <class T>
64 [[nodiscard]] T xyz_match_x(T lambda)
65 {
66  const T t0 = (lambda - T{442.0}) * ((lambda < T{442.0}) ? T{0.0624} : T{0.0374});
67  const T t1 = (lambda - T{599.8}) * ((lambda < T{599.8}) ? T{0.0264} : T{0.0323});
68  const T t2 = (lambda - T{501.1}) * ((lambda < T{501.1}) ? T{0.0490} : T{0.0382});
69 
70  const T x0 = T{ 0.362} * std::exp(T{-0.5} * t0 * t0);
71  const T x1 = T{ 1.056} * std::exp(T{-0.5} * t1 * t1);
72  const T x2 = T{-0.065} * std::exp(T{-0.5} * t2 * t2);
73 
74  return x0 + x1 + x2;
75 }
76 
85 template <class T>
86 [[nodiscard]] T xyz_match_y(T lambda)
87 {
88  const T t0 = (lambda - T{568.8}) * ((lambda < T{568.8}) ? T{0.0213} : T{0.0247});
89  const T t1 = (lambda - T{530.9}) * ((lambda < T{530.9}) ? T{0.0613} : T{0.0322});
90 
91  const T y0 = T{0.821} * std::exp(T{-0.5} * t0 * t0);
92  const T y1 = T{0.286} * std::exp(T{-0.5} * t1 * t1);
93 
94  return y0 + y1;
95 }
96 
105 template <class T>
106 [[nodiscard]] T xyz_match_z(T lambda)
107 {
108  const T t0 = (lambda - T{437.0}) * ((lambda < T{437.0}) ? T{0.0845} : T{0.0278});
109  const T t1 = (lambda - T{459.0}) * ((lambda < T{459.0}) ? T{0.0385} : T{0.0725});
110 
111  const T z0 = T{1.217} * std::exp(T{-0.5} * t0 * t0);
112  const T z1 = T{0.681} * std::exp(T{-0.5} * t1 * t1);
113 
114  return z0 + z1;
115 }
116 
129 template <class T>
130 [[nodiscard]] math::vec3<T> xyz_match(T lambda)
131 {
132  return math::vec3<T>
133  {
134  xyz_match_x<T>(lambda),
135  xyz_match_y<T>(lambda),
136  xyz_match_z<T>(lambda)
137  };
138 }
139 
141 
142 } // namespace color
143 
144 #endif // ANTKEEPER_COLOR_XYZ_HPP
Color science.
Definition: aces.hpp:27
T xyz_match_x(T lambda)
CIE 1931 standard observer color matching function for the X tristimulus value.
Definition: xyz.hpp:64
constexpr math::vec3< T > xyz_to_xyy(const math::vec3< T > &x) noexcept
Transforms a CIE XYZ color into the CIE xyY color space.
Definition: xyz.hpp:49
math::vec3< T > xyz_match(T lambda)
Fitted piecewise gaussian approximation to the CIE 1931 standard observer color matching function.
Definition: xyz.hpp:130
T xyz_match_y(T lambda)
CIE 1931 standard observer color matching function for the Y tristimulus value.
Definition: xyz.hpp:86
constexpr T xyz_to_luminance(const math::vec3< T > &x) noexcept
Returns the luminance of a CIE XYZ color.
Definition: xyz.hpp:37
T xyz_match_z(T lambda)
CIE 1931 standard observer color matching function for the Z tristimulus value.
Definition: xyz.hpp:106
constexpr T sum(const vector< T, N > &x) noexcept
Calculates the sum of all elements in a vector.
Definition: vector.hpp:1585
n-dimensional vector.
Definition: vector.hpp:44