@ -0,0 +1,73 @@ | |||||
/* | |||||
* Copyright (C) 2021 Christopher J. Howard | |||||
* | |||||
* This file is part of Antkeeper source code. | |||||
* | |||||
* Antkeeper source code is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU General Public License as published by | |||||
* the Free Software Foundation, either version 3 of the License, or | |||||
* (at your option) any later version. | |||||
* | |||||
* Antkeeper source code is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU General Public License | |||||
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>. | |||||
*/ | |||||
#ifndef ANTKEEPER_MATH_QUADRATURE_HPP | |||||
#define ANTKEEPER_MATH_QUADRATURE_HPP | |||||
#include <iterator> | |||||
#include <type_traits> | |||||
namespace math { | |||||
/// Numerical integration functions. | |||||
namespace quadrature { | |||||
/** | |||||
* Approximates the definite integral of a function using the trapezoidal rule. | |||||
* | |||||
* @param f Unary function object to integrate. | |||||
* @param first,last Range of sample points on `[first, last)`. | |||||
* @return Approximated integral of @p f. | |||||
* | |||||
* @see https://en.wikipedia.org/wiki/Trapezoidal_rule | |||||
*/ | |||||
template<class UnaryOp, class InputIt> | |||||
typename std::invoke_result<UnaryOp, typename std::iterator_traits<InputIt>::value_type>::type trapezoid(UnaryOp f, InputIt first, InputIt last) | |||||
{ | |||||
typedef typename std::invoke_result<UnaryOp, typename std::iterator_traits<InputIt>::value_type>::type result_type; | |||||
if (first == last) | |||||
return result_type(0); | |||||
result_type f_a = f(*first); | |||||
InputIt second = first; | |||||
++second; | |||||
if (second == last) | |||||
return f_a; | |||||
result_type f_b = f(*second); | |||||
result_type sum = (f_a + f_b) / result_type(2) * (*second - *first); | |||||
for (first = second++; second != last; first = second++) | |||||
{ | |||||
f_a = f_b; | |||||
f_b = f(*second); | |||||
sum += (f_a + f_b) / result_type(2) * (*second - *first); | |||||
} | |||||
return sum; | |||||
} | |||||
} // namespace quadrature | |||||
} // namespace math | |||||
#endif // ANTKEEPER_MATH_QUADRATURE_HPP |
@ -0,0 +1,72 @@ | |||||
/* | |||||
* Copyright (C) 2021 Christopher J. Howard | |||||
* | |||||
* This file is part of Antkeeper source code. | |||||
* | |||||
* Antkeeper source code is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU General Public License as published by | |||||
* the Free Software Foundation, either version 3 of the License, or | |||||
* (at your option) any later version. | |||||
* | |||||
* Antkeeper source code is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU General Public License | |||||
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>. | |||||
*/ | |||||
#ifndef ANTKEEPER_PHYSICS_CONSTANTS_HPP | |||||
#define ANTKEEPER_PHYSICS_CONSTANTS_HPP | |||||
namespace physics { | |||||
/// Physical constants | |||||
namespace constants { | |||||
/** | |||||
* Boltzmann constant (k), in joule per kelvin. | |||||
* | |||||
* @see https://physics.nist.gov/cgi-bin/cuu/Value?k|search_for=universal_in! | |||||
*/ | |||||
template <class T> | |||||
constexpr T boltzmann = T(1.380649e-23); | |||||
/** | |||||
* Gravitational constant (G), in cubic meter per second squared per kilogram. | |||||
* | |||||
* @see https://physics.nist.gov/cgi-bin/cuu/Value?G|search_for=universal_in! | |||||
*/ | |||||
template <class T> | |||||
constexpr T gravitational = T(6.67430e-11); | |||||
/** | |||||
* Planck constant (h), in joule per hertz. | |||||
* | |||||
* @see https://physics.nist.gov/cgi-bin/cuu/Value?h|search_for=universal_in! | |||||
*/ | |||||
template <class T> | |||||
constexpr T planck = T(6.62607015e-34); | |||||
/** | |||||
* Stefan-Boltzmann constant (sigma), in watt per square meter kelvin to the fourth. | |||||
* | |||||
* @see https://en.wikipedia.org/wiki/Stefan%E2%80%93Boltzmann_constant | |||||
*/ | |||||
template <class T> | |||||
constexpr T stefan_boltzmann = T(5.67037441918442945397099673188923087584012297029130e-8); | |||||
/** | |||||
* Speed of light in vacuum (c), in meters per second. | |||||
* | |||||
* @see https://physics.nist.gov/cgi-bin/cuu/Value?c|search_for=universal_in! | |||||
*/ | |||||
template <class T> | |||||
constexpr T speed_of_light = T(299792458); | |||||
} // namespace constant | |||||
} // namespace physics | |||||
#endif // ANTKEEPER_PHYSICS_CONSTANTS_HPP |
@ -0,0 +1,90 @@ | |||||
/* | |||||
* Copyright (C) 2021 Christopher J. Howard | |||||
* | |||||
* This file is part of Antkeeper source code. | |||||
* | |||||
* Antkeeper source code is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU General Public License as published by | |||||
* the Free Software Foundation, either version 3 of the License, or | |||||
* (at your option) any later version. | |||||
* | |||||
* Antkeeper source code is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU General Public License | |||||
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>. | |||||
*/ | |||||
#ifndef ANTKEEPER_PHYSICS_LIGHT_BLACKBODY_HPP | |||||
#define ANTKEEPER_PHYSICS_LIGHT_BLACKBODY_HPP | |||||
#include "math/constants.hpp" | |||||
#include "physics/constants.hpp" | |||||
#include "physics/planck.hpp" | |||||
namespace physics { | |||||
namespace light { | |||||
/** | |||||
* Blackbody radiation functions. | |||||
*/ | |||||
namespace blackbody { | |||||
/** | |||||
* Calculates the radiant exitance of a blackbody. | |||||
* | |||||
* @param t Temperature of the blackbody, in kelvin. | |||||
* @return Radiant exitance of the blackbody, in watt per square meter. | |||||
* | |||||
* @see https://en.wikipedia.org/wiki/Stefan%E2%80%93Boltzmann_law | |||||
* @see https://en.wikipedia.org/wiki/Radiant_exitance | |||||
*/ | |||||
template <class T> | |||||
T radiant_exitance(T t); | |||||
/** | |||||
* Calculates the radiant flux of a blackbody. | |||||
* | |||||
* @param t Temperature of the blackbody, in kelvin. | |||||
* @param a Surface area of the blackbody, in square meters. | |||||
* @return Radiant power of the blackbody, in watts. | |||||
* | |||||
* @see https://en.wikipedia.org/wiki/Stefan%E2%80%93Boltzmann_law | |||||
*/ | |||||
template <class T> | |||||
T radiant_flux(T t, T a); | |||||
/** | |||||
* Calculates the spectral radiance of a blackbody at a given wavelength. | |||||
* | |||||
* @param t Temperature of the blackbody, in kelvin. | |||||
* @param lambda Wavelength of light, in meters. | |||||
* @param c Speed of light in medium. | |||||
* @return Spectral radiance, in watt per steradian per square meter per meter. | |||||
* | |||||
* @see physics::planck::wavelength | |||||
*/ | |||||
template <class T> | |||||
constexpr auto spectral_radiance = planck::wavelength<T>; | |||||
template <class T> | |||||
T radiant_exitance(T t) | |||||
{ | |||||
const T tt = t * t; | |||||
return constants::stefan_boltzmann<T> * (tt * tt); | |||||
} | |||||
template <class T> | |||||
T radiant_flux(T t, T a) | |||||
{ | |||||
return a * radiant_exitance(t); | |||||
} | |||||
} // namespace blackbody | |||||
} // namespace light | |||||
} // namespace physics | |||||
#endif // ANTKEEPER_PHYSICS_LIGHT_BLACKBODY_HPP |
@ -0,0 +1,35 @@ | |||||
/* | |||||
* Copyright (C) 2021 Christopher J. Howard | |||||
* | |||||
* This file is part of Antkeeper source code. | |||||
* | |||||
* Antkeeper source code is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU General Public License as published by | |||||
* the Free Software Foundation, either version 3 of the License, or | |||||
* (at your option) any later version. | |||||
* | |||||
* Antkeeper source code is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU General Public License | |||||
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>. | |||||
*/ | |||||
#ifndef ANTKEEPER_PHYSICS_LIGHT_HPP | |||||
#define ANTKEEPER_PHYSICS_LIGHT_HPP | |||||
namespace physics { | |||||
/// Light-related functions. | |||||
namespace light {} | |||||
} // namespace physics | |||||
#include "blackbody.hpp" | |||||
#include "luminosity.hpp" | |||||
#include "phase.hpp" | |||||
#include "photometry.hpp" | |||||
#endif // ANTKEEPER_PHYSICS_LIGHT_HPP |
@ -0,0 +1,56 @@ | |||||
/* | |||||
* Copyright (C) 2021 Christopher J. Howard | |||||
* | |||||
* This file is part of Antkeeper source code. | |||||
* | |||||
* Antkeeper source code is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU General Public License as published by | |||||
* the Free Software Foundation, either version 3 of the License, or | |||||
* (at your option) any later version. | |||||
* | |||||
* Antkeeper source code is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU General Public License | |||||
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>. | |||||
*/ | |||||
#ifndef ANTKEEPER_PHYSICS_LIGHT_LUMINOSITY_HPP | |||||
#define ANTKEEPER_PHYSICS_LIGHT_LUMINOSITY_HPP | |||||
#include <cmath> | |||||
namespace physics { | |||||
namespace light { | |||||
/// Luminous efficiency functions. | |||||
namespace luminosity { | |||||
/** | |||||
* Fitted Gaussian approximation to the CIE 1931 standard observer photopic luminosity function. | |||||
* | |||||
* @param lambda Wavelength of light, in nanometers. | |||||
* @return Luminous efficiency, on `[0, 1]`. | |||||
* | |||||
* @see Wyman, C., Sloan, P.J., & Shirley, P. (2013). Simple Analytic Approximations to the CIE XYZ Color Matching Functions. | |||||
*/ | |||||
template <class T> | |||||
T photopic(T lambda) | |||||
{ | |||||
const T t0 = (lambda - T(568.8)) * ((lambda < T(568.8)) ? T(0.0213) : T(0.0247)); | |||||
const T t1 = (lambda - T(530.9)) * ((lambda < T(530.9)) ? T(0.0613) : T(0.0322)); | |||||
const T y0 = T(0.821) * std::exp(T(-0.5) * t0 * t0); | |||||
const T y1 = T(0.286) * std::exp(T(-0.5) * t1 * t1); | |||||
return y0 + y1; | |||||
} | |||||
} // namespace luminosity | |||||
} // namespace light | |||||
} // namespace physics | |||||
#endif // ANTKEEPER_PHYSICS_LIGHT_LUMINOSITY_HPP |
@ -0,0 +1,78 @@ | |||||
/* | |||||
* Copyright (C) 2021 Christopher J. Howard | |||||
* | |||||
* This file is part of Antkeeper source code. | |||||
* | |||||
* Antkeeper source code is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU General Public License as published by | |||||
* the Free Software Foundation, either version 3 of the License, or | |||||
* (at your option) any later version. | |||||
* | |||||
* Antkeeper source code is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU General Public License | |||||
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>. | |||||
*/ | |||||
#ifndef ANTKEEPER_PHYSICS_LIGHT_PHASE_HPP | |||||
#define ANTKEEPER_PHYSICS_LIGHT_PHASE_HPP | |||||
#include "math/constants.hpp" | |||||
#include <cmath> | |||||
namespace physics { | |||||
namespace light { | |||||
/// Light-scattering phase functions. | |||||
namespace phase { | |||||
/** | |||||
* Henyey–Greenstein phase function. | |||||
* | |||||
* @param mu Cosine of the angle between the light and view directions. | |||||
* @param g Asymmetry factor, on `[-1, 1]`. Positive values cause forward scattering, negative values cause back scattering. | |||||
* | |||||
* @see http://www.pbr-book.org/3ed-2018/Volume_Scattering/Phase_Functions.html | |||||
*/ | |||||
template <class T> | |||||
T henyey_greenstein(T mu, T g); | |||||
/** | |||||
* Isotropic phase function. Causes light to be scattered uniformly in all directions. | |||||
*/ | |||||
template <class T> | |||||
constexpr T isotropic() | |||||
{ | |||||
return T(1) / (T(4) * math::pi<T>); | |||||
} | |||||
/** | |||||
* Rayleigh phase function. | |||||
* | |||||
* @param mu Cosine of the angle between the light and view directions. | |||||
*/ | |||||
template <class T> | |||||
T rayleigh(T mu); | |||||
template <class T> | |||||
T henyey_greenstein(T mu, T g) | |||||
{ | |||||
const T gg = g * g; | |||||
return (T(1) - gg) / (T(4) * math::pi<T> * std::pow(T(1) + gg - T(2) * g * mu, T(1.5))); | |||||
} | |||||
template <class T> | |||||
T rayleigh(T mu) | |||||
{ | |||||
return (T(1) + mu * mu) * (T(3) / (T(16) * math::pi<T>)); | |||||
} | |||||
} // namespace phase | |||||
} // namespace light | |||||
} // namespace physics | |||||
#endif // ANTKEEPER_PHYSICS_LIGHT_PHASE_HPP |
@ -0,0 +1,82 @@ | |||||
/* | |||||
* Copyright (C) 2021 Christopher J. Howard | |||||
* | |||||
* This file is part of Antkeeper source code. | |||||
* | |||||
* Antkeeper source code is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU General Public License as published by | |||||
* the Free Software Foundation, either version 3 of the License, or | |||||
* (at your option) any later version. | |||||
* | |||||
* Antkeeper source code is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU General Public License | |||||
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>. | |||||
*/ | |||||
#ifndef ANTKEEPER_PHYSICS_LIGHT_PHOTOMETRY_HPP | |||||
#define ANTKEEPER_PHYSICS_LIGHT_PHOTOMETRY_HPP | |||||
#include "math/constants.hpp" | |||||
#include "math/quadrature.hpp" | |||||
namespace physics { | |||||
namespace light { | |||||
/** | |||||
* Calculates the luminous efficiency of a light source. | |||||
* | |||||
* @param spd Unary function object that returns spectral radiance given a wavelength. | |||||
* @param lef Unary function object that returns luminous efficiency given a wavelength. | |||||
* @param first,last Range of sample wavelengths. | |||||
* @return Luminous efficiency, on `[0, 1]`. | |||||
* | |||||
* @see physics::light::blackbody::spectral_radiance | |||||
* @see physics::light::luminosity::photopic | |||||
*/ | |||||
template <class T, class UnaryOp1, class UnaryOp2, class InputIt> | |||||
T luminous_efficiency(UnaryOp1 spd, UnaryOp2 lef, InputIt first, InputIt last) | |||||
{ | |||||
auto spd_lef = [spd, lef](T x) -> T | |||||
{ | |||||
return spd(x) * lef(x); | |||||
}; | |||||
const T num = math::quadrature::trapezoid(spd_lef, first, last); | |||||
const T den = math::quadrature::trapezoid(spd, first, last); | |||||
return num / den; | |||||
} | |||||
/** | |||||
* Calculates luminous efficacy given luminous efficiency. | |||||
* | |||||
* @param efficiency Luminous efficiency, on `[0, 1]`. | |||||
* @return Luminous flux, in lumens. | |||||
*/ | |||||
template <class T> | |||||
T luminous_efficacy(T efficiency) | |||||
{ | |||||
return T(683.002) * efficiency; | |||||
} | |||||
/** | |||||
* Converts watts (radiant flux) to lumens (luminous flux). | |||||
* | |||||
* @param radient_flux Radiance flux, in watts. | |||||
* @param efficiency Luminous efficiency, on `[0, 1]`. | |||||
* @return Luminous flux, in lumens. | |||||
*/ | |||||
template <class T> | |||||
T watts_to_lumens(T radient_flux, T efficiency) | |||||
{ | |||||
return radient_flux * luminous_efficacy(efficiency); | |||||
} | |||||
} // namespace light | |||||
} // namespace physics | |||||
#endif // ANTKEEPER_PHYSICS_LIGHT_PHOTOMETRY_HPP |
@ -0,0 +1,61 @@ | |||||
/* | |||||
* Copyright (C) 2021 Christopher J. Howard | |||||
* | |||||
* This file is part of Antkeeper source code. | |||||
* | |||||
* Antkeeper source code is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU General Public License as published by | |||||
* the Free Software Foundation, either version 3 of the License, or | |||||
* (at your option) any later version. | |||||
* | |||||
* Antkeeper source code is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU General Public License | |||||
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>. | |||||
*/ | |||||
#ifndef ANTKEEPER_PHYSICS_PLANCK_HPP | |||||
#define ANTKEEPER_PHYSICS_PLANCK_HPP | |||||
#include "physics/constants.hpp" | |||||
#include <cmath> | |||||
namespace physics { | |||||
/// Various forms of Planck's law. | |||||
namespace planck { | |||||
/** | |||||
* Wavelength variant of Planck's law. | |||||
* | |||||
* @param t Temperature of the blackbody, in kelvin. | |||||
* @param lambda Wavelength of light, in meters. | |||||
* @param c Speed of light in medium. | |||||
* @return Spectral radiance, in watt per steradian per square meter per meter. | |||||
*/ | |||||
template <class T> | |||||
T wavelength(T t, T lambda, T c = constants::speed_of_light<T>); | |||||
template <class T> | |||||
T wavelength(T t, T lambda, T c) | |||||
{ | |||||
const T hc = constants::planck<T> * c; | |||||
const T lambda2 = lambda * lambda; | |||||
// First radiation constant (c1L) | |||||
const T c1 = T(2) * hc * c; | |||||
// Second radiation constant (c2) | |||||
const T c2 = hc / constants::boltzmann<T>; | |||||
return (c1 / (lambda2 * lambda2 * lambda)) / std::expm1(c2 / (lambda * t)); | |||||
} | |||||
} // namespace planck | |||||
} // namespace physics | |||||
#endif // ANTKEEPER_PHYSICS_PLANCK_HPP |