Functions.hh 6.6 KB
Newer Older
1 2 3 4 5
/***********************************************************************
 * Copyright 2011-2012 Computer Graphics Group RWTH Aachen University. *
 * All rights reserved.                                                *
 * Distributed under the terms of the MIT License (see LICENSE.TXT).   *
 **********************************************************************/
Robert Menzel's avatar
Robert Menzel committed
6 7 8 9

#ifndef ACGL_MATH_FUNCTIONS_HH
#define ACGL_MATH_FUNCTIONS_HH

10 11 12 13 14 15
/*
 * Some basic math functions.
 *
 * DON'T INCLUDE THIS DIRECTLY! Include <ACGL/Math.hh> instead!
 */

Robert Menzel's avatar
Robert Menzel committed
16
#include <ACGL/ACGL.hh>
Robert Menzel's avatar
Robert Menzel committed
17 18 19 20
#include <ACGL/Math/Constants.hh>

#include <cmath>
#include <limits>
Martin Schultz's avatar
Martin Schultz committed
21
#include <algorithm>
Robert Menzel's avatar
Robert Menzel committed
22

Robert Menzel's avatar
Robert Menzel committed
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
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
Robert Menzel's avatar
Robert Menzel committed
68 69
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 ) );}
Robert Menzel's avatar
Robert Menzel committed
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89

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);}

90 91 92
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; }

93 94 95 96 97 98
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);}

Robert Menzel's avatar
Robert Menzel committed
99 100
inline uint_t ring(int_t a, uint_t mod) {bool b = a < 0; a = abs(a) % mod; return(b ? mod - a : a);}

101 102 103 104 105 106
/**
 * @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);
Robert Menzel's avatar
Robert Menzel committed
107

108 109 110 111 112 113
/**
 * @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);
Robert Menzel's avatar
Robert Menzel committed
114

115 116 117 118 119 120
/**
 * @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);
Robert Menzel's avatar
Robert Menzel committed
121

122 123 124 125 126
/**
 * @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.
 */
Robert Menzel's avatar
Robert Menzel committed
127 128 129 130 131
inline glm::mat3 normalMatrix(const glm::mat4& matrix)
{
    return glm::inverseTranspose( glm::mat3( matrix ) );
}

132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
/**
 * @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);

Robert Menzel's avatar
Robert Menzel committed
164 165 166 167
} // Functions
} // Math
} // ACGL

168
#endif // ACGL_MATH_FUNCTIONS_HH