Browse Source

Import heat dispersion visualizer

DricomDragon 4 years ago
parent
commit
51491b29f2
2 changed files with 242 additions and 0 deletions
  1. 1 0
      chaleur/Compile.sh
  2. 241 0
      chaleur/chaleur.cpp

+ 1 - 0
chaleur/Compile.sh

@@ -0,0 +1 @@
+g++ chaleur.cpp -l SDL -l SDL_gfx -std=c++11

+ 241 - 0
chaleur/chaleur.cpp

@@ -0,0 +1,241 @@
+# include <iostream>
+# include <vector>
+
+# include <SDL/SDL.h>
+# undef main
+
+# include <SDL/SDL_gfxPrimitives.h>
+
+struct Contact
+{
+	float temp ;
+	Uint32 y ;
+	Uint32 x ;
+};
+
+int main(int argc, char const *argv[])
+{
+	/// [0] Requête des informations
+	std::cout << "LANCEMENT DIFFUSION CHALEUR" << std::endl << std::endl;
+	// [0.1] Dimensions de la fenêtre
+	bool changement(false);
+	Uint32 w_cmd(400), h_cmd(300);
+	float lambda( 0.2495 );
+	unsigned int iteration( 1 );
+	std::cout << "Changer les valeurs par défaut ? (0:non, 1:oui)" << std::endl << ">>>";
+	std::cin >> changement;
+
+	if ( changement )
+	{
+		std::cout << "Hauteur de la fenêtre ?" << std::endl << ">>>";
+		std::cin >> h_cmd;
+		std::cout << "Longueur de la fenêtre ?" << std::endl << ">>>";
+		std::cin >> w_cmd;
+		std::cout << "Conductivité thermique ?" << std::endl << ">>>";
+		std::cin >> lambda;
+		std::cout << "Nombre d'itérations par frame ?" << std::endl << ">>>";
+		std::cin >> iteration;
+	}
+
+	const Uint32 w( w_cmd );
+	const Uint32 h( h_cmd );
+
+	/// [1] SDL
+	// [1.1] Démarrages SDL
+    if ( SDL_Init( SDL_INIT_VIDEO ) < 0)
+    {
+        std::cout << "Impossible d'initialiser la SDL: " << SDL_GetError() << std::endl;
+        return 1;
+    }
+
+    // [1.2] Préparation de fermeture
+    atexit(SDL_Quit);
+
+    // [1.3] Para-fenêtre
+    SDL_WM_SetCaption("Diffusion Chaleur", 0);
+
+    /// [2] Préparation des composants SDL
+    // [2.1] Préparation de la fenêtre
+    SDL_Surface* screen = SDL_SetVideoMode(w, h, 32, SDL_HWSURFACE|SDL_DOUBLEBUF);
+    if ( !screen )
+    {
+        std::cout << "Bug à l'initialisation: " << SDL_GetError() << std::endl;
+        return 1;
+    }
+
+    // [2.2] Préparation variables
+    SDL_Rect mouse({ 400, 200, 0, 0 });
+
+    // [2.3] Préparation surfaces
+
+    // [2.4] Préparation du temps
+    Uint32 frameRate( 60 );
+    Uint32 tprev(0), twait( 1000 / frameRate ), total_frame(0);
+    bool pause( false );
+
+    // [2.5] Préparation des messages
+    std::string msg("Victor");
+
+    /// [3] Préparation de la chaleur
+    // [3.1] Préparation des buffers
+    float buffer[2][h][w]; // entre 0.0f et 1.0f
+    int current_buffer(0), next_buffer(1);
+
+    // [3.2] Liste des conditions aux limites
+    std::vector<Contact> limiteur;
+    bool trigger( false );
+    float temp( 1.0f );
+
+    // [3.3] Conditions initiales
+    for ( int k(0); k < 2; k++ )
+	    for ( Uint32 i(0); i < h; i ++ )
+			for ( Uint32 j(0); j < w; j ++ )
+			{
+				buffer[k][i][j] = 0.0f;
+			}
+
+    /// [4] Boucle principale
+    bool done( false );
+    SDL_Event event;
+    while (!done)
+    {
+        // [4.1] Gestion évènements
+        while (SDL_PollEvent(&event))
+        {
+            switch (event.type)
+            {
+            case SDL_QUIT:
+                done = true;
+                break;
+            case SDL_KEYDOWN:
+                switch( event.key.keysym.sym )
+                {
+                case SDLK_ESCAPE :
+                    done = true;
+                    break;
+                case SDLK_BACKSPACE :
+                    std::cout << std::endl << "Destruction des points de contact." << std::endl << std::endl;
+                    limiteur.clear();
+                    break;
+                case SDLK_SPACE :
+                	std::cout << std::endl << "Reinscription du cas initial." << std::endl << std::endl;
+                    for ( Uint32 i(0); i < h; i ++ )
+						for ( Uint32 j(0); j < w; j ++ )
+						{
+							buffer[current_buffer][i][j] = 0.0f;
+						};
+                    break;
+                case SDLK_a :
+                	temp = 1.0f ;
+                    break;
+                case SDLK_z :
+                	temp = 0.5f ;
+                    break;
+                case SDLK_e :
+                	temp = 0.0f ;
+                    break;
+                }
+                break;
+            case SDL_KEYUP:
+                switch( event.key.keysym.sym )
+                {
+                case SDLK_LEFT :
+                case SDLK_RIGHT :
+                case SDLK_DOWN :
+                    break;
+                }
+                break;
+            case SDL_MOUSEMOTION:
+                mouse.x = event.motion.x ;
+                mouse.y = event.motion.y ;
+
+                if ( trigger )
+                	limiteur.push_back( { temp, mouse.y, mouse.x } );
+                break;
+            case SDL_MOUSEBUTTONDOWN:
+                trigger = true ;
+                break;
+            case SDL_MOUSEBUTTONUP:
+                trigger = false ;
+                break;
+            } // end switch event type
+        } // end of message processing
+
+        // [4.2] Calculs
+        if ( !pause )
+        {
+        	for ( unsigned int c(0); c < iteration ; c++ )
+        	{
+	        	// Conditions initiales
+	        	for ( unsigned int k(0); k < limiteur.size(); k++ )
+	        		buffer[current_buffer][ limiteur[k].y ][ limiteur[k].x ] = limiteur[k].temp ;
+
+	        	// Calcul
+				for ( Uint32 i(1); i < h - 1; i ++ )
+					for ( Uint32 j(1); j < w - 1; j ++ )
+					{
+						buffer[next_buffer][i][j] = lambda * buffer[current_buffer][i + 1][j]
+													+ lambda * buffer[current_buffer][i][j + 1]
+													+ lambda * buffer[current_buffer][i - 1][j]
+													+ lambda * buffer[current_buffer][i][j - 1]
+													+ (1.0f - 4.0f * lambda ) * buffer[current_buffer][i][j] ;
+
+						if ( buffer[current_buffer][i][j] > 1.0f )
+							buffer[current_buffer][i][j] = 1.0f ;
+
+						else if ( buffer[current_buffer][i][j] < 0.0f )
+							buffer[current_buffer][i][j] = 0.0f ;
+					}
+
+
+	        	// Changement de buffer
+	        	current_buffer = next_buffer ;
+	        	next_buffer = 1 - current_buffer ;
+        	}
+        }
+
+        // [4.3] Affichage
+        if ( !pause )
+        {
+        	// Calcul
+			for ( Uint32 i(1); i < h - 1; i ++ )
+				for ( Uint32 j(1); j < w - 1; j ++ )
+					pixelRGBA( screen, j, i, (Uint8)( buffer[current_buffer][i][j] * 255 ), 0, 0, 255 );
+        }
+
+        SDL_Flip(screen);
+
+        // [4.4] Temps
+        total_frame ++;
+        while( SDL_GetTicks() - tprev < twait )
+        {
+        	if ( SDL_GetTicks() - tprev < twait/2 )
+        		SDL_Delay( twait/3 );
+        }
+        tprev = SDL_GetTicks();
+
+    } //fin bcl principale
+
+    ///[5] Destruction des composants
+    SDL_FreeSurface( screen );
+
+    ///[6] Affichage puissance de calcul
+    std::cout << "Performances : " << std::endl;
+    std::cout << "> Nombre de pixels : " << w*h << std::endl;
+    std::cout << "> Nombre total d'images : " << total_frame << std::endl;
+    std::cout << "> Temps total : " << SDL_GetTicks() << "ms." << std::endl;
+    std::cout << "> Moyenne par frame : " << (float)SDL_GetTicks() / total_frame << std::endl;
+    std::cout << "> Moyenne par frame et par pixel : " << (float)SDL_GetTicks() / total_frame / w / h << std::endl;
+
+    ///[7] Tableau
+    /*for ( Uint32 i(1); i < h - 1; i ++ )
+    {
+    	for ( Uint32 j(1); j < w - 1; j ++ )
+		{
+			std::cout << (int)(buffer[next_buffer][i][j] * 255) << ":";
+		}
+		std::cout << std::endl;
+    }*/
+
+	return 0;
+}