main.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. #include <unistd.h>
  2. #include <stdint.h>
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <omp.h>
  6. #include <time.h>
  7. #include <math.h>
  8. #ifndef M_PI
  9. #define M_PI 3.14
  10. #endif
  11. #include "SDL2/SDL.h"
  12. #include <SDL2/SDL_image.h>
  13. #include <SDL2/SDL_timer.h>
  14. #include "particles.h"
  15. #include "terrain.h"
  16. #define ARG_POP 1
  17. #define ARG_W 2
  18. #define ARG_H 3
  19. #define ARG_V 4
  20. #define ARG_INCREASE 5
  21. #define ARG_DECAY 6
  22. #define ARG_SAMPLING_D 7
  23. #define ARG_SAMPLING_A 8
  24. #define ARG_STEERING 9
  25. Uint8 clamp_Uint8(float x){
  26. if(x >= 255.0f)
  27. return 255;
  28. if(x <= 0.0f)
  29. return 0;
  30. return (Uint8) x;
  31. }
  32. int main(int argc, char *argv[]){
  33. if(argc < 5){
  34. fprintf(stderr, "./particles [n_particles] [width] [height] [speed]\n");
  35. return -1;
  36. }
  37. size_t n_particules;
  38. size_t width;
  39. size_t height;
  40. coord_t speed;
  41. float increase;
  42. float decay;
  43. coord_t sampling_distance;
  44. coord_t sampling_angle;
  45. coord_t steering_angle;
  46. size_t surface;
  47. particle_t *particles;
  48. terrain_t *terrain;
  49. n_particules = strtol(argv[ARG_POP], NULL, 0);
  50. width = strtol(argv[ARG_W], NULL, 0);
  51. height = strtol(argv[ARG_H], NULL, 0);
  52. speed = strtod(argv[ARG_V], NULL);
  53. increase = strtof(argv[ARG_INCREASE], NULL);
  54. decay = strtof(argv[ARG_DECAY], NULL);
  55. sampling_angle = strtof(argv[ARG_SAMPLING_A], NULL);
  56. sampling_distance = strtof(argv[ARG_SAMPLING_D], NULL);
  57. steering_angle = strtof(argv[ARG_STEERING], NULL);
  58. surface = width*height;
  59. particles = (particle_t *) malloc(n_particules * sizeof(particle_t));
  60. terrain = (terrain_t *) malloc(surface * sizeof(terrain_t));
  61. srand(time(NULL));
  62. float average_pop = (float)n_particules / (float)surface;
  63. float average_pheromone = (float)n_particules * (float)(increase) / (float)surface;
  64. /* Intialization */
  65. for(size_t i = 0 ; i < height ; ++i){
  66. for(size_t j = 0 ; j < width ; ++j){
  67. float d_i = (float)(2.0f * i - height)/(float)height;
  68. float d_j = (float)(2.0f * j - width)/(float)width;
  69. float d_center = sqrt((d_i * d_i + d_j * d_j) / 2.0f);
  70. terrain[i * width + j].pheromone = 0;
  71. // terrain[i * width + j].decay = decay * (5 - d_center + (float) rand() / (float)(RAND_MAX)) / 7.0f;
  72. terrain[i * width + j].decay = decay * (5 + 2 * (float) rand() / (float)(RAND_MAX)) / 7.0f;
  73. }
  74. }
  75. for(size_t n = 0 ; n < n_particules ; ++n){
  76. particles[n].pos.x = width * (float)(rand())/(float)(RAND_MAX);
  77. particles[n].pos.y = height * (float)(rand())/(float)(RAND_MAX);
  78. if(particles[n].pos.x == width)
  79. particles[n].pos.x = 0;
  80. if(particles[n].pos.y == height)
  81. particles[n].pos.y = 0;
  82. coord_t angle = 2 * M_PI * (float)(rand())/(float)(RAND_MAX);
  83. particles[n].dir.x = cosf(angle);
  84. particles[n].dir.y = sinf(angle);
  85. }
  86. if (SDL_Init(SDL_INIT_VIDEO) != 0) {
  87. printf("error initializing SDL: %s\n", SDL_GetError());
  88. }
  89. SDL_Window* win;
  90. SDL_Renderer* renderer;
  91. Uint64 time_last;
  92. Uint64 time_now;
  93. coord_t time_delta;
  94. SDL_CreateWindowAndRenderer(width, height, 0, &win, &renderer);
  95. SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
  96. SDL_RenderClear(renderer);
  97. time_now = SDL_GetTicks64();
  98. int close = 0;
  99. while(!close){
  100. SDL_Event event;
  101. // Events management
  102. while (SDL_PollEvent(&event)) {
  103. if(event.type == SDL_QUIT) {
  104. close = 1;
  105. break;
  106. }
  107. }
  108. time_last = time_now;
  109. time_now = SDL_GetTicks64();
  110. time_delta = (time_now - time_last) / 1000.0f;
  111. // Clear pop count in world
  112. for(size_t k = 0 ; k < surface ; ++k){
  113. terrain[k].pop = 0;
  114. terrain[k].increase = 0;
  115. }
  116. // Update particles
  117. for(size_t n = 0 ; n < n_particules ; ++n){
  118. particle_update(&particles[n], terrain, time_delta , speed, width, height, sampling_distance, sampling_angle, steering_angle);
  119. }
  120. for(size_t n = 0 ; n < n_particules ; ++n){
  121. terrain[(size_t)floor(particles[n].pos.y) * width + (size_t)floor(particles[n].pos.x)].pop ++;
  122. terrain[(size_t)floor(particles[n].pos.y) * width + (size_t)floor(particles[n].pos.x)].increase += increase;
  123. }
  124. // Update world pheromone level
  125. terrain_update(terrain, width, height, time_delta);
  126. SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
  127. SDL_RenderClear(renderer);
  128. for(size_t i = 0 ; i < height ; ++i){
  129. for(size_t j = 0 ; j < width ; ++j){
  130. float value_1 = clamp_Uint8( terrain[i * width + j].pop * (20.0f/average_pop) );
  131. float value_2 = clamp_Uint8( terrain[i * width + j].pheromone * (255.0f/average_pheromone) );
  132. // SDL_SetRenderDrawColor(renderer, value_1, value_2, value_2, 1);
  133. SDL_SetRenderDrawColor(renderer, value_2, value_1, value_2, 1);
  134. SDL_RenderDrawPoint(renderer, j, i);
  135. }
  136. }
  137. SDL_RenderPresent(renderer);
  138. }
  139. // destroy my things
  140. free(particles);
  141. free(terrain);
  142. // destroy SDL things
  143. SDL_DestroyWindow(win);
  144. SDL_DestroyRenderer(renderer);
  145. SDL_Quit();
  146. return 0;
  147. }