From 3705cb3cb9eed362a28d8ca3ab0cf96fa8d9dd0f Mon Sep 17 00:00:00 2001 From: cnr-isti-vclab Date: Wed, 14 Oct 2009 16:10:42 +0000 Subject: [PATCH] Improved speed by using DynamicLegendre and precomputing Scaling Factors --- vcg/math/spherical_harmonics.h | 43 ++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/vcg/math/spherical_harmonics.h b/vcg/math/spherical_harmonics.h index 42495ff6..e9211c80 100644 --- a/vcg/math/spherical_harmonics.h +++ b/vcg/math/spherical_harmonics.h @@ -40,6 +40,33 @@ class DummyPolarFunctor{ inline ScalarType operator()(ScalarType theta, ScalarType phi) {return ScalarType(0);} }; + +template +class ScalingFactor +{ +private : + + ScalarType k_factor[MAX_BAND][MAX_BAND]; + + static ScalingFactor sf; + + ScalingFactor() + { + for (unsigned l = 0; l < MAX_BAND; ++l) + for (unsigned m = 0; m <= l; ++m) + k_factor[l][m] = Sqrt( ( (2.0*l + 1.0) * Factorial(l-m) ) / (4.0 * M_PI * Factorial(l + m)) ); + } + +public : + static ScalarType K(unsigned l, unsigned m) + { + return sf.k_factor[l][m]; + } +}; + +template +ScalingFactor ScalingFactor::sf; + /** * Although the Real Spherical Harmonic Function is correctly defined over any * positive l and any -l <= m <= l, the two internal functions computing the @@ -50,19 +77,22 @@ template class SphericalHarmonics{ private : - inline static ScalarType scaling_factor(unsigned l, unsigned m) + + static DynamicLegendre legendre; + + static ScalarType scaling_factor(unsigned l, unsigned m) { - return Sqrt( ( (2.0*l + 1.0) * Factorial(l-m) ) / (4.0 * M_PI * Factorial(l + m)) );; + return ScalingFactor::K(l,m); } inline static ScalarType complex_spherical_harmonic_re(unsigned l, unsigned m, ScalarType theta, ScalarType phi) { - return scaling_factor(l, m) * Legendre::AssociatedPolynomial(l, m, Cos(theta), Sin(theta)) * Cos(m * phi); + return scaling_factor(l, m) * legendre.AssociatedPolynomial(l, m, Cos(theta), Sin(theta)) * Cos(m * phi); } inline static ScalarType complex_spherical_harmonic_im(unsigned l, unsigned m, ScalarType theta, ScalarType phi) { - return scaling_factor(l, m) * Legendre::AssociatedPolynomial(l, m, Cos(theta), Sin(theta)) * Sin(m * phi); + return scaling_factor(l, m) * legendre.AssociatedPolynomial(l, m, Cos(theta), Sin(theta)) * Sin(m * phi); } ScalarType coefficients[MAX_BAND * MAX_BAND]; @@ -83,7 +113,7 @@ public : if (m > 0) return SQRT_TWO * complex_spherical_harmonic_re(l, m, theta, phi); - else if (m == 0) return scaling_factor(l, 0) * Legendre::Polynomial(l, Cos(theta)); + else if (m == 0) return scaling_factor(l, 0) * legendre.Polynomial(l, Cos(theta)); else return SQRT_TWO * complex_spherical_harmonic_im(l, -m, theta, phi); } @@ -154,6 +184,9 @@ public : } }; +template +DynamicLegendre SphericalHarmonics::legendre; + }} //namespace vcg::math #endif