2 ===========================================================================
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
26 ===========================================================================
29 #ifndef __MATH_COMPLEX_H__
30 #define __MATH_COMPLEX_H__
33 ===============================================================================
37 ===============================================================================
43 float i; // imaginary part
46 idComplex( const float r, const float i );
48 void Set( const float r, const float i );
51 float operator[]( int index ) const;
52 float & operator[]( int index );
54 idComplex operator-() const;
55 idComplex & operator=( const idComplex &a );
57 idComplex operator*( const idComplex &a ) const;
58 idComplex operator/( const idComplex &a ) const;
59 idComplex operator+( const idComplex &a ) const;
60 idComplex operator-( const idComplex &a ) const;
62 idComplex & operator*=( const idComplex &a );
63 idComplex & operator/=( const idComplex &a );
64 idComplex & operator+=( const idComplex &a );
65 idComplex & operator-=( const idComplex &a );
67 idComplex operator*( const float a ) const;
68 idComplex operator/( const float a ) const;
69 idComplex operator+( const float a ) const;
70 idComplex operator-( const float a ) const;
72 idComplex & operator*=( const float a );
73 idComplex & operator/=( const float a );
74 idComplex & operator+=( const float a );
75 idComplex & operator-=( const float a );
77 friend idComplex operator*( const float a, const idComplex &b );
78 friend idComplex operator/( const float a, const idComplex &b );
79 friend idComplex operator+( const float a, const idComplex &b );
80 friend idComplex operator-( const float a, const idComplex &b );
82 bool Compare( const idComplex &a ) const; // exact compare, no epsilon
83 bool Compare( const idComplex &a, const float epsilon ) const; // compare with epsilon
84 bool operator==( const idComplex &a ) const; // exact compare, no epsilon
85 bool operator!=( const idComplex &a ) const; // exact compare, no epsilon
87 idComplex Reciprocal( void ) const;
88 idComplex Sqrt( void ) const;
89 float Abs( void ) const;
91 int GetDimension( void ) const;
93 const float * ToFloatPtr( void ) const;
94 float * ToFloatPtr( void );
95 const char * ToString( int precision = 2 ) const;
98 extern idComplex complex_origin;
99 #define complex_zero complex_origin
101 ID_INLINE idComplex::idComplex( void ) {
104 ID_INLINE idComplex::idComplex( const float r, const float i ) {
109 ID_INLINE void idComplex::Set( const float r, const float i ) {
114 ID_INLINE void idComplex::Zero( void ) {
118 ID_INLINE float idComplex::operator[]( int index ) const {
119 assert( index >= 0 && index < 2 );
120 return ( &r )[ index ];
123 ID_INLINE float& idComplex::operator[]( int index ) {
124 assert( index >= 0 && index < 2 );
125 return ( &r )[ index ];
128 ID_INLINE idComplex idComplex::operator-() const {
129 return idComplex( -r, -i );
132 ID_INLINE idComplex &idComplex::operator=( const idComplex &a ) {
138 ID_INLINE idComplex idComplex::operator*( const idComplex &a ) const {
139 return idComplex( r * a.r - i * a.i, i * a.r + r * a.i );
142 ID_INLINE idComplex idComplex::operator/( const idComplex &a ) const {
144 if ( idMath::Fabs( a.r ) >= idMath::Fabs( a.i ) ) {
146 t = 1.0f / ( a.r + s * a.i );
147 return idComplex( ( r + s * i ) * t, ( i - s * r ) * t );
150 t = 1.0f / ( s * a.r + a.i );
151 return idComplex( ( r * s + i ) * t, ( i * s - r ) * t );
155 ID_INLINE idComplex idComplex::operator+( const idComplex &a ) const {
156 return idComplex( r + a.r, i + a.i );
159 ID_INLINE idComplex idComplex::operator-( const idComplex &a ) const {
160 return idComplex( r - a.r, i - a.i );
163 ID_INLINE idComplex &idComplex::operator*=( const idComplex &a ) {
164 *this = idComplex( r * a.r - i * a.i, i * a.r + r * a.i );
168 ID_INLINE idComplex &idComplex::operator/=( const idComplex &a ) {
170 if ( idMath::Fabs( a.r ) >= idMath::Fabs( a.i ) ) {
172 t = 1.0f / ( a.r + s * a.i );
173 *this = idComplex( ( r + s * i ) * t, ( i - s * r ) * t );
176 t = 1.0f / ( s * a.r + a.i );
177 *this = idComplex( ( r * s + i ) * t, ( i * s - r ) * t );
182 ID_INLINE idComplex &idComplex::operator+=( const idComplex &a ) {
188 ID_INLINE idComplex &idComplex::operator-=( const idComplex &a ) {
194 ID_INLINE idComplex idComplex::operator*( const float a ) const {
195 return idComplex( r * a, i * a );
198 ID_INLINE idComplex idComplex::operator/( const float a ) const {
200 return idComplex( r * s, i * s );
203 ID_INLINE idComplex idComplex::operator+( const float a ) const {
204 return idComplex( r + a, i );
207 ID_INLINE idComplex idComplex::operator-( const float a ) const {
208 return idComplex( r - a, i );
211 ID_INLINE idComplex &idComplex::operator*=( const float a ) {
217 ID_INLINE idComplex &idComplex::operator/=( const float a ) {
224 ID_INLINE idComplex &idComplex::operator+=( const float a ) {
229 ID_INLINE idComplex &idComplex::operator-=( const float a ) {
234 ID_INLINE idComplex operator*( const float a, const idComplex &b ) {
235 return idComplex( a * b.r, a * b.i );
238 ID_INLINE idComplex operator/( const float a, const idComplex &b ) {
240 if ( idMath::Fabs( b.r ) >= idMath::Fabs( b.i ) ) {
242 t = a / ( b.r + s * b.i );
243 return idComplex( t, - s * t );
246 t = a / ( s * b.r + b.i );
247 return idComplex( s * t, - t );
251 ID_INLINE idComplex operator+( const float a, const idComplex &b ) {
252 return idComplex( a + b.r, b.i );
255 ID_INLINE idComplex operator-( const float a, const idComplex &b ) {
256 return idComplex( a - b.r, -b.i );
259 ID_INLINE idComplex idComplex::Reciprocal( void ) const {
261 if ( idMath::Fabs( r ) >= idMath::Fabs( i ) ) {
263 t = 1.0f / ( r + s * i );
264 return idComplex( t, - s * t );
267 t = 1.0f / ( s * r + i );
268 return idComplex( s * t, - t );
272 ID_INLINE idComplex idComplex::Sqrt( void ) const {
275 if ( r == 0.0f && i == 0.0f ) {
276 return idComplex( 0.0f, 0.0f );
278 x = idMath::Fabs( r );
279 y = idMath::Fabs( i );
282 w = idMath::Sqrt( x ) * idMath::Sqrt( 0.5f * ( 1.0f + idMath::Sqrt( 1.0f + w * w ) ) );
285 w = idMath::Sqrt( y ) * idMath::Sqrt( 0.5f * ( w + idMath::Sqrt( 1.0f + w * w ) ) );
288 return idComplex( 0.0f, 0.0f );
291 return idComplex( w, 0.5f * i / w );
293 return idComplex( 0.5f * y / w, ( i >= 0.0f ) ? w : -w );
297 ID_INLINE float idComplex::Abs( void ) const {
299 x = idMath::Fabs( r );
300 y = idMath::Fabs( i );
303 } else if ( y == 0.0f ) {
305 } else if ( x > y ) {
307 return x * idMath::Sqrt( 1.0f + t * t );
310 return y * idMath::Sqrt( 1.0f + t * t );
314 ID_INLINE bool idComplex::Compare( const idComplex &a ) const {
315 return ( ( r == a.r ) && ( i == a.i ) );
318 ID_INLINE bool idComplex::Compare( const idComplex &a, const float epsilon ) const {
319 if ( idMath::Fabs( r - a.r ) > epsilon ) {
322 if ( idMath::Fabs( i - a.i ) > epsilon ) {
328 ID_INLINE bool idComplex::operator==( const idComplex &a ) const {
332 ID_INLINE bool idComplex::operator!=( const idComplex &a ) const {
333 return !Compare( a );
336 ID_INLINE int idComplex::GetDimension( void ) const {
340 ID_INLINE const float *idComplex::ToFloatPtr( void ) const {
344 ID_INLINE float *idComplex::ToFloatPtr( void ) {
348 #endif /* !__MATH_COMPLEX_H__ */