00001
00002
00003
00004
00005
00006
00007
00008
00009
#ifndef _ZFXMATH_INCLUDE_SH_H_
00010
#define _ZFXMATH_INCLUDE_SH_H_
00011
00012
namespace ZFXMath
00013 {
00014
00029
namespace SphericalHarmonics
00030 {
00031
00037
template<
class PrecisionType>
00038 struct TSample
00039 {
00040
00041
TSample() { };
00042
00043
00044
TSample(
const PrecisionType u,
const PrecisionType v ) :
00045
theta(u),
00046
phi(v)
00047 {
00048
x = PrecisionType( sin(
theta) * cos(
phi) );
00049
y = PrecisionType( sin(
theta) * sin(phi) );
00050
z = PrecisionType( cos(
theta) );
00051 }
00052
00054 PrecisionType
theta,
phi;
00055
00057 PrecisionType
x,
y,
z;
00058 };
00059
00069
template<
class PrecisionType,
class FuncValueType>
00070 struct TSphericalFunction
00071 {
00077
virtual FuncValueType
EvalFunction(
const TSample<PrecisionType>& s)
const = 0;
00078 };
00079
00089
template<
class T>
00090 class TCoeffs
00091 {
00092
public:
00098
template<
class TAlloc>
00099 class TAllocator
00100 {
00101
public:
00102
TAllocator(
int size )
00103 {
00104 m_Size = size;
00105 m_pMemory =
new TAlloc[size];
00106 m_pNextMem = m_pMemory;
00107 }
00108
00109 ~
TAllocator()
00110 {
00111
delete[] m_pMemory;
00112 }
00113
00114 TAlloc* GetMem(
int amount )
00115 {
00116 m_Size -= amount;
00117 assert( m_Size >= 0 );
00118
00119 TAlloc* pMem = m_pNextMem;
00120 m_pNextMem += amount;
00121
00122
return pMem;
00123 }
00124
00125
private:
00126 TAlloc* m_pMemory;
00127 TAlloc* m_pNextMem;
00128
int m_Size;
00129 };
00130
typedef TAllocator<T> Allocator;
00131
00132
TCoeffs() : m_Coeffs(0), m_NbBands(0), m_NbCoeffs(0) { }
00133
00134
TCoeffs(
const int nb_bands) :
00135 m_Coeffs(0),
00136 m_NbBands(nb_bands),
00137 m_NbCoeffs(m_NbBands * m_NbBands),
00138 m_FromAllocator(false)
00139 {
00140
00141 m_Coeffs =
new T[m_NbCoeffs];
00142 }
00143
00144 TCoeffs(
const int nb_bands, Allocator* pAlloc) :
00145 m_Coeffs(0),
00146 m_NbCoeffs(nb_bands * nb_bands),
00147 m_FromAllocator(true)
00148 {
00149
00150 m_Coeffs = pAlloc->GetMem( m_NbCoeffs );
00151 }
00152
00153 ~TCoeffs()
00154 {
00155
00156
if (!m_FromAllocator)
00157
delete [] m_Coeffs;
00158 }
00159
00160 TCoeffs(
const TCoeffs& other) :
00161 m_Coeffs(0),
00162 m_NbBands(other.m_NbBands),
00163 m_NbCoeffs(other.m_NbCoeffs),
00164 m_FromAllocator(other.m_FromAllocator)
00165 {
00166
00167
if (m_FromAllocator)
00168 m_Coeffs = other.m_Coeffs;
00169
00170
else
00171 {
00172
00173 m_Coeffs =
new T[m_NbCoeffs];
00174
for (
int i = 0; i < m_NbCoeffs; i++)
00175 m_Coeffs[i] = other.m_Coeffs[i];
00176 }
00177 }
00178
00179
00180 T operator () (
const int l,
const int m)
const
00181
{
00182
return (m_Coeffs[Check(l * (l + 1) + m)]);
00183 }
00184 T& operator () (
const int l,
const int m)
00185 {
00186
return (m_Coeffs[Check(l * (l + 1) + m)]);
00187 }
00188
00189
00190 T operator () (
const int i)
const
00191
{
00192
return (m_Coeffs[Check(i)]);
00193 }
00194 T& operator () (
const int i)
00195 {
00196
return (m_Coeffs[Check(i)]);
00197 }
00198
00199
int GetNbBands(
void)
const
00200
{
00201
return (m_NbBands);
00202 }
00203
00204
int GetSize(
void)
const
00205
{
00206
return (m_NbCoeffs);
00207 }
00208
00209
private:
00210
inline int Check(
const int index)
const
00211
{
00212
00213 assert(index >= 0 && index < m_NbCoeffs);
00214
00215
return (index);
00216 }
00217
00218
00219 T* m_Coeffs;
00220
00221
00222
int m_NbBands;
00223
00224
00225
int m_NbCoeffs;
00226
00227
00228
bool m_FromAllocator;
00229
00230 };
00231
00232
00236
00237
00238
00239
00240
00241
00242
00243
00245
template<
class PrecisionType,
class FuncValueType>
00246
void Project(
const TSphericalFunction<PrecisionType,FuncValueType>& func,
00247
const TSample<PrecisionType>* samples,
00248
const TCoeffs<PrecisionType>* coeffs,
00249
const int nb_samples,
00250 TCoeffs<FuncValueType>& dest )
00251 {
00252
int nb_coeffs = dest.GetSize();
00253
00254
00255 assert(samples && coeffs);
00256 assert(nb_samples >= 0);
00257 assert(coeffs[0].GetSize() == nb_coeffs);
00258
00259
00260
for (
int i = 0; i < nb_coeffs; i++)
00261 dest(i) = 0;
00262
00263
for (
int i = 0; i < nb_samples; i++)
00264 {
00265
00266
const TSample<PrecisionType>& s = samples[i];
00267
const TCoeffs<PrecisionType>& c = coeffs[i];
00268 FuncValueType sample = func.EvalFunction(s);
00269
00270
00271
for (
int j = 0; j < nb_coeffs; j++)
00272 dest(j) += sample * FuncValueType( c(j) );
00273 }
00274
00275
00276
for (
int i = 0; i < nb_coeffs; i++)
00277 dest(i) = dest(i) * FuncValueType( PrecisionType( (4 * PI) / nb_samples ) );
00278 }
00279
00280
00281
00282
template<
class PrecisionType>
00283 PrecisionType P(
const int l,
const int m,
const PrecisionType x)
00284 {
00285
00286 PrecisionType pmm = 1;
00287
00288
00289
00290
00291
00292
00293 PrecisionType somx2 = (PrecisionType)sqrt(1 - x * x);
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305 PrecisionType fact = 1;
00306
for (
int i = 1; i <= m; i++)
00307 {
00308 pmm *= -1 * fact * somx2;
00309 fact += 2;
00310 }
00311
00312
00313
if (l == m)
00314
return (pmm);
00315
00316
00317
00318
00319
00320 PrecisionType pmmp1 = x * (2 * m + 1) * pmm;
00321
00322
00323
if (l == m + 1)
00324
return (pmmp1);
00325
00326
00327 PrecisionType pll = 0;
00328
for (
int ll = m + 2; ll <= l; ll++)
00329 {
00330
00331 pll = PrecisionType( (x * (2.0f * ll - 1.0f) * pmmp1 - (ll + m - 1.0f) * pmm) / (ll - m) );
00332
00333
00334 pmm = pmmp1;
00335 pmmp1 = pll;
00336 }
00337
00338
return (pll);
00339 }
00340
00341
00342
template<
class PrecisionType>
00343 PrecisionType y(
const int l,
const int m,
const PrecisionType theta,
const PrecisionType phi)
00344 {
00345
if (0 == m)
00346
return (PrecisionType(K<PrecisionType>(l, 0) * P(l, 0, (PrecisionType)cos(theta))));
00347
00348
if (m > 0)
00349
return PrecisionType(sqrt(2.0) * K<PrecisionType>(l, m) * cos(m * phi) * P(l, m, (PrecisionType)cos(theta)));
00350
00351
00352
return PrecisionType(sqrt(2.0) * K<PrecisionType>(l, -m) * sin(-m * phi) * P(l, -m, (PrecisionType)cos(theta)));
00353 }
00354
00355
00356
00357
template<
class PrecisionType>
00358 PrecisionType K(
const int l,
const int m)
00359 {
00360
struct FactorialGen
00361 {
00362 FactorialGen(
const int count) :
00363 factorials(0),
00364 nb_factorials(count)
00365 {
00366 factorials =
new int[nb_factorials];
00367
00368
00369 factorials[0] = 1;
00370
for (
int i = 1; i < nb_factorials; i++)
00371 factorials[i] = i * factorials[i - 1];
00372 }
00373
00374 ~FactorialGen(
void)
00375 {
00376
delete [] factorials;
00377 }
00378
00379
int operator () (
const int i)
const
00380
{
00381
00382 assert(i >= 0 && i < nb_factorials);
00383
return (factorials[i]);
00384 }
00385
00386
int* factorials;
00387
int nb_factorials;
00388 };
00389
00390
00391
00392
00393
static FactorialGen factorial(14);
00394
00395
00396
return PrecisionType(sqrt(((2 * l + 1) * factorial(l - m)) / (4 * PI * factorial(l + m))));
00397 }
00398
00399
00400 };
00401
00402 };
00403
00404
#endif //_ZFXMATH_INCLUDE_SH_H_
00405
00406