chaleur.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. # include <iostream>
  2. # include <vector>
  3. # include <SDL/SDL.h>
  4. # undef main
  5. # include <SDL/SDL_gfxPrimitives.h>
  6. struct Contact
  7. {
  8. float temp ;
  9. Uint32 y ;
  10. Uint32 x ;
  11. };
  12. int main(int argc, char const *argv[])
  13. {
  14. /// [0] Requête des informations
  15. std::cout << "LANCEMENT DIFFUSION CHALEUR" << std::endl << std::endl;
  16. // [0.1] Dimensions de la fenêtre
  17. bool changement(false);
  18. Uint32 w_cmd(400), h_cmd(300);
  19. float lambda( 0.2495 );
  20. unsigned int iteration( 1 );
  21. std::cout << "Changer les valeurs par défaut ? (0:non, 1:oui)" << std::endl << ">>>";
  22. std::cin >> changement;
  23. if ( changement )
  24. {
  25. std::cout << "Hauteur de la fenêtre ?" << std::endl << ">>>";
  26. std::cin >> h_cmd;
  27. std::cout << "Longueur de la fenêtre ?" << std::endl << ">>>";
  28. std::cin >> w_cmd;
  29. std::cout << "Conductivité thermique ?" << std::endl << ">>>";
  30. std::cin >> lambda;
  31. std::cout << "Nombre d'itérations par frame ?" << std::endl << ">>>";
  32. std::cin >> iteration;
  33. }
  34. const Uint32 w( w_cmd );
  35. const Uint32 h( h_cmd );
  36. /// [1] SDL
  37. // [1.1] Démarrages SDL
  38. if ( SDL_Init( SDL_INIT_VIDEO ) < 0)
  39. {
  40. std::cout << "Impossible d'initialiser la SDL: " << SDL_GetError() << std::endl;
  41. return 1;
  42. }
  43. // [1.2] Préparation de fermeture
  44. atexit(SDL_Quit);
  45. // [1.3] Para-fenêtre
  46. SDL_WM_SetCaption("Diffusion Chaleur", 0);
  47. /// [2] Préparation des composants SDL
  48. // [2.1] Préparation de la fenêtre
  49. SDL_Surface* screen = SDL_SetVideoMode(w, h, 32, SDL_HWSURFACE|SDL_DOUBLEBUF);
  50. if ( !screen )
  51. {
  52. std::cout << "Bug à l'initialisation: " << SDL_GetError() << std::endl;
  53. return 1;
  54. }
  55. // [2.2] Préparation variables
  56. SDL_Rect mouse({ 400, 200, 0, 0 });
  57. // [2.3] Préparation surfaces
  58. // [2.4] Préparation du temps
  59. Uint32 frameRate( 60 );
  60. Uint32 tprev(0), twait( 1000 / frameRate ), total_frame(0);
  61. bool pause( false );
  62. // [2.5] Préparation des messages
  63. std::string msg("Victor");
  64. /// [3] Préparation de la chaleur
  65. // [3.1] Préparation des buffers
  66. float buffer[2][h][w]; // entre 0.0f et 1.0f
  67. int current_buffer(0), next_buffer(1);
  68. // [3.2] Liste des conditions aux limites
  69. std::vector<Contact> limiteur;
  70. bool trigger( false );
  71. float temp( 1.0f );
  72. // [3.3] Conditions initiales
  73. for ( int k(0); k < 2; k++ )
  74. for ( Uint32 i(0); i < h; i ++ )
  75. for ( Uint32 j(0); j < w; j ++ )
  76. {
  77. buffer[k][i][j] = 0.0f;
  78. }
  79. /// [4] Boucle principale
  80. bool done( false );
  81. SDL_Event event;
  82. while (!done)
  83. {
  84. // [4.1] Gestion évènements
  85. while (SDL_PollEvent(&event))
  86. {
  87. switch (event.type)
  88. {
  89. case SDL_QUIT:
  90. done = true;
  91. break;
  92. case SDL_KEYDOWN:
  93. switch( event.key.keysym.sym )
  94. {
  95. case SDLK_ESCAPE :
  96. done = true;
  97. break;
  98. case SDLK_BACKSPACE :
  99. std::cout << std::endl << "Destruction des points de contact." << std::endl << std::endl;
  100. limiteur.clear();
  101. break;
  102. case SDLK_SPACE :
  103. std::cout << std::endl << "Reinscription du cas initial." << std::endl << std::endl;
  104. for ( Uint32 i(0); i < h; i ++ )
  105. for ( Uint32 j(0); j < w; j ++ )
  106. {
  107. buffer[current_buffer][i][j] = 0.0f;
  108. };
  109. break;
  110. case SDLK_a :
  111. temp = 1.0f ;
  112. break;
  113. case SDLK_z :
  114. temp = 0.5f ;
  115. break;
  116. case SDLK_e :
  117. temp = 0.0f ;
  118. break;
  119. }
  120. break;
  121. case SDL_KEYUP:
  122. switch( event.key.keysym.sym )
  123. {
  124. case SDLK_LEFT :
  125. case SDLK_RIGHT :
  126. case SDLK_DOWN :
  127. break;
  128. }
  129. break;
  130. case SDL_MOUSEMOTION:
  131. mouse.x = event.motion.x ;
  132. mouse.y = event.motion.y ;
  133. if ( trigger )
  134. limiteur.push_back( { temp, mouse.y, mouse.x } );
  135. break;
  136. case SDL_MOUSEBUTTONDOWN:
  137. trigger = true ;
  138. break;
  139. case SDL_MOUSEBUTTONUP:
  140. trigger = false ;
  141. break;
  142. } // end switch event type
  143. } // end of message processing
  144. // [4.2] Calculs
  145. if ( !pause )
  146. {
  147. for ( unsigned int c(0); c < iteration ; c++ )
  148. {
  149. // Conditions initiales
  150. for ( unsigned int k(0); k < limiteur.size(); k++ )
  151. buffer[current_buffer][ limiteur[k].y ][ limiteur[k].x ] = limiteur[k].temp ;
  152. // Calcul
  153. for ( Uint32 i(1); i < h - 1; i ++ )
  154. for ( Uint32 j(1); j < w - 1; j ++ )
  155. {
  156. buffer[next_buffer][i][j] = lambda * buffer[current_buffer][i + 1][j]
  157. + lambda * buffer[current_buffer][i][j + 1]
  158. + lambda * buffer[current_buffer][i - 1][j]
  159. + lambda * buffer[current_buffer][i][j - 1]
  160. + (1.0f - 4.0f * lambda ) * buffer[current_buffer][i][j] ;
  161. if ( buffer[current_buffer][i][j] > 1.0f )
  162. buffer[current_buffer][i][j] = 1.0f ;
  163. else if ( buffer[current_buffer][i][j] < 0.0f )
  164. buffer[current_buffer][i][j] = 0.0f ;
  165. }
  166. // Changement de buffer
  167. current_buffer = next_buffer ;
  168. next_buffer = 1 - current_buffer ;
  169. }
  170. }
  171. // [4.3] Affichage
  172. if ( !pause )
  173. {
  174. // Calcul
  175. for ( Uint32 i(1); i < h - 1; i ++ )
  176. for ( Uint32 j(1); j < w - 1; j ++ )
  177. pixelRGBA( screen, j, i, (Uint8)( buffer[current_buffer][i][j] * 255 ), 0, 0, 255 );
  178. }
  179. SDL_Flip(screen);
  180. // [4.4] Temps
  181. total_frame ++;
  182. while( SDL_GetTicks() - tprev < twait )
  183. {
  184. if ( SDL_GetTicks() - tprev < twait/2 )
  185. SDL_Delay( twait/3 );
  186. }
  187. tprev = SDL_GetTicks();
  188. } //fin bcl principale
  189. ///[5] Destruction des composants
  190. SDL_FreeSurface( screen );
  191. ///[6] Affichage puissance de calcul
  192. std::cout << "Performances : " << std::endl;
  193. std::cout << "> Nombre de pixels : " << w*h << std::endl;
  194. std::cout << "> Nombre total d'images : " << total_frame << std::endl;
  195. std::cout << "> Temps total : " << SDL_GetTicks() << "ms." << std::endl;
  196. std::cout << "> Moyenne par frame : " << (float)SDL_GetTicks() / total_frame << std::endl;
  197. std::cout << "> Moyenne par frame et par pixel : " << (float)SDL_GetTicks() / total_frame / w / h << std::endl;
  198. ///[7] Tableau
  199. /*for ( Uint32 i(1); i < h - 1; i ++ )
  200. {
  201. for ( Uint32 j(1); j < w - 1; j ++ )
  202. {
  203. std::cout << (int)(buffer[next_buffer][i][j] * 255) << ":";
  204. }
  205. std::cout << std::endl;
  206. }*/
  207. return 0;
  208. }