|
@@ -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;
|
|
|
+}
|