Saxum/extern/acgl/include/ACGL/Math/Functions.hh
2014-10-20 17:31:26 +02:00

169 lines
6.6 KiB
C++

/***********************************************************************
* Copyright 2011-2012 Computer Graphics Group RWTH Aachen University. *
* All rights reserved. *
* Distributed under the terms of the MIT License (see LICENSE.TXT). *
**********************************************************************/
#ifndef ACGL_MATH_FUNCTIONS_HH
#define ACGL_MATH_FUNCTIONS_HH
/*
* Some basic math functions.
*
* DON'T INCLUDE THIS DIRECTLY! Include <ACGL/Math.hh> instead!
*/
#include <ACGL/ACGL.hh>
#include <ACGL/Math/Constants.hh>
#include <cmath>
#include <limits>
#include <algorithm>
namespace ACGL{
namespace Math{
namespace Functions{
//functions to change from degree to radians and back
inline float calcDegToRad(float d) {return (d * Constants::DEG_TO_RAD_FLOAT);}
inline double calcDegToRad(double d) {return (d * Constants::DEG_TO_RAD_DOUBLE);}
inline float calcRadToDeg(float r) {return (r * Constants::RAD_TO_DEG_FLOAT);}
inline double calcRadToDeg(double r) {return (r * Constants::RAD_TO_DEG_DOUBLE);}
//sine, cosine and tangens
inline float sinRad(float r) {return (::sinf(r));}
inline float cosRad(float r) {return (::cosf(r));}
inline float tanRad(float r) {return (::tanf(r));}
inline float sinDeg(float d) {return (::sinf(d * Constants::DEG_TO_RAD_FLOAT));}
inline float cosDeg(float d) {return (::cosf(d * Constants::DEG_TO_RAD_FLOAT));}
inline float tanDeg(float d) {return (::tanf(d * Constants::DEG_TO_RAD_FLOAT));}
inline double sinRad(double r) {return (::sin(r));}
inline double cosRad(double r) {return (::cos(r));}
inline double tanRad(double r) {return (::tan(r));}
inline double sinDeg(double d) {return (::sin(d * Constants::DEG_TO_RAD_DOUBLE));}
inline double cosDeg(double d) {return (::cos(d * Constants::DEG_TO_RAD_DOUBLE));}
inline double tanDeg(double d) {return (::tan(d * Constants::DEG_TO_RAD_DOUBLE));}
//and back! (asin, acos and atan)
inline float asinRad (float v) {return (::asinf (v));}
inline float acosRad (float v) {return (::acosf (v));}
inline float atanRad (float v) {return (::atanf (v));}
inline float atan2Rad(float a, float b) {return (::atan2f(a, b));}
inline float asinDeg (float v) {return (::asinf (v) * Constants::RAD_TO_DEG_FLOAT);}
inline float acosDeg (float v) {return (::acosf (v) * Constants::RAD_TO_DEG_FLOAT);}
inline float atanDeg (float v) {return (::atanf (v) * Constants::RAD_TO_DEG_FLOAT);}
inline float atan2Deg(float a, float b) {return (::atan2f(a, b) * Constants::RAD_TO_DEG_FLOAT);}
inline double asinRad(double v) {return (::asin (v));}
inline double acosRad(double v) {return (::acos (v));}
inline double atanRad(double v) {return (::atan (v));}
inline double atan2Rad(double a, double b) {return (::atan2(a, b));}
inline double asinDeg(double v) {return (::asin (v) * Constants::RAD_TO_DEG_DOUBLE);}
inline double acosDeg(double v) {return (::acos (v) * Constants::RAD_TO_DEG_DOUBLE);}
inline double atanDeg(double v) {return (::atan (v) * Constants::RAD_TO_DEG_DOUBLE);}
inline double atan2Deg(double a, double b) {return (::atan2(a, b) * Constants::RAD_TO_DEG_DOUBLE);}
//Helpers
inline int32_t round(float a) {return (int32_t) ( (a < 0.5f)? ceil(a-0.5f) : floor(a+0.5f) );}
inline int32_t round(double a) {return (int32_t) ( (a < 0.5 )? ceil(a-0.5 ) : floor(a+0.5 ) );}
inline float pow(float a, float b) { return ::powf(a, b); }
inline double pow(double a, double b) { return ::pow(a, b); }
inline float ceil(float a) {return ::ceilf(a);}
inline double ceil(double a) {return ::ceil(a);}
inline float floor(float a) {return ::floorf(a);}
inline double floor(double a) {return ::floor(a);}
inline float sqrt(float a) {return(::sqrtf(a));}
inline double sqrt(double a) {return(::sqrt (a));}
inline float sig(float a) {return(a < 0.0f ? -1.0f : 1.0f);}
inline double sig(double a) {return(a < 0.0 ? -1.0 : 1.0 );}
inline float abs(float a) {return(a < 0.0f ? -a : a);}
inline double abs(double a) {return(a < 0.0 ? -a : a);}
inline int_t abs(int_t a) {return(a < 0 ? -a : a);}
inline double randD (double _from = 0.0, double _to = 1.0) { return (_to - _from) * (double(rand()) / double(RAND_MAX)) + _from; }
inline int32_t randI32 (int32_t _from = 0, int32_t _to = 1) { return (rand() % (_to - _from + 1)) + _from; }
template<typename T>
inline T max(T a, T b) {return(a > b ? a : b);}
template<typename T>
inline T min(T a, T b) {return(a < b ? a : b);}
inline uint_t ring(int_t a, uint_t mod) {bool b = a < 0; a = abs(a) % mod; return(b ? mod - a : a);}
/**
* @brief Returns a rotation matrix that rotates a givn degree around the X-axis.
* @param degree is the angle in degree, not radians!
* @return The rotation matrix.
*/
glm::mat3 rotationMatrixX(float degree);
/**
* @brief Returns a rotation matrix that rotates a givn degree around the Y-axis.
* @param degree is the angle in degree, not radians!
* @return The rotation matrix.
*/
glm::mat3 rotationMatrixY(float degree);
/**
* @brief Returns a rotation matrix that rotates a givn degree around the Z-axis.
* @param degree is the angle in degree, not radians!
* @return The rotation matrix.
*/
glm::mat3 rotationMatrixZ(float degree);
/**
* @brief Returns the inverse transpose of the given matrix to use as a normal matrix.
* @param The e.g. modelview matrix.
* @return The inverse transposed.
*/
inline glm::mat3 normalMatrix(const glm::mat4& matrix)
{
return glm::inverseTranspose( glm::mat3( matrix ) );
}
/**
* @brief Test if two glm vectors are equal with respect to a given epsilon.
*/
template<typename T>
bool isApproxEqual(const T &_v1, const T &_v2, float _eps = .01)
{
return glm::distance(_v1, _v2) < _eps;
}
/**
* @brief isApproxEqual returns whether two glm 4x4 matrices are equal with respect to a small epsilon.
* @param _v1: first matrix
* @param _v2: second matrix
* @param _eps: small numerical value
* @return true if the sum off the componentwise difference is smaller than _eps.
*/
bool isApproxEqual(const glm::mat4 &_v1, const glm::mat4 &_v2, float _eps = .01);
/**
* @brief isApproxEqual returns whether two glm 3x3 matrices are equal with respect to a small epsilon.
* @param _v1: first matrix
* @param _v2: second matrix
* @param _eps: small numerical value
* @return true if the sum off the componentwise difference is smaller than _eps.
*/
bool isApproxEqual(const glm::mat3 &_v1, const glm::mat3 &_v2, float _eps = .01);
/**
* @brief Checks if a given matrix is orthonormal.
*/
bool isOrthonormalMatrix(const glm::mat3 &_matrix);
} // Functions
} // Math
} // ACGL
#endif // ACGL_MATH_FUNCTIONS_HH