1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
| template <typename T, typename U> class Terrain
{
//type T : type des valeurs traitées dans la matrice
//type U : type utilisé pour le deltaT
protected:
unsigned int Width; //Largeur du terrain
unsigned int Height; //Hauteur du terrain
unsigned int Size; //Taille du terrain = Width*Height
std::vector<T> Surface; //Surface sur laquel est simulée la diffision
U CoefficientDeDiffusion;
U CoefficientDEvaporation;
T Threshold; //Seuil en dessous duquel on considère que la valeur est nulle
T Zéro; //Le zéro du type T
public:
Terrain ( const unsigned int largeur, const unsigned int hauteur );
~Terrain ();
unsigned int GetWidth ();
unsigned int GetHeight ();
void SetCoefficientDeDiffusion ( U coeffDiff );
U GetCoefficientDeDiffusion () ;
void SetCoefficientDEvaporation ( U coeffEvap );
U GetCoefficientDEvaporation ();
void SetThreshold ( T seuil );
T GetThreshold ();
unsigned int GetX ( unsigned int index );
unsigned int GetY ( unsigned int index );
void SetValue ( unsigned int posX, unsigned int posY, T valeur );
T GetValue ( unsigned int posX, unsigned int posY );
void Reset ();
void affiche () const; //Affichage en mode console
void affiche ( unsigned char* image, int tailleLigne ); //Affichage dans bitmap
void Diffuse ( U dT );
};
template <typename T, typename U> void Terrain<T,U>::Diffuse ( U dT )
{
//Matrices utilisées pour le calcul
std::vector<T> gain ( Size, Zéro );//Matrice des gains de chaques cases
std::vector<T> perte ( Size, Zéro );//Matrice des pertes de chaques cases
//Variables de la boucle de calcul principale ( Calcul des matrices 'gain' et 'perte' )
T fluxHaut, fluxBas, fluxDroite, fluxGauche, fluxEvap;
unsigned int index; //Index de la case voisine ( Haute, Basse, Gauche ou Droite )
T delta;
T valeurCourante;
//Précalcul de valeurs constantes à cette fonction
const T coeffDiffDeltaT = static_cast<T> ( CoefficientDeDiffusion * dT );
const T coeffEvapDeltaT = static_cast<T> ( CoefficientDEvaporation * dT );
//Calcul des matrices 'gain' et 'perte'
for ( unsigned int indexCourant = 0; indexCourant < Size; indexCourant++ )
{
//Initialisation
valeurCourante = Surface[ indexCourant ];
if ( valeurCourante != Zéro ) //Si la valeur courante est non nulle on calcule sinon on passe le tour
{
//Initialisation des variables de la boucle
fluxHaut = Zéro; fluxBas = Zéro; fluxGauche = Zéro; fluxDroite = Zéro; fluxEvap = Zéro;
//Traitement du pixel Haut :
if ( indexCourant >= Width ) //Si on est pas à la première ligne :
{
index = indexCourant - Width;
delta = valeurCourante - Surface [ index ];
if ( delta > Zéro )
{
fluxHaut = coeffDiffDeltaT * delta;
gain [ index ] += fluxHaut;
}
}
//Traitement du pixel Bas :
if ( ( indexCourant / Width ) < ( Height - 1 ) )//Si on est pas à la dernière ligne :
{
index = indexCourant + Width;
delta = valeurCourante - Surface [ index ];
if ( delta > Zéro )
{
fluxBas = coeffDiffDeltaT * delta;
gain[ index ] += fluxBas;
}
}
//Traitement du pixel Gauche :
if ( indexCourant % Width ) //Si on est pas à la première colonne :
{
index = indexCourant - 1;
delta = valeurCourante - Surface [ index ];
if ( delta > Zéro )
{
fluxGauche = coeffDiffDeltaT * delta;
gain[ index ] += fluxGauche;
}
}
//Traitement du pixel Droite :
if ( ( indexCourant % Width ) < ( Width - 1 ) )//Si on est pas à la dernière colonne :
{
index = indexCourant + 1;
delta = valeurCourante - Surface [ index ];
if ( delta > Zéro )
{
fluxDroite = coeffDiffDeltaT * delta;
gain[ index ] += fluxDroite;
}
}
fluxEvap = coeffEvapDeltaT * valeurCourante;
perte[ indexCourant ] = fluxHaut + fluxBas + fluxDroite + fluxGauche + fluxEvap;
}
}
//Synthèse des trois matrices : Surface, gain et perte
for ( unsigned int indexCourant = 0; indexCourant < Size; indexCourant++ )
Surface[ indexCourant ] += gain[ indexCourant ] - perte[ indexCourant ];
//On annule les pixels de trop faible valeur
if ( Threshold != 0 )
for ( unsigned int indexCourant = 0; indexCourant < Size; indexCourant++ )
if ( Surface [ indexCourant ] < Threshold )
Surface [ indexCourant ] = Zéro;
} |
Partager