@ -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 |