Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members

SHRotate.h

Go to the documentation of this file.
00001 00002 00003 00004 00005 00006 00007 00008 00009 00010 00011 00012 00013 00014 00015 00016 00017 00018 00019 00020 00021 #ifndef _ZFXMATH_INCLUDE_SH_ROTATE_H_ 00022 #define _ZFXMATH_INCLUDE_SH_ROTATE_H_ 00023 00024 namespace ZFXMath 00025 { 00026 00027 namespace SphericalHarmonics 00028 { 00029 00030 inline int delta(const int m, const int n) 00031 { 00032 // Kronecker Delta 00033 return ( m == n ? 1 : 0 ); 00034 } 00035 00036 template<class PrecisionType> 00037 void uvw(const int l, const int m, const int n, PrecisionType& u, PrecisionType& v, PrecisionType& w) 00038 { 00039 // Pre-calculate simple reusable terms 00040 PrecisionType d = PrecisionType( delta(m, 0) ); 00041 int abs_m = abs(m); 00042 00043 // Only calculate the required denominator once 00044 PrecisionType denom; 00045 if (abs(n) == l) 00046 denom = PrecisionType( (2 * l) * (2 * l - 1) ); 00047 00048 else 00049 denom = PrecisionType( (l + n) * (l - n) ); 00050 00051 // Now just calculate the scalars 00052 u = PrecisionType( sqrt((l + m) * (l - m) / denom) ); 00053 v = PrecisionType( 0.5f * sqrt((1 + d) * (l + abs_m - 1) * (l + abs_m) / denom) * (1 - 2 * d) ); 00054 w = PrecisionType( -0.5f * sqrt((l - abs_m - 1) * (l - abs_m) / denom) * (1 - d) ); 00055 } 00056 00057 template<class PrecisionType, class FuncValueType> 00058 PrecisionType M(const int l, const int m, const int n, const TRotateMatrix<PrecisionType,FuncValueType>& M) 00059 { 00060 // First get the scalars 00061 PrecisionType u, v, w; 00062 uvw(l, m, n, u, v, w); 00063 00064 // Scale by their functions 00065 if (u) 00066 u *= U(l, m, n, M); 00067 if (v) 00068 v *= V(l, m, n, M); 00069 if (w) 00070 w *= W(l, m, n, M); 00071 00072 return (u + v + w); 00073 } 00074 00075 template<class PrecisionType, class FuncValueType> 00076 PrecisionType P(const int i, const int l, const int a, const int b, const TRotateMatrix<PrecisionType,FuncValueType>& M) 00077 { 00078 // Rather than passing the permuted rotation matrix around grab it directly from the first 00079 // rotation band which is never modified 00080 PrecisionType ri1 = M(1, i, 1); 00081 PrecisionType rim1 = M(1, i, -1); 00082 PrecisionType ri0 = M(1, i, 0); 00083 00084 if (b == -l) 00085 return (ri1 * M(l - 1, a, -l + 1) + rim1 * M(l - 1, a, l - 1)); 00086 00087 else if (b == l) 00088 return (ri1 * M(l - 1, a, l - 1) - rim1 * M(l - 1, a, -l + 1)); 00089 00090 else // |b|<l 00091 return (ri0 * M(l - 1, a, b)); 00092 } 00093 00094 00095 template<class PrecisionType, class FuncValueType> 00096 PrecisionType U(const int l, const int m, const int n, const TRotateMatrix<PrecisionType,FuncValueType>& M) 00097 { 00098 // All cases fall correctly through here 00099 return (P(0, l, m, n, M)); 00100 } 00101 00102 00103 template<class PrecisionType, class FuncValueType> 00104 PrecisionType V(const int l, const int m, const int n, const TRotateMatrix<PrecisionType,FuncValueType>& M) 00105 { 00106 if (m == 0) 00107 { 00108 PrecisionType p0 = P(1, l, 1, n, M); 00109 PrecisionType p1 = P(-1, l, -1, n, M); 00110 return (p0 + p1); 00111 } 00112 00113 else if (m > 0) 00114 { 00115 PrecisionType d = PrecisionType( delta(m, 1) ); 00116 PrecisionType p0 = P(1, l, m - 1, n, M); 00117 PrecisionType p1 = P(-1, l, -m + 1, n, M); 00118 return PrecisionType(p0 * sqrt(1 + d) - p1 * (1 - d)); 00119 } 00120 00121 else // m < 0 00122 { 00123 PrecisionType d = PrecisionType( delta(m, -1) ); 00124 PrecisionType p0 = P(1, l, m + 1, n, M); 00125 PrecisionType p1 = P(-1, l, -m - 1, n, M); 00126 return PrecisionType(p0 * (1 - d) + p1 * sqrt(1 + d)); 00127 } 00128 } 00129 00130 00131 template<class PrecisionType, class FuncValueType> 00132 PrecisionType W(const int l, const int m, const int n, const TRotateMatrix<PrecisionType,FuncValueType>& M) 00133 { 00134 if (m == 0) 00135 { 00136 // Never gets called as kd=0 00137 assert(false); 00138 return (0); 00139 } 00140 00141 else if (m > 0) 00142 { 00143 PrecisionType p0 = P(1, l, m + 1, n, M); 00144 PrecisionType p1 = P(-1, l, -m - 1, n, M); 00145 return (p0 + p1); 00146 } 00147 00148 else // m < 0 00149 { 00150 PrecisionType p0 = P(1, l, m - 1, n, M); 00151 PrecisionType p1 = P(-1, l, -m + 1, n, M); 00152 return (p0 - p1); 00153 } 00154 } 00155 00161 template<class PrecisionType, class FuncValueType> 00162 void SHRotate( TRotateMatrix<PrecisionType,FuncValueType>& shrm, const TMatrix3x3<PrecisionType>& rotation ) 00163 { 00164 // The first band is rotated by a permutation of the original matrix 00165 shrm(1, -1, -1) = (PrecisionType) rotation._22; 00166 shrm(1, -1, 0) = (PrecisionType) -rotation._32; 00167 shrm(1, -1, +1) = (PrecisionType) rotation._12; 00168 shrm(1, 0, -1) = (PrecisionType) -rotation._23; 00169 shrm(1, 0, 0) = (PrecisionType) rotation._33; 00170 shrm(1, 0, +1) = (PrecisionType) -rotation._13; 00171 shrm(1, +1, -1) = (PrecisionType) rotation._21; 00172 shrm(1, +1, 0) = (PrecisionType) -rotation._31; 00173 shrm(1, +1, +1) = (PrecisionType) rotation._11; 00174 00175 // Calculate each block of the rotation matrix for each subsequent band 00176 for (int band = 2; band < shrm.GetNbBands(); band++) 00177 { 00178 for (int m = -band; m <= band; m++) 00179 for (int n = -band; n <= band; n++) 00180 shrm(band, m, n) = M(band, m, n, shrm); 00181 } 00182 } 00183 }; // namespace SphericalHarmonics 00184 00185 }; // namespace ZFXMath 00186 00187 #endif //_ZFXMATH_INCLUDE_SH_ROTATE_H__

Generated on Thu Nov 25 04:02:58 2004 for ZFX-Math Library by doxygen 1.3.8