home *** CD-ROM | disk | FTP | other *** search
/ GameStar 2006 March / Gamestar_82_2006-03_dvd.iso / DVDStar / Editace / quake4_sdkv10.exe / source / idlib / math / Complex.h < prev    next >
C/C++ Source or Header  |  2005-11-14  |  8KB  |  322 lines

  1.  
  2. #ifndef __MATH_COMPLEX_H__
  3. #define __MATH_COMPLEX_H__
  4.  
  5. /*
  6. ===============================================================================
  7.  
  8.   Complex number
  9.  
  10. ===============================================================================
  11. */
  12.  
  13. class idComplex {
  14. public:
  15.     float                r;        // real part
  16.     float                i;        // imaginary part
  17.  
  18.                         idComplex( void );
  19.                         idComplex( const float r, const float i );
  20.  
  21.     void                 Set( const float r, const float i );
  22.     void                Zero( void );
  23.  
  24.     float                operator[]( int index ) const;
  25.     float &                operator[]( int index );
  26.  
  27.     idComplex            operator-() const;
  28.     idComplex &            operator=( const idComplex &a );
  29.  
  30.     idComplex            operator*( const idComplex &a ) const;
  31.     idComplex            operator/( const idComplex &a ) const;
  32.     idComplex            operator+( const idComplex &a ) const;
  33.     idComplex            operator-( const idComplex &a ) const;
  34.  
  35.     idComplex &            operator*=( const idComplex &a );
  36.     idComplex &            operator/=( const idComplex &a );
  37.     idComplex &            operator+=( const idComplex &a );
  38.     idComplex &            operator-=( const idComplex &a );
  39.  
  40.     idComplex            operator*( const float a ) const;
  41.     idComplex            operator/( const float a ) const;
  42.     idComplex            operator+( const float a ) const;
  43.     idComplex            operator-( const float a ) const;
  44.  
  45.     idComplex &            operator*=( const float a );
  46.     idComplex &            operator/=( const float a );
  47.     idComplex &            operator+=( const float a );
  48.     idComplex &            operator-=( const float a );
  49.  
  50.     friend idComplex    operator*( const float a, const idComplex &b );
  51.     friend idComplex    operator/( const float a, const idComplex &b );
  52.     friend idComplex    operator+( const float a, const idComplex &b );
  53.     friend idComplex    operator-( const float a, const idComplex &b );
  54.  
  55.     bool                Compare( const idComplex &a ) const;                        // exact compare, no epsilon
  56.     bool                Compare( const idComplex &a, const float epsilon ) const;    // compare with epsilon
  57.     bool                operator==(    const idComplex &a ) const;                        // exact compare, no epsilon
  58.     bool                operator!=(    const idComplex &a ) const;                        // exact compare, no epsilon
  59.  
  60.     idComplex            Reciprocal( void ) const;
  61.     idComplex            Sqrt( void ) const;
  62.     float                Abs( void ) const;
  63.  
  64.     int                    GetDimension( void ) const;
  65.  
  66.     const float *        ToFloatPtr( void ) const;
  67.     float *                ToFloatPtr( void );
  68.     const char *        ToString( int precision = 2 ) const;
  69. };
  70.  
  71. extern idComplex complex_origin;
  72. #define complex_zero complex_origin
  73.  
  74. ID_INLINE idComplex::idComplex( void ) {
  75. }
  76.  
  77. ID_INLINE idComplex::idComplex( const float r, const float i ) {
  78.     this->r = r;
  79.     this->i = i;
  80. }
  81.  
  82. ID_INLINE void idComplex::Set( const float r, const float i ) {
  83.     this->r = r;
  84.     this->i = i;
  85. }
  86.  
  87. ID_INLINE void idComplex::Zero( void ) {
  88.     r = i = 0.0f;
  89. }
  90.  
  91. ID_INLINE float idComplex::operator[]( int index ) const {
  92.     assert( index >= 0 && index < 2 );
  93.     return ( &r )[ index ];
  94. }
  95.  
  96. ID_INLINE float& idComplex::operator[]( int index ) {
  97.     assert( index >= 0 && index < 2 );
  98.     return ( &r )[ index ];
  99. }
  100.  
  101. ID_INLINE idComplex idComplex::operator-() const {
  102.     return idComplex( -r, -i );
  103. }
  104.  
  105. ID_INLINE idComplex &idComplex::operator=( const idComplex &a ) {
  106.     r = a.r;
  107.     i = a.i;
  108.     return *this;
  109. }
  110.  
  111. ID_INLINE idComplex idComplex::operator*( const idComplex &a ) const {
  112.     return idComplex( r * a.r - i * a.i, i * a.r + r * a.i );
  113. }
  114.  
  115. ID_INLINE idComplex idComplex::operator/( const idComplex &a ) const {
  116.     float s, t;
  117.     if ( idMath::Fabs( a.r ) >= idMath::Fabs( a.i ) ) {
  118.         s = a.i / a.r;
  119.         t = 1.0f / ( a.r + s * a.i );
  120.         return idComplex( ( r + s * i ) * t, ( i - s * r ) * t );
  121.     } else {
  122.         s = a.r / a.i;
  123.         t = 1.0f / ( s * a.r + a.i );
  124.         return idComplex( ( r * s + i ) * t, ( i * s - r ) * t );
  125.     }
  126. }
  127.  
  128. ID_INLINE idComplex idComplex::operator+( const idComplex &a ) const {
  129.     return idComplex( r + a.r, i + a.i );
  130. }
  131.  
  132. ID_INLINE idComplex idComplex::operator-( const idComplex &a ) const {
  133.     return idComplex( r - a.r, i - a.i );
  134. }
  135.  
  136. ID_INLINE idComplex &idComplex::operator*=( const idComplex &a ) {
  137.     *this = idComplex( r * a.r - i * a.i, i * a.r + r * a.i );
  138.     return *this;
  139. }
  140.  
  141. ID_INLINE idComplex &idComplex::operator/=( const idComplex &a ) {
  142.     float s, t;
  143.     if ( idMath::Fabs( a.r ) >= idMath::Fabs( a.i ) ) {
  144.         s = a.i / a.r;
  145.         t = 1.0f / ( a.r + s * a.i );
  146.         *this = idComplex( ( r + s * i ) * t, ( i - s * r ) * t );
  147.     } else {
  148.         s = a.r / a.i;
  149.         t = 1.0f / ( s * a.r + a.i );
  150.         *this = idComplex( ( r * s + i ) * t, ( i * s - r ) * t );
  151.     }
  152.     return *this;
  153. }
  154.  
  155. ID_INLINE idComplex &idComplex::operator+=( const idComplex &a ) {
  156.     r += a.r;
  157.     i += a.i;
  158.     return *this;
  159. }
  160.  
  161. ID_INLINE idComplex &idComplex::operator-=( const idComplex &a ) {
  162.     r -= a.r;
  163.     i -= a.i;
  164.     return *this;
  165. }
  166.  
  167. ID_INLINE idComplex idComplex::operator*( const float a ) const {
  168.     return idComplex( r * a, i * a );
  169. }
  170.  
  171. ID_INLINE idComplex idComplex::operator/( const float a ) const {
  172.     float s = 1.0f / a;
  173.     return idComplex( r * s, i * s );
  174. }
  175.  
  176. ID_INLINE idComplex idComplex::operator+( const float a ) const {
  177.     return idComplex( r + a, i );
  178. }
  179.  
  180. ID_INLINE idComplex idComplex::operator-( const float a ) const {
  181.     return idComplex( r - a, i );
  182. }
  183.  
  184. ID_INLINE idComplex &idComplex::operator*=( const float a ) {
  185.     r *= a;
  186.     i *= a;
  187.     return *this;
  188. }
  189.  
  190. ID_INLINE idComplex &idComplex::operator/=( const float a ) {
  191.     float s = 1.0f / a;
  192.     r *= s;
  193.     i *= s;
  194.     return *this;
  195. }
  196.  
  197. ID_INLINE idComplex &idComplex::operator+=( const float a ) {
  198.     r += a;
  199.     return *this;
  200. }
  201.  
  202. ID_INLINE idComplex &idComplex::operator-=( const float a ) {
  203.     r -= a;
  204.     return *this;
  205. }
  206.  
  207. ID_INLINE idComplex operator*( const float a, const idComplex &b ) {
  208.     return idComplex( a * b.r, a * b.i );
  209. }
  210.  
  211. ID_INLINE idComplex operator/( const float a, const idComplex &b ) {
  212.     float s, t;
  213.     if ( idMath::Fabs( b.r ) >= idMath::Fabs( b.i ) ) {
  214.         s = b.i / b.r;
  215.         t = a / ( b.r + s * b.i );
  216.         return idComplex( t, - s * t );
  217.     } else {
  218.         s = b.r / b.i;
  219.         t = a / ( s * b.r + b.i );
  220.         return idComplex( s * t, - t );
  221.     }
  222. }
  223.  
  224. ID_INLINE idComplex operator+( const float a, const idComplex &b ) {
  225.     return idComplex( a + b.r, b.i );
  226. }
  227.  
  228. ID_INLINE idComplex operator-( const float a, const idComplex &b ) {
  229.     return idComplex( a - b.r, -b.i );
  230. }
  231.  
  232. ID_INLINE idComplex idComplex::Reciprocal( void ) const {
  233.     float s, t;
  234.     if ( idMath::Fabs( r ) >= idMath::Fabs( i ) ) {
  235.         s = i / r;
  236.         t = 1.0f / ( r + s * i );
  237.         return idComplex( t, - s * t );
  238.     } else {
  239.         s = r / i;
  240.         t = 1.0f / ( s * r + i );
  241.         return idComplex( s * t, - t );
  242.     }
  243. }
  244.  
  245. ID_INLINE idComplex idComplex::Sqrt( void ) const {
  246.     float x, y, w;
  247.  
  248.     if ( r == 0.0f && i == 0.0f ) {
  249.         return idComplex( 0.0f, 0.0f );
  250.     }
  251.     x = idMath::Fabs( r );
  252.     y = idMath::Fabs( i );
  253.     if ( x >= y ) {
  254.         w = y / x;
  255.         w = idMath::Sqrt( x ) * idMath::Sqrt( 0.5f * ( 1.0f + idMath::Sqrt( 1.0f + w * w ) ) );
  256.     } else {
  257.         w = x / y;
  258.         w = idMath::Sqrt( y ) * idMath::Sqrt( 0.5f * ( w + idMath::Sqrt( 1.0f + w * w ) ) );
  259.     }
  260.     if ( w == 0.0f ) {
  261.         return idComplex( 0.0f, 0.0f );
  262.     }
  263.     if ( r >= 0.0f ) {
  264.         return idComplex( w, 0.5f * i / w );
  265.     } else {
  266.         return idComplex( 0.5f * y / w, ( i >= 0.0f ) ? w : -w );
  267.     }
  268. }
  269.  
  270. ID_INLINE float idComplex::Abs( void ) const {
  271.     float x, y, t;
  272.     x = idMath::Fabs( r );
  273.     y = idMath::Fabs( i );
  274.     if ( x == 0.0f ) {
  275.         return y;
  276.     } else if ( y == 0.0f ) {
  277.         return x;
  278.     } else if ( x > y ) {
  279.         t = y / x;
  280.         return x * idMath::Sqrt( 1.0f + t * t );
  281.     } else {
  282.         t = x / y;
  283.         return y * idMath::Sqrt( 1.0f + t * t );
  284.     }
  285. }
  286.  
  287. ID_INLINE bool idComplex::Compare( const idComplex &a ) const {
  288.     return ( ( r == a.r ) && ( i == a.i ) );
  289. }
  290.  
  291. ID_INLINE bool idComplex::Compare( const idComplex &a, const float epsilon ) const {
  292.     if ( idMath::Fabs( r - a.r ) > epsilon ) {
  293.         return false;
  294.     }
  295.     if ( idMath::Fabs( i - a.i ) > epsilon ) {
  296.         return false;
  297.     }
  298.     return true;
  299. }
  300.  
  301. ID_INLINE bool idComplex::operator==( const idComplex &a ) const {
  302.     return Compare( a );
  303. }
  304.  
  305. ID_INLINE bool idComplex::operator!=( const idComplex &a ) const {
  306.     return !Compare( a );
  307. }
  308.  
  309. ID_INLINE int idComplex::GetDimension( void ) const {
  310.     return 2;
  311. }
  312.  
  313. ID_INLINE const float *idComplex::ToFloatPtr( void ) const {
  314.     return &r;
  315. }
  316.  
  317. ID_INLINE float *idComplex::ToFloatPtr( void ) {
  318.     return &r;
  319. }
  320.  
  321. #endif /* !__MATH_COMPLEX_H__ */
  322.