//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: Functions for spherical geometry. // // $NoKeywords: $ // //=============================================================================// #ifndef SPHERICAL_GEOMETRY_H #define SPHERICAL_GEOMETRY_H #ifdef _WIN32 #pragma once #endif #include #include // see http://mathworld.wolfram.com/SphericalTrigonometry.html // return the spherical distance, in radians, between 2 points on the unit sphere. FORCEINLINE float UnitSphereLineSegmentLength( Vector const &a, Vector const &b ) { // check unit length Assert( fabs( VectorLength( a ) - 1.0 ) < 1.0e-3 ); Assert( fabs( VectorLength( b ) - 1.0 ) < 1.0e-3 ); return acos( DotProduct( a, b ) ); } // given 3 points on the unit sphere, return the spherical area (in radians) of the triangle they form. // valid for "small" triangles. FORCEINLINE float UnitSphereTriangleArea( Vector const &a, Vector const &b , Vector const &c ) { float flLengthA = UnitSphereLineSegmentLength( b, c ); float flLengthB = UnitSphereLineSegmentLength( c, a ); float flLengthC = UnitSphereLineSegmentLength( a, b ); if ( ( flLengthA == 0. ) || ( flLengthB == 0. ) || ( flLengthC == 0. ) ) return 0.; // zero area triangle // now, find the 3 incribed angles for the triangle float flHalfSumLens = 0.5 * ( flLengthA + flLengthB + flLengthC ); float flSinSums = sin( flHalfSumLens ); float flSinSMinusA= sin( flHalfSumLens - flLengthA ); float flSinSMinusB= sin( flHalfSumLens - flLengthB ); float flSinSMinusC= sin( flHalfSumLens - flLengthC ); float flTanAOver2 = sqrt ( ( flSinSMinusB * flSinSMinusC ) / ( flSinSums * flSinSMinusA ) ); float flTanBOver2 = sqrt ( ( flSinSMinusA * flSinSMinusC ) / ( flSinSums * flSinSMinusB ) ); float flTanCOver2 = sqrt ( ( flSinSMinusA * flSinSMinusB ) / ( flSinSums * flSinSMinusC ) ); // Girards formula : area = sum of angles - pi. return 2.0 * ( atan( flTanAOver2 ) + atan( flTanBOver2 ) + atan( flTanCOver2 ) ) - M_PI; } // spherical harmonics-related functions. Best explanation at http://www.research.scea.com/gdc2003/spherical-harmonic-lighting.pdf // Evaluate associated legendre polynomial P( l, m ) at flX, using recurrence relation float AssociatedLegendrePolynomial( int nL, int nM, float flX ); // Evaluate order N spherical harmonic with spherical coordinates // nL = band, 0..N // nM = -nL .. nL // theta = 0..M_PI // phi = 0.. 2 * M_PHI float SphericalHarmonic( int nL, int nM, float flTheta, float flPhi ); // evaluate spherical harmonic with normalized vector direction float SphericalHarmonic( int nL, int nM, Vector const &vecDirection ); #endif // SPHERICAL_GEOMETRY_H