#pragma region CPL License /* Nuclex Native Framework Copyright (C) 2002-2015 Nuclex Development Labs This library is free software; you can redistribute it and/or modify it under the terms of the IBM Common Public License as published by the IBM Corporation; either version 1.0 of the License, or (at your option) any later version. This library 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 IBM Common Public License for more details. You should have received a copy of the IBM Common Public License along with this library */ #pragma endregion // CPL License #ifndef NUCLEX_GEOMETRY_MATH_H #define NUCLEX_GEOMETRY_MATH_H #include "Nuclex/Geometry/Config.h" #include #include #include #include namespace Nuclex { namespace Geometry { // ------------------------------------------------------------------------------------------- // /// Provides math routines to the other geometry classes template class Math { /// The PI constant public: static constexpr TScalar Pi = ( 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253 ); /// Two times PI, useful for some operations public: static constexpr TScalar Perigon = ( 6.2831853071795864769252867665590057683943387987502116419498891846156328125724179972560696507 ); /// Calculates the square root of the specified value /// Value of which the square root is calculated /// The square root of the specified number public: static TScalar SquareRoot(TScalar value) { return std::sqrt(value); } /// Returns a random number from 0.0 to the specified maximum /// The random number generator that will be used /// Upper limit for the random number (exclusive) /// A random number from 0.0 to the specified maximum public: template static TScalar Random( TRandomNumberEngine &random, TScalar max ) { std::uniform_real_distribution distribution(0, max); return distribution(random); } /// Returns a random number in the specified range /// The random number generator that will be used /// Minimum possible value of the random number /// Upper limit for the random number (exclusive) /// A random number within the specified range public: template static TScalar Random( TRandomNumberEngine &random, TScalar min, TScalar max ) { std::uniform_real_distribution distribution(min, max); return distribution(random); } /// Calculates the sine of the specified angle /// Angle for which the sine will be calculated /// The sine of the specified angle public: static TScalar Sine(TScalar angleInRadians) { return std::sin(angleInRadians); } /// Calculates the cosine of the specified angle /// Angle for which the cosine will be calculated /// The cosine of the specified angle public: static TScalar Cosine(TScalar angleInRadians) { return std::cos(angleInRadians); } /// Calculates the angle of the specified sine value /// Sine value of which the angle will be calculated /// The angle of the specified sine value in radians public: static TScalar ArcSine(TScalar sineValue) { return std::asin(sineValue); } /// Calculates the angle of the specified cosine value /// Cosine value for which the angle will be calculated /// The angle of the specified cosine value in radians public: static TScalar ArcCosine(TScalar cosineValue) { return std::acos(cosineValue); } /// Calculates the angle of the tangent specified by a direction /// X coordinate of the direction /// Y coordinate of the direction /// The angle of the tangent specified through the direction public: static TScalar ArcTangent(TScalar x, TScalar y) { return std::atan2(y, x); } /// Returns the absolute value of the specified value /// Value of which the absolute value will be returned /// The absolute value of the provided value public: static TScalar Abs(TScalar value) { return std::fabs(value); } /// Calculates to the power of /// Value that will be multiplied /// To which power the value will be multiplied /// to the power of public: static TScalar Power(TScalar value, TScalar power) { return std::pow(value, power); } /// Returns the smaller of two values /// First of the two values /// Second of the two values /// The smaller of the two provided values public: static TScalar Min(TScalar first, TScalar second) { return std::min(first, second); } /// Returns the smallest of three values /// First of the three values /// Second of the three values /// Third of the three values /// The smallest of the three provided values public: static TScalar Min(TScalar first, TScalar second, TScalar third) { return std::min(std::min(first, second), third); } /// Returns the larger of two values /// First of the two values /// Second of the two values /// The larger of the two provided values public: static TScalar Max(TScalar first, TScalar second) { return std::max(first, second); } /// Returns the largest of three values /// First of the three values /// Second of the three values /// Third of the three values /// The largest of the three provided values public: static TScalar Max(TScalar first, TScalar second, TScalar third) { return std::max(std::max(first, second), third); } /// Determines the extremes of two values /// First of the values whose extremes will be found /// Second of the values whose extremes will be found /// /// A pair containing the smaller and the larger value in that order /// public: static std::pair Extremes( TScalar first, TScalar second ) { if(first < second) { return std::pair(first, second); } else { return std::pair(second, first); } } /// Determines the extremes of three values /// First of the values whose extremes will be found /// Second of the values whose extremes will be found /// Third of the values whose extremes will be found /// /// A pair containing the smallest and the largest value of the three inputs /// public: static std::pair Extremes( TScalar first, TScalar second, TScalar third ) { if(first < second) { if(second < third) { // first < second < third return std::make_pair(first, third); } else if(first < third) { // first < third < second return std::make_pair(first, second); } else { // third < first < second return std::make_pair(third, second); } } else { if(first < third) { // second < first < third return std::make_pair(second, third); } else if(second < third) { // second < third < first return std::make_pair(second, first); } else { // third < second < first return std::make_pair(third, first); } } } /* public: static std::ptrdiff_t RoundToDiffT(TScalar value) { return static_cast(value); } public: static std::size_t RoundToSizeT(TScalar value) { return static_cast(value); } */ /// Unwinds a value in a circular (repeating) value range /// Value that will be unwound /// Lower limit of the circular value range /// Upper limit of the circular value range /// The unwound value public: static TScalar Unwind(TScalar value, TScalar min, TScalar max) { TScalar range = (max - min); TScalar floor = std::floor((value - min) / range); return value - (floor * range); } /// Limits the value to the specified range /// Value that will be limited /// Minimum the value cannot go under /// Maximum the value cannot go above /// The value limited to the specified range public: static TScalar Clamp(TScalar value, TScalar min, TScalar max) { if(value < min) { return min; } if(value > max) { return max; } return value; } /// Linearly interpolates between two values /// Value at the left interpolation point /// Value at the right interpolation point /// Time (0.0 .. 1.0) for which to interpolate the value /// The interpolated value at the specified time public: static TScalar Lerp(TScalar left, TScalar right, TScalar t) { return (right - left) * t + left; } /// Calculates the time of a linearly interpolated value /// Value at the left interpolation point /// Value at the right interpolation point /// Value that resulted from the interpolation /// Time at which the value is placed in the interpolation range public: static TScalar Unlerp(TScalar left, TScalar right, TScalar value) { return (value - left) / (right - left); } /// Checks whether the specified value is invalid (not a number) /// Value that will be checked /// True if the specified value is not a number public: static bool IsNan(TScalar value) { return std::isnan(value); } }; // ------------------------------------------------------------------------------------------- // }} // namespace Nuclex::Geometry #include "Math.Float.inl" #include "Math.Double.inl" #include "Math.LongDouble.inl" #endif // NUCLEX_GEOMETRY_MATH_H