00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef __MATHUNIT_H__
00026 #define __MATHUNIT_H__
00027
00028
00029 #include "Peonstdafx.h"
00030
00031
00032 namespace peon
00033 {
00039 class Radian
00040 {
00041 Real mRad;
00042
00043 public:
00044 explicit Radian ( Real r=0 ) : mRad(r) {}
00045 Radian ( const Degree& d );
00046 const Radian& operator = ( const Real& f ) { mRad = f; return *this; }
00047 const Radian& operator = ( const Radian& r ) { mRad = r.mRad; return *this; }
00048 const Radian& operator = ( const Degree& d );
00049
00050 Real valueDegrees() const;
00051 Real valueRadians() const { return mRad; }
00052 Real valueAngleUnits() const;
00053
00054 Radian operator + ( const Radian& r ) const { return Radian ( mRad + r.mRad ); }
00055 Radian operator + ( const Degree& d ) const;
00056 Radian& operator += ( const Radian& r ) { mRad += r.mRad; return *this; }
00057 Radian& operator += ( const Degree& d );
00058 Radian operator - () { return Radian(-mRad); }
00059 Radian operator - ( const Radian& r ) const { return Radian ( mRad - r.mRad ); }
00060 Radian operator - ( const Degree& d ) const;
00061 Radian& operator -= ( const Radian& r ) { mRad -= r.mRad; return *this; }
00062 Radian& operator -= ( const Degree& d );
00063 Radian operator * ( Real f ) const { return Radian ( mRad * f ); }
00064 Radian operator * ( const Radian& f ) const { return Radian ( mRad * f.mRad ); }
00065 Radian& operator *= ( Real f ) { mRad *= f; return *this; }
00066 Radian operator / ( Real f ) const { return Radian ( mRad / f ); }
00067 Radian& operator /= ( Real f ) { mRad /= f; return *this; }
00068
00069 bool operator < ( const Radian& r ) const { return mRad < r.mRad; }
00070 bool operator <= ( const Radian& r ) const { return mRad <= r.mRad; }
00071 bool operator == ( const Radian& r ) const { return mRad == r.mRad; }
00072 bool operator != ( const Radian& r ) const { return mRad != r.mRad; }
00073 bool operator >= ( const Radian& r ) const { return mRad >= r.mRad; }
00074 bool operator > ( const Radian& r ) const { return mRad > r.mRad; }
00075 };
00076
00082 class Degree
00083 {
00084 Real mDeg;
00085
00086 public:
00087 explicit Degree ( Real d=0 ) : mDeg(d) {}
00088 Degree ( const Radian& r ) : mDeg(r.valueDegrees()) {}
00089 const Degree& operator = ( const Real& f ) { mDeg = f; return *this; }
00090 const Degree& operator = ( const Degree& d ) { mDeg = d.mDeg; return *this; }
00091 const Degree& operator = ( const Radian& r ) { mDeg = r.valueDegrees(); return *this; }
00092
00093 Real valueDegrees() const { return mDeg; }
00094 Real valueRadians() const;
00095 Real valueAngleUnits() const;
00096
00097 Degree operator + ( const Degree& d ) const { return Degree ( mDeg + d.mDeg ); }
00098 Degree operator + ( const Radian& r ) const { return Degree ( mDeg + r.valueDegrees() ); }
00099 Degree& operator += ( const Degree& d ) { mDeg += d.mDeg; return *this; }
00100 Degree& operator += ( const Radian& r ) { mDeg += r.valueDegrees(); return *this; }
00101 Degree operator - () { return Degree(-mDeg); }
00102 Degree operator - ( const Degree& d ) const { return Degree ( mDeg - d.mDeg ); }
00103 Degree operator - ( const Radian& r ) const { return Degree ( mDeg - r.valueDegrees() ); }
00104 Degree& operator -= ( const Degree& d ) { mDeg -= d.mDeg; return *this; }
00105 Degree& operator -= ( const Radian& r ) { mDeg -= r.valueDegrees(); return *this; }
00106 Degree operator * ( Real f ) const { return Degree ( mDeg * f ); }
00107 Degree operator * ( const Degree& f ) const { return Degree ( mDeg * f.mDeg ); }
00108 Degree& operator *= ( Real f ) { mDeg *= f; return *this; }
00109 Degree operator / ( Real f ) const { return Degree ( mDeg / f ); }
00110 Degree& operator /= ( Real f ) { mDeg /= f; return *this; }
00111
00112 bool operator < ( const Degree& d ) const { return mDeg < d.mDeg; }
00113 bool operator <= ( const Degree& d ) const { return mDeg <= d.mDeg; }
00114 bool operator == ( const Degree& d ) const { return mDeg == d.mDeg; }
00115 bool operator != ( const Degree& d ) const { return mDeg != d.mDeg; }
00116 bool operator >= ( const Degree& d ) const { return mDeg >= d.mDeg; }
00117 bool operator > ( const Degree& d ) const { return mDeg > d.mDeg; }
00118 };
00119
00126 class Angle
00127 {
00128 Real mAngle;
00129 public:
00130 explicit Angle ( Real angle ) : mAngle(angle) {}
00131 operator Radian();
00132 operator Degree();
00133 };
00134
00135
00136
00137 inline Radian::Radian ( const Degree& d ) : mRad(d.valueRadians()) {
00138 }
00139 inline const Radian& Radian::operator = ( const Degree& d ) {
00140 mRad = d.valueRadians(); return *this;
00141 }
00142 inline Radian Radian::operator + ( const Degree& d ) const {
00143 return Radian ( mRad + d.valueRadians() );
00144 }
00145 inline Radian& Radian::operator += ( const Degree& d ) {
00146 mRad += d.valueRadians();
00147 return *this;
00148 }
00149 inline Radian Radian::operator - ( const Degree& d ) const {
00150 return Radian ( mRad - d.valueRadians() );
00151 }
00152 inline Radian& Radian::operator -= ( const Degree& d ) {
00153 mRad -= d.valueRadians();
00154 return *this;
00155 }
00156
00167 class _PeonExport MathUnit
00168 {
00169 public:
00175 enum AngleUnit
00176 {
00177 AU_DEGREE,
00178 AU_RADIAN
00179 };
00180
00181 protected:
00182
00183 static AngleUnit msAngleUnit;
00184
00186 static int mTrigTableSize;
00187
00189 static Real mTrigTableFactor;
00190 static Real* mSinTable;
00191 static Real* mTanTable;
00192
00195 void buildTrigTables();
00196
00197 static Real SinTable (Real fValue);
00198 static Real TanTable (Real fValue);
00199 public:
00205 MathUnit(unsigned int trigTableSize = 4096);
00206
00209 ~MathUnit();
00210
00211 static inline int IAbs (int iValue) { return ( iValue >= 0 ? iValue : -iValue ); }
00212 static inline int ICeil (float fValue) { return int(ceil(fValue)); }
00213 static inline int IFloor (float fValue) { return int(floor(fValue)); }
00214 static int ISign (int iValue);
00215
00216 static inline Real Abs (Real fValue) { return Real(fabs(fValue)); }
00217 static inline Degree Abs (const Degree& dValue) { return Degree(fabs(dValue.valueDegrees())); }
00218 static inline Radian Abs (const Radian& rValue) { return Radian(fabs(rValue.valueRadians())); }
00219 static Radian ACos (Real fValue);
00220 static Radian ASin (Real fValue);
00221 static inline Radian ATan (Real fValue) { return Radian(atan(fValue)); }
00222 static inline Radian ATan2 (Real fY, Real fX) { return Radian(atan2(fY,fX)); }
00223 static inline Real Ceil (Real fValue) { return Real(ceil(fValue)); }
00224
00232 static inline Real Cos (const Radian& fValue, bool useTables = false) {
00233 return (!useTables) ? Real(cos(fValue.valueRadians())) : SinTable(fValue.valueRadians() + HALF_PI);
00234 }
00242 static inline Real Cos (Real fValue, bool useTables = false) {
00243 return (!useTables) ? Real(cos(fValue)) : SinTable(fValue + HALF_PI);
00244 }
00245
00246 static inline Real Exp (Real fValue) { return Real(exp(fValue)); }
00247
00248 static inline Real Floor (Real fValue) { return Real(floor(fValue)); }
00249
00250 static inline Real Log (Real fValue) { return Real(log(fValue)); }
00251
00252 static inline Real Pow (Real fBase, Real fExponent) { return Real(pow(fBase,fExponent)); }
00253
00254 static Real Sign (Real fValue);
00255 static inline Radian Sign ( const Radian& rValue )
00256 {
00257 return Radian(Sign(rValue.valueRadians()));
00258 }
00259 static inline Degree Sign ( const Degree& dValue )
00260 {
00261 return Degree(Sign(dValue.valueDegrees()));
00262 }
00263
00271 static inline Real Sin (const Radian& fValue, bool useTables = false) {
00272 return (!useTables) ? Real(sin(fValue.valueRadians())) : SinTable(fValue.valueRadians());
00273 }
00281 static inline Real Sin (Real fValue, bool useTables = false) {
00282 return (!useTables) ? Real(sin(fValue)) : SinTable(fValue);
00283 }
00284
00285 static inline Real Sqr (Real fValue) { return fValue*fValue; }
00286
00287 static inline Real Sqrt (Real fValue) { return Real(sqrt(fValue)); }
00288
00289 static inline Radian Sqrt (const Radian& fValue) { return Radian(sqrt(fValue.valueRadians())); }
00290
00291 static inline Degree Sqrt (const Degree& fValue) { return Degree(sqrt(fValue.valueDegrees())); }
00292
00296 static Real InvSqrt(Real fValue);
00297
00298 static Real UnitRandom ();
00299
00300 static Real RangeRandom (Real fLow, Real fHigh);
00301
00302 static Real SymmetricRandom ();
00303
00311 static inline Real Tan (const Radian& fValue, bool useTables = false) {
00312 return (!useTables) ? Real(tan(fValue.valueRadians())) : TanTable(fValue.valueRadians());
00313 }
00321 static inline Real Tan (Real fValue, bool useTables = false) {
00322 return (!useTables) ? Real(tan(fValue)) : TanTable(fValue);
00323 }
00324
00325 static inline Real DegreesToRadians(Real degrees) { return degrees * fDeg2Rad; }
00326 static inline Real RadiansToDegrees(Real radians) { return radians * fRad2Deg; }
00327
00334 static void setAngleUnit(AngleUnit unit);
00336 static AngleUnit getAngleUnit(void);
00337
00339 static Real AngleUnitsToRadians(Real units);
00341 static Real RadiansToAngleUnits(Real radians);
00343 static Real AngleUnitsToDegrees(Real units);
00345 static Real DegreesToAngleUnits(Real degrees);
00346
00376 static bool pointInTri2D( Real px, Real pz, Real ax, Real az, Real bx, Real bz, Real cx, Real cz );
00377
00379 static std::pair<bool, Real> intersects(const Ray& ray, const Plane& plane);
00380
00382 static std::pair<bool, Real> intersects(const Ray& ray, const Sphere& sphere,
00383 bool discardInside = true);
00384
00386 static std::pair<bool, Real> intersects(const Ray& ray, const AxisAlignedBox& sphere);
00387
00389 static bool intersects(const Sphere& sphere, const AxisAlignedBox& box);
00390
00392 static bool intersects(const Plane& plane, const AxisAlignedBox& box);
00393
00399 static std::pair<bool, Real> intersects(
00400 const Ray& ray, const std::vector<Plane>& planeList,
00401 bool normalIsOutside);
00407 static std::pair<bool, Real> intersects(
00408 const Ray& ray, const std::list<Plane>& planeList,
00409 bool normalIsOutside);
00410
00414 static bool intersects(const Sphere& sphere, const Plane& plane);
00415
00418 static bool RealEqual(Real a, Real b,
00419 Real tolerance = std::numeric_limits<Real>::epsilon());
00420
00422 static Vector3 calculateTangentSpaceVector(
00423 const Vector3& position1, const Vector3& position2, const Vector3& position3,
00424 Real u1, Real v1, Real u2, Real v2, Real u3, Real v3);
00425
00427 static Matrix44 buildReflectionMatrix(const Plane& p);
00429 static Vector4 calculateFaceNormal(const Vector3& v1, const Vector3& v2, const Vector3& v3);
00431 static Vector3 calculateBasicFaceNormal(const Vector3& v1, const Vector3& v2, const Vector3& v3);
00433 static Vector4 calculateFaceNormalWithoutNormalize(const Vector3& v1, const Vector3& v2, const Vector3& v3);
00435 static Vector3 calculateBasicFaceNormalWithoutNormalize(const Vector3& v1, const Vector3& v2, const Vector3& v3);
00436
00437 static const Real POS_INFINITY;
00438 static const Real NEG_INFINITY;
00439 static const Real PI;
00440 static const Real TWO_PI;
00441 static const Real HALF_PI;
00442 static const Real fDeg2Rad;
00443 static const Real fRad2Deg;
00444
00445 };
00446
00447
00448
00449
00450 inline Real Radian::valueDegrees() const
00451 {
00452 return MathUnit::RadiansToDegrees ( mRad );
00453 }
00454
00455 inline Real Radian::valueAngleUnits() const
00456 {
00457 return MathUnit::RadiansToAngleUnits ( mRad );
00458 }
00459
00460 inline Real Degree::valueRadians() const
00461 {
00462 return MathUnit::DegreesToRadians ( mDeg );
00463 }
00464
00465 inline Real Degree::valueAngleUnits() const
00466 {
00467 return MathUnit::DegreesToAngleUnits ( mDeg );
00468 }
00469
00470 inline Angle::operator Radian()
00471 {
00472 return Radian(MathUnit::AngleUnitsToRadians(mAngle));
00473 }
00474
00475 inline Angle::operator Degree()
00476 {
00477 return Degree(MathUnit::AngleUnitsToDegrees(mAngle));
00478 }
00479
00480 inline Radian operator * ( Real a, const Radian& b )
00481 {
00482 return Radian ( a * b.valueRadians() );
00483 }
00484
00485 inline Radian operator / ( Real a, const Radian& b )
00486 {
00487 return Radian ( a / b.valueRadians() );
00488 }
00489
00490 inline Degree operator * ( Real a, const Degree& b )
00491 {
00492 return Degree ( a * b.valueDegrees() );
00493 }
00494
00495 inline Degree operator / ( Real a, const Degree& b )
00496 {
00497 return Degree ( a / b.valueDegrees() );
00498 }
00499
00500 }
00501
00502 #endif