spherical_harmonics.h
Go to the documentation of this file.
00001 /****************************************************************************
00002 * VCGLib                                                            o o     *
00003 * Visual and Computer Graphics Library                            o     o   *
00004 *                                                                _   O  _   *
00005 * Copyright(C) 2006                                                \/)\/    *
00006 * Visual Computing Lab                                            /\/|      *
00007 * ISTI - Italian National Research Council                           |      *
00008 *                                                                    \      *
00009 * All rights reserved.                                                      *
00010 *                                                                           *
00011 * This program is free software; you can redistribute it and/or modify      *
00012 * it under the terms of the GNU General Public License as published by      *
00013 * the Free Software Foundation; either version 2 of the License, or         *
00014 * (at your option) any later version.                                       *
00015 *                                                                           *
00016 * This program is distributed in the hope that it will be useful,           *
00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
00019 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt)          *
00020 * for more details.                                                         *
00021 *                                                                           *
00022 ****************************************************************************/
00023 
00024 #ifndef __VCGLIB_SPHERICAL_HARMONICS_H
00025 #define __VCGLIB_SPHERICAL_HARMONICS_H
00026 
00027 #include <climits>
00028 
00029 #include <vcg/math/base.h>
00030 #include <vcg/math/random_generator.h>
00031 #include <vcg/math/legendre.h>
00032 #include <vcg/math/factorial.h>
00033 
00034 namespace vcg{
00035 namespace math{
00036 
00037 template <typename ScalarType>
00038 class DummyPolarFunctor{
00039         public:
00040                 inline ScalarType operator()(ScalarType theta, ScalarType phi) {return ScalarType(0);}
00041 };
00042 
00043 
00044 template <typename ScalarType, int MAX_BAND = 4>
00045 class ScalingFactor
00046 {
00047 private :
00048 
00049         ScalarType k_factor[MAX_BAND][MAX_BAND];
00050 
00051         static ScalingFactor sf;
00052 
00053         ScalingFactor()
00054         {
00055                 for (unsigned l = 0; l < MAX_BAND; ++l)
00056                         for (unsigned m = 0; m <= l; ++m)
00057                                 k_factor[l][m] = Sqrt( ( (2.0*l + 1.0) * Factorial<ScalarType>(l-m) ) / (4.0 * M_PI * Factorial<ScalarType>(l + m)) );
00058         }
00059 
00060 public :
00061         static ScalarType K(unsigned l, unsigned m)
00062         {
00063                 return sf.k_factor[l][m];
00064         }
00065 };
00066 
00067 template <typename ScalarType, int MAX_BAND>
00068 ScalingFactor<ScalarType, MAX_BAND> ScalingFactor<ScalarType, MAX_BAND>::sf;
00069 
00076 template <typename ScalarType, int MAX_BAND = 4>
00077 class SphericalHarmonics{
00078 
00079 private :
00080 
00081         static DynamicLegendre<ScalarType, MAX_BAND> legendre;
00082 
00083         static ScalarType scaling_factor(unsigned l, unsigned m)
00084         {
00085                 return ScalingFactor<ScalarType, MAX_BAND>::K(l,m);
00086         }
00087 
00088         inline static ScalarType complex_spherical_harmonic_re(unsigned l, unsigned m, ScalarType theta, ScalarType phi)
00089         {
00090                 return scaling_factor(l, m) * legendre.AssociatedPolynomial(l, m, Cos(theta), Sin(theta)) * Cos(m * phi);
00091         }
00092 
00093         inline static ScalarType complex_spherical_harmonic_im(unsigned l, unsigned m, ScalarType theta, ScalarType phi)
00094         {
00095                 return scaling_factor(l, m) * legendre.AssociatedPolynomial(l, m, Cos(theta), Sin(theta)) * Sin(m * phi);
00096         }
00097 
00098         ScalarType coefficients[MAX_BAND * MAX_BAND];
00099 
00100 public :
00101 
00110         static ScalarType Real(unsigned l, int m, ScalarType theta, ScalarType phi)
00111         {
00112                 assert((int)-l <= m && m <= (int)l && theta >= 0.0 && theta <= (ScalarType)M_PI && phi >= 0.0 && phi <= (ScalarType)(2.0 * M_PI));
00113 
00114                 if (m > 0) return SQRT_TWO * complex_spherical_harmonic_re(l, m, theta, phi);
00115 
00116                 else if (m == 0) return scaling_factor(l, 0) * legendre.Polynomial(l, Cos(theta));
00117 
00118                 else return SQRT_TWO * complex_spherical_harmonic_im(l, -m, theta, phi);
00119         }
00120 
00121         template <typename PolarFunctor>
00122         static SphericalHarmonics Project(PolarFunctor * fun, unsigned n_samples)
00123         {
00124                 const ScalarType weight = 4 * M_PI;
00125 
00126                 unsigned sqrt_n_samples = (unsigned int) Sqrt((int)n_samples);
00127                 unsigned actual_n_samples = sqrt_n_samples * sqrt_n_samples;
00128                 unsigned n_coeff = MAX_BAND * MAX_BAND;
00129 
00130                 ScalarType one_over_n = 1.0/(ScalarType)sqrt_n_samples;
00131 
00132                 MarsenneTwisterRNG rand;
00133                 SphericalHarmonics sph;
00134 
00135                 int i = 0;
00136 
00137                 for (unsigned k = 0; k < n_coeff; k++ ) sph.coefficients[k] = 0;
00138 
00139                 for (unsigned a = 0; a < sqrt_n_samples; ++a )
00140                 {
00141                         for (unsigned b = 0; b < sqrt_n_samples; ++b)
00142                         {
00143                                 ScalarType x = (a + ScalarType(rand.generate01())) * one_over_n;
00144                                 ScalarType y = (b + ScalarType(rand.generate01())) * one_over_n;
00145 
00146                                 ScalarType theta = 2.0 * Acos(Sqrt(1.0 - x));
00147                                 ScalarType phi = 2.0 * M_PI * y;
00148 
00149                                 for (int l = 0; l < (int)MAX_BAND; ++l)
00150                                 {
00151                                         for (int m = -l; m <= l; ++m)
00152                                         {
00153                                                 int index = l * (l+1) + m;
00154                                                 sph.coefficients[index] += (*fun)(theta, phi) * Real(l, m, theta, phi);
00155                                         }
00156                                 }
00157                                 i++;
00158                         }
00159                 }
00160 
00161                 ScalarType factor = weight / actual_n_samples;
00162                 for(i = 0; i < (int)n_coeff; ++i)
00163                 {
00164                         sph.coefficients[i] *= factor;
00165                 }
00166 
00167                 return sph;
00168         }
00169 
00170         static SphericalHarmonics Wrap(ScalarType * _coefficients)
00171         {
00172                 SphericalHarmonics sph;
00173                 for(int i = 0; i < (int) MAX_BAND *  MAX_BAND; ++i) sph.coefficients[i] = _coefficients[i];
00174                 return sph;
00175         }
00176 
00177         ScalarType operator()(ScalarType theta, ScalarType phi)
00178         {
00179                 ScalarType f = 0;
00180 
00181                 for (int l = 0; l < MAX_BAND; ++l)
00182                 {
00183                         for (int m = -l; m <= l; ++m)
00184                         {
00185                                 int index = l * (l+1) + m;
00186                                 f += (coefficients[index] * Real(l, m, theta, phi));
00187                         }
00188                 }
00189 
00190                 return f;
00191         }
00192 };
00193 
00194 template <typename ScalarType, int MAX_BAND>
00195 DynamicLegendre<ScalarType, MAX_BAND> SphericalHarmonics<ScalarType, MAX_BAND>::legendre;
00196 
00197 }} //namespace vcg::math
00198 
00199 #endif


shape_reconstruction
Author(s): Roberto Martín-Martín
autogenerated on Sat Jun 8 2019 18:36:31