/***************************************************************************
 *   Copyright (C) 2007 by A.J. Tavakoli                                   *
 *                                                                         *
 *   This program 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 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program 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 this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#ifndef NUMERIC_H
#define NUMERIC_H

#include <cmath>
#include <cfloat>


namespace Math3D {


// returns the absolute value of s
// (provided since the C math library does not have standard routine
//  for taking the absolute values of all data types)
template<class Real>
inline Real rabs(Real s) {
  return s < 0.0 ? -s : s;
}


// returns -1 if a < b, 0 if a is about equal to b (within eps of a), or 1
// if a > b
template<class Real>
inline int rcmp( Real a, Real b, Real eps = Real(1.0/1024.0) ) {
  Real diff = a - b;

  // roughly equal?
  if ( rabs(diff) < eps )
    return 0;

  if ( a < b )
    return -1;

  return 1;
}


// returns the square root of s
template<class Real>
inline Real rsqrt(Real s) {
  return (Real)sqrt( double(s) );
}


// returns the sine of angle theta (in radians)
template<class Real>
inline Real rsin(Real theta) {
  return (Real)sin( double(theta) );
}


// returns the cosine of angle theta (in radians)
template<class Real>
inline Real rcos(Real theta) {
  return (Real)cos( double(theta) );
}


// returns the tangent of angle theta (in radians)
template<class Real>
inline Real rtan(Real theta) {
  return (Real)tan( double(theta) );
}


// returns the arcsine of s
template<class Real>
inline Real rasin(Real s) {
  return (Real)asin( double(s) );
}


// returns the arccosine of s
template<class Real>
inline Real racos(Real s) {
  return (Real)acos( double(s) );
}


// returns the arctangent of s
template<class Real>
inline Real ratan(Real s) {
  return (Real)atan( double(s) );
}


} // namespace Math3D


#endif
