Moved from ps directory; add Poya's existing MathUtil.h, previously in terrain directory, at top of this header. Disabled all the existing MathUtil class; looks broken in several places, but don't think anyone's actually using it. Hope they're not, anyway.

This was SVN commit r305.
This commit is contained in:
notpete 2004-05-29 20:55:08 +00:00
parent 2cbc27174c
commit 4d826bb5f2
2 changed files with 468 additions and 0 deletions

248
source/maths/MathUtil.cpp Executable file
View File

@ -0,0 +1,248 @@
#if 0
// last modified Thursday, May 08, 2003
#include <time.h>
#include <cstdlib>
#include "MathUtil.h"
// MathUtil Errors
DEFINE_ERROR(ERRONEOUS_BOUND_ERROR, "Lower Bound is >= Upper Bound");
//////////////////////////////////////////////////////////////////////
// NAME: CompareFloat
// PURPOSE: Returns true if two floating point numbers are within
// FL_FP_TOLERANCE of each other.
//
_bool MathUtil::CompareFloat(const _double &num1, const _double &num2)
{
if( Abs(num1 - num2) < FL_FP_TOLERANCE )
return true;
else
return false;
}
//////////////////////////////////////////////////////////////////////
// NAME: RadiansToDegrees
// PURPOSE: Converts from Radians to Degrees
//
inline _double MathUtil::RadiansToDegrees(const _double &num)
{
return num*(PI/180);
}
//////////////////////////////////////////////////////////////////////
// NAME: RadiansToDegrees
// PURPOSE: Converts from Degrees to Radians
//
inline _double MathUtil::DegreesToRadians(const _double &num)
{
return (num*180)/PI;
}
/*
//////////////////////////////////////////////////////////////////////
// NAME: Random
// PURPOSE: returns a random floating point number between lowerBound
// and upperBound
// NOTES: returns -1 if lowerBound >= upperBound
//
_float MathUtil::Random(const _float &lowerBound, const _float &upperBound)
{
if( lowerBound >= upperBound)
return -1;
else
{
// seed generator with current time
srand( static_cast<unsigned>( time(NULL) ) );
// finds a floating point number between 0 and 1.0
_float randVar = ( static_cast<_float>( rand() )/RAND_MAX );
// maps the number onto the set from 0 to upperBound
randVar *= Abs(lowerBound - upperBound ) + 1;
//translate to the proper range
randVar += lowerBound;
return randVar;
}
}
//////////////////////////////////////////////////////////////////////
// NAME: Random
// PURPOSE: returns a random number between lowerBound and upperBound
// NOTES: returns -1 if lowerBound >= upperBound
//
_int MathUtil::Random(const _int &lowerBound,const _int &upperBound)
{
if( lowerBound >= upperBound)
return -1;
else
{
// seed generator with current time
srand( static_cast<unsigned>( time(NULL) ) );
// find a random variable between 0 and range size
_int randVar = rand()%( Abs(upperBound - lowerBound) + 1);
// translate to proper range
randVar += lowerBound;
return randVar;
}
}
*/
//////////////////////////////////////////////////////////
// NAME: Round
// PURPOSE: Rounds a number.
// NOTES: Round rounds to the nearest representable number
// float version.
//
_int MathUtil::Round(const float &num)
{
if( num > 0 )
return static_cast<_int>(num + .5);
else if (num < 0 )
return static_cast<_int>(num - .5);
else
return 0;
}
//////////////////////////////////////////////////////////
// NAME: Round
// PURPOSE: Rounds a number.
// NOTES: Round rounds to the nearest representable number
// double version.
//
_int MathUtil::Round(const double &num)
{
if( num > 0 )
return static_cast<_int>(num + .5);
else if (num < 0 )
return static_cast<_int>(num - .5);
else
return 0;
}
//////////////////////////////////////////////////////////////////////
// NAME: SignedModulus
// PURPOSE: returns a mathematically correct modulus for int
//
_int MathUtil::SignedModulus(const _int &num, const _int &n)
{
if( num >= 0 )
return num%n;
else
{
// the % operator reflects the range if num < 0, so
// we have to multiply by -1 to reflect it back. This method
// is faster than calling Abs() and then doing the modulus.
_int Tnum = -1*(num%n);
// if num%n equals 0, then n - Tnum will be n, which, logically
// speaking, is 0 in a different form, but we have to make sure it's
// in the form 0, and not n. Therefore, if Tnum = 0, simply leave
// it like that.
if( Tnum != 0)
Tnum = n - Tnum;
return Tnum;
}
}
//////////////////////////////////////////////////////////////////////
// NAME: SignedModulus
// PURPOSE: returns a mathematically correct modulus for long
//
_long MathUtil::SignedModulus(const _long &num, const _long &n)
{
if( num >= 0 )
return num%n;
else
{
// the % operator reflects the range if num < 0, so
// we have to multiply by -1 to reflect it back. This method
// is faster than calling Abs() and then doing the modulus.
_long Tnum = -1*(num%n);
// if num%n equals 0, then n - Tnum will be n, which, logically
// speaking, is 0 in a different form, but we have to make sure it's
// in the form 0, and not n. Therefore, if Tnum = 0, simply leave
// it like that.
if( Tnum != 0)
Tnum = n - Tnum;
return Tnum;
}
}
//////////////////////////////////////////////////////////////////////
// NAME: SignedModulus
// PURPOSE: returns a mathematically correct modulus for float
// NOTES: uses fmod() in math.h, which returns the modulus of floats
//
_float MathUtil::SignedModulus(const _float &num, const _float &n)
{
if( num >=0 )
return static_cast<_float>( fmod(num,n) );
else
{
// the % operator reflects the range if num < 0, so
// we have to multiply by -1 to reflect it back. This method
// is faster than calling Abs() and then doing the modulus.
_float Tnum = -1*( static_cast<_float>( fmod(num,n) ) );
// if num%n equals 0, then n - Tnum will be n, which, logically
// speaking, is 0 in a different form, but we have to make sure it's
// in the form 0, and not n. Therefore, if Tnum = 0, simply leave
// it like that.
if( Tnum != 0)
Tnum = n - Tnum;
return Tnum;
}
}
//////////////////////////////////////////////////////////////////////
// NAME: SignedModulus
// PURPOSE: returns a mathematically correct modulus for double
// NOTES: uses fmod() in math.h, which returns the modulus of floats
//
_double MathUtil::SignedModulus(const _double &num, const _double &n)
{
if( num >=0 )
return fmod(num,n);
else
{
// the % operator reflects the range if num < 0, so
// we have to multiply by -1 to reflect it back. This method
// is faster than calling Abs() and then doing the modulus.
_double Tnum = -1*( fmod(num,n) );
// if num%n equals 0, then n - Tnum will be n, which, logically
// speaking, is 0 in a different form, but we have to make sure it's
// in the form 0, and not n. Therefore, if Tnum = 0, simply leave
// it like that.
if( Tnum != 0)
Tnum = n - Tnum;
return Tnum;
}
}
#endif

220
source/maths/MathUtil.h Executable file
View File

@ -0,0 +1,220 @@
#ifndef MATH_UTIL_H
#define MATH_UTIL_H
#ifndef PI
#define PI 3.14159265358979323846f
#endif
#define DEGTORAD(a) ((a) * (PI/180.0f))
#define RADTODEG(a) ((a) * (180.0f/PI))
#define SQR(x) ((x) * (x))
#define MAX3(a,b,c) ( MAX (MAX(a,b), c) )
#define ABS(a) ((a > 0) ? (a) : (-a))
#if 0
/*
Math utility functions
by Michael Reiland
recondite_phreak@yahool.com
--Overview--
Contains common math functions like Abs, Sign, Max, Min, etc.
--More info--
TODO: actually write corresponding documentation
http://wildfiregames.com/0ad/codepit/TDD/math_utils.html
*/
//--------------------------------------------------------
// Includes / Compiler directives
//--------------------------------------------------------
#include "Prometheus.h" // Standard Engine Include
#include <math.h> // Needed for fmod()
//--------------------------------------------------------
// Error declarations
//--------------------------------------------------------
// MathUtil Errors
DECLARE_ERROR(ERRONEOUS_BOUND_ERROR);
//--------------------------------------------------------
// Declarations
//--------------------------------------------------------
namespace MathUtil
{
const _double PI = 3.14159265358932384;
const _double FL_FP_TOLERANCE = .000000001;
//--------------------------------------------------------
// Template functions
//--------------------------------------------------------
//--------------------------------------------------------
// Declarations
//--------------------------------------------------------
//////////////////////////////////////////////////////////
// NAME: Abs
// PURPOSE: Calculates the Absolute value
//
template <typename T>
T Abs(const T &num)
{
if( num < 0)
return -1*num;
return num;
}
//////////////////////////////////////////////////////////
// NAME: Clamp
// PURPOSE: Forces num to be between lowerBound and upperBound
//
template <typename T>
T Clamp(T &num, const _int &lowerBound,const _int &upperBound)
{
if(num <= lowerBound)
num = static_cast<T>(lowerBound);
else if( num >= upperBound)
num = static_cast<T>(upperBound);
}
//////////////////////////////////////////////////////////
// NAME: Max
// PURPOSE: Returns the largest number.
//
template <typename T>
T Max(const T &num1, const T &num2)
{
if( num1 > num2)
return num1;
else
return num2;
}
//////////////////////////////////////////////////////////
// NAME: Min
// PURPOSE: Returns the smallest number.
//
template <typename T>
T Min(const T &num1, const T &num2)
{
if( num1 < num2)
return num1;
else
return num2;
}
//////////////////////////////////////////////////////////
// NAME: Sign
// PURPOSE: Returns 1 if the number is > 0, -1 if it's < 0,
// otherwise returns 0.
//
template <typename T>
_int Sign(const T &num)
{
if( num > 0 )
return 1;
else if( num < 0 )
return -1;
else
return 0;
}
//////////////////////////////////////////////////////////
// NAME: Square
// PURPOSE: Returns the square of a number
// NOTES: Num should be less than the square root of the
// maximum representable number for the data type.
//
template <typename T>
inline _double Square(const T &num)
{
return num*num;
}
//////////////////////////////////////////////////////////
// NAME: Swap
// PURPOSE: Swaps two numbers
//
template <typename T>
void Swap(T *num1, T *num2)
{
T temp = num1;
num1 = num2;
num2 = temp;
}
//////////////////////////////////////////////////////////
// NAME: Wrap
// PURPOSE: Wraps num between lowerBound and upperBound.
//
template <typename T>
PS_RESULT Wrap(T *num,const T &lowerBound, const T &upperBound)
{
if(lowerBound >= upperBound)
return ERRONEOUS_BOUND_ERROR;
else
{
// translate to range 0 to n-1, find the modulus, then
// translate back to range lowerBound to upperBound.
num -= lowerBound;
num = SignedModulus( num, Abs(upperBound - lowerBound) );
num += lowerBound;
}
return PS_OK;
}
//--------------------------------------------------------
// Non-template functions
//--------------------------------------------------------
_int Ceiling(const float &num);
_int Ceiling(const double &num);
_bool CompareFloat(const _double &, const _double &);
_int Floor(const float &num);
_int Floor(const double &num);
inline _double RadiansToDegrees(const _double &num);
inline _double DegreesToRadians(const _double &num);
_float Random(const _float &, const _float &);
_int Random(const _int &,const _int &);
_int Round(const float &num);
_int Round(const double &num);
_int SignedModulus(const _int &num, const _int &n);
_long SignedModulus(const _long &num, const _long &n);
_float SignedModulus(const _float &num, const _float &n);
_double SignedModulus(const _double &num, const _double &n);
}
#endif
#endif