LightRays/LightRays/Source.h
2020-03-04 23:14:44 +01:00

168 lines
6.5 KiB
C++

/*******************************************************************************
* Classe de base des sources. Divers types de sources.
*******************************************************************************/
#ifndef _LIGHTRAYS_SOURCE_H_
#define _LIGHTRAYS_SOURCE_H_
#include "Rayon.h"
#include <vector>
#include <SFML/Graphics/RenderWindow.hpp>
//------------------------------------------------------------------------------
// Classe de base, abstraite, des sources. À priori, seulement définie par
// son spectre.
class Source {
public:
Specte spectre; // spectre de la source en intensité
// source de spectre arbitraire
Source (Specte spectre) : spectre(spectre) {}
// source monochromatique polarisée
Source (color_id_t couleur, float I, pola_t pol) : spectre( Specte::monochromatique(I, couleur, pol) ) {}
// source monochromatique non-polarisée
Source (color_id_t couleur, float I) : spectre( Specte::monochromatique(I, couleur) ) {};
Source& operator= (const Source&) = default;
Source (const Source&) = default;
virtual ~Source () {}
// génération des rayons
virtual std::vector<Rayon> genere_rayons () = 0;
// dessin de la source
virtual void dessiner (sf::RenderWindow& window) const = 0;
};
//------------------------------------------------------------------------------
// Source émettant un unique rayon à partir du point `position` et à un angle
// `dir_angle` à l'horizontale. "Rayon laser".
class Source_UniqueRayon : public Source {
public:
point_t position;
float dir_angle;
// relai aux constructeurs de `Source`
template<typename... Args> Source_UniqueRayon (point_t pos, float dir, Args&&... x) :
Source(x...), position(pos), dir_angle(dir) {}
Source_UniqueRayon& operator= (const Source_UniqueRayon&) = default;
Source_UniqueRayon (const Source_UniqueRayon&) = default;
virtual ~Source_UniqueRayon () {}
// création de l'unique rayon
virtual std::vector<Rayon> genere_rayons () override;
void dessiner (sf::RenderWindow& window) const override;
};
//------------------------------------------------------------------------------
// Source étendue émettant un plusieurs rayon distribués sur une ligne et à un
// angle fixe. Peut être vu comme une source ponctuelle à l'infini, ou un
// ensemble de `Source_UniqueRayon`.
class Source_LinParallels : public Source {
public:
point_t a; // point A du segment
vec_t vec; // vecteur AB du segment
float dens_lin; // nombre de rayons par unité de longueur
float dir_angle_rel; // angle par rapport au vecteur AB
template<typename... Args> Source_LinParallels (point_t pos_seg_a, point_t pos_seg_b, float dir_angle, Args&&... x) :
Source(x...), a(pos_seg_a), vec(pos_seg_b-pos_seg_a), dens_lin(100), dir_angle_rel(dir_angle) {}
template<typename... Args> Source_LinParallels (point_t pos_seg_a, vec_t pos_ab_vecteur, float dir_angle, Args&&... x) :
Source(x...), a(pos_seg_a), vec(pos_ab_vecteur), dens_lin(100), dir_angle_rel(dir_angle) {}
Source_LinParallels& operator= (const Source_LinParallels&) = default;
Source_LinParallels (const Source_LinParallels&) = default;
virtual ~Source_LinParallels () {}
virtual std::vector<Rayon> genere_rayons () override;
void dessiner (sf::RenderWindow& window) const override;
};
//------------------------------------------------------------------------------
// Classe de base virtuelle des sources omnidirectionnelle
// (ou restreinte à un secteur angulaire `secteur`) à directivité arbitraire.
class Source_Omni : public Source {
public:
point_t position; // position de la source
float dens_ang; // nombre de rayons pour 2π
bool dir_alea; // émission dans des directions aléatoires ou équiréparties/déterministe
std::function< float(float theta) > directivite; // directivité (normalisée à 1)
const static decltype(directivite) directivite_unif; // directivité unirforme
std::optional<angle_interv_t> secteur; // secteur angulaire d'émission
template<typename... Args> Source_Omni (point_t pos, Args&&... x) :
Source(x...), position(pos), dens_ang(100), dir_alea(true), directivite(directivite_unif) {}
Source_Omni& operator= (const Source_Omni&) = default;
Source_Omni (const Source_Omni&) = default;
virtual ~Source_Omni () {}
};
//------------------------------------------------------------------------------
// Source ponctuelle omnidirectionnelle (ou restreinte à un secteur angulaire)
class Source_PonctOmni : public Source_Omni {
public:
virtual std::vector<Rayon> genere_rayons () override;
void dessiner (sf::RenderWindow& window) const override;
template<typename... Args> Source_PonctOmni (point_t pos, Args&&... x) : Source_Omni(pos, x...) {}
virtual ~Source_PonctOmni () {}
};
//------------------------------------------------------------------------------
// Source étendue en secteur de disque ("projecteur") avec une émission
// lambertienne à chaque point de sa surface (loi en cosinus). Si R très petit,
// équivalent à Source_PonctOmni.
class Source_SecteurDisqueLambertien : public Source_Omni {
public:
float R;
angle_interv_t ang;
template<typename... Args> Source_SecteurDisqueLambertien (float radius, angle_interv_t ang_interval, Args&&... x) :
Source_Omni(x...), R(radius), ang(ang_interval) {}
Source_SecteurDisqueLambertien& operator= (const Source_SecteurDisqueLambertien&) = default;
Source_SecteurDisqueLambertien (const Source_SecteurDisqueLambertien&) = default;
virtual ~Source_SecteurDisqueLambertien () {}
virtual std::vector<Rayon> genere_rayons () override;
void dessiner (sf::RenderWindow& window) const override;
};
//------------------------------------------------------------------------------
// Source étendue linéaire ("écran lumineux") avec une émission lambertienne
// à chaque point de sa surface (loi en cosinus), et d'un seul côté du segment.
class Source_LinLambertien : public Source {
public:
point_t a;
vec_t vec;
float dens_lin;
template<typename... Args> Source_LinLambertien (point_t pos_seg_a, point_t pos_seg_b, Args&&... x) :
Source(x...), a(pos_seg_a), vec(pos_seg_b-pos_seg_a), dens_lin(100) {}
template<typename... Args> Source_LinLambertien (point_t pos_seg_a, vec_t pos_ab_vecteur, Args&&... x) :
Source(x...), a(pos_seg_a), vec(pos_ab_vecteur), dens_lin(100) {}
Source_LinLambertien& operator= (const Source_LinLambertien&) = default;
Source_LinLambertien (const Source_LinLambertien&) = default;
virtual ~Source_LinLambertien () {}
virtual std::vector<Rayon> genere_rayons () override;
void dessiner (sf::RenderWindow& window) const override;
};
#endif