sphericalHarmonics.h 4.51 KB
Newer Older
1 2 3 4 5 6 7
/*
 * spericalHarmonics.h
 *
 *  Created on: Oct 2, 2013
 *      Author: sauvage
 */

8 9
#ifndef __SPHERICALHARMONICS_H__
#define __SPHERICALHARMONICS_H__
10

11 12 13
#include <cassert>
#include <cmath>
#include <iostream>
14 15 16 17 18

#include <Eigen/Core>
#include <Eigen/Dense>
#include <Eigen/Cholesky>

19 20
namespace CGoGN
{
21

22 23 24 25 26 27
namespace Utils
{

template <typename Tscalar, typename Tcoef>
class SphericalHarmonics
{
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
private :
	static const int max_resolution = 10 ;                   // max possible resolution for any object of that class
	static int resolution ;                                  // actual resolution level
	static int nb_coefs ;                                    // number of coefs = (resolution + 1) * (resolution + 1)
	static unsigned long cpt_instances;                      // number of instances of the class
	static Tscalar K_tab [(max_resolution+1)*(max_resolution+1)];   // table containing constants K
	static Tscalar F_tab [(max_resolution+1)*(max_resolution+1)];   // table for computing the functions : P or Y or y

	Tcoef* coefs;                                            // table of coefficients

public :
	// construction, destruction and initialization
	SphericalHarmonics();
	SphericalHarmonics(SphericalHarmonics const &);
	~SphericalHarmonics();

	static void set_level(int res_level);
	static void set_nb_coefs (int nb_coefs);
46 47
	static int get_resolution () { return resolution; }
	static int get_nb_coefs () { return nb_coefs; }
48 49 50 51 52

	// evaluation

	static void set_eval_direction (Tscalar theta, Tscalar phi) ;       // fix the direction in which the SH has to be evaluated
	static void set_eval_direction (Tscalar x, Tscalar y, Tscalar z) ;  // fix the direction in which the SH has to be evaluated
53
	Tcoef evaluate () const;				  						    // evaluates at a fixed direction
54

55 56
	Tcoef evaluate_at (Tscalar theta, Tscalar phi) const;               // eval spherical coordinates
	Tcoef evaluate_at (Tscalar x, Tscalar y, Tscalar z) const;          // eval cartesian coordinates
57 58

	// I/O
59 60
	const Tcoef& get_coef (int l, int m) const {assert ((l>=0 && l <=resolution) || !" maybe you forgot to call set_level()"); assert (m >= (-l) && m <= l); return get_coef(index(l,m));}
	Tcoef& get_coef (int l, int m) {assert ((l>=0 && l <=resolution) || !" maybe you forgot to call set_level()"); assert (m >= (-l) && m <= l); return get_coef(index(l,m));}
61 62 63
	template <typename TS,typename TC> friend std::ostream & operator<< (std::ostream & os, const SphericalHarmonics<TS,TC> & sh);

	// operators
64 65 66 67 68 69 70 71 72 73 74
	void operator= (const SphericalHarmonics<Tscalar,Tcoef>&);
	void operator+= (const SphericalHarmonics<Tscalar,Tcoef>&);
	SphericalHarmonics<Tscalar,Tcoef> operator+ (const SphericalHarmonics<Tscalar,Tcoef>&) const;
	void operator-= (const SphericalHarmonics<Tscalar,Tcoef> &);
	SphericalHarmonics<Tscalar,Tcoef> operator- (const SphericalHarmonics<Tscalar,Tcoef>&) const;
	void operator*= (Tscalar);
	SphericalHarmonics<Tscalar,Tcoef> operator* (Tscalar) const;
	void operator/= (Tscalar);
	SphericalHarmonics<Tscalar,Tcoef> operator/ (Tscalar) const;

	std::string CGoGNnameOfType() const { return "SphericalHarmonics"; }
75 76 77 78 79 80 81 82 83

//	static void copy_K_tab (Tscalar tab[]) ; // obsolete, was used for shaders

	// fitting
	template <typename Tdirection, typename Tchannel>
	void fit_to_data(int n, Tdirection* t_theta, Tdirection* t_phi, Tchannel* t_R, Tchannel* t_G, Tchannel* t_B, double lambda);
	template <typename Tdirection, typename Tchannel>
	void fit_to_data(int n, Tdirection* t_x, Tdirection* t_y, Tdirection* t_z, Tchannel* t_R, Tchannel* t_G, Tchannel* t_B, double lambda);

84
private :
85 86 87 88 89 90 91
	static int index (int l, int m) {return l*(l+1)+m;}

	// evaluation :
	static void init_K_tab (); // compute the normalization constants K_l^m and store them into K_tab
	static void compute_P_tab (Tscalar t); // Compute Legendre Polynomials at parameter t and store them in F_tab (only for m>=0)
	static void compute_y_tab (Tscalar phi); // Compute the real basis functions y_l^m at (theta, phi) and store them in F_tab (compute_P_tab must have been called before)

92 93
	const Tcoef& get_coef (int i) const {assert ((i>=0 && i<nb_coefs ) || !" maybe you forgot to call set_level()"); return coefs[i];}
	Tcoef& get_coef (int i) {assert ((i>=0 && i<nb_coefs ) || !" maybe you forgot to call set_level()"); return coefs[i];}
94 95 96 97 98 99

	// fitting
	template <typename Tchannel>
	void fit_to_data(int n, Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic>& mM, Tchannel* t_R, Tchannel* t_G, Tchannel* t_B, double lambda);
};

100 101 102
} // namespace Utils

} // namespace CGoGN
103

104
#include "Utils/sphericalHarmonics.hpp"
105

106
#endif /* __SPHERICALHARMONICS_H__ */