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
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
00040 PrecisionType d = PrecisionType( delta(m, 0) );
00041
int abs_m = abs(m);
00042
00043
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
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
00061 PrecisionType u, v, w;
00062 uvw(l, m, n, u, v, w);
00063
00064
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
00079
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
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
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
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
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
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
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
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 };
00184
00185 };
00186
00187
#endif //_ZFXMATH_INCLUDE_SH_ROTATE_H__