particles.h 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. #ifndef PARTICLES
  2. #define PARTICLES
  3. #include "terrain.h"
  4. #include "math.h"
  5. #include <omp.h>
  6. typedef double coord_t;
  7. typedef struct particule_coord_t {
  8. coord_t x;
  9. coord_t y;
  10. } particule_coord_t;
  11. typedef struct particle_t {
  12. particule_coord_t pos;
  13. particule_coord_t dir;
  14. } particle_t;
  15. particule_coord_t bit_ahead(particule_coord_t at, particule_coord_t dir, coord_t distance){
  16. return (particule_coord_t){at.x + distance * dir.x, at.y + distance * dir.y};
  17. }
  18. particule_coord_t rotate(particule_coord_t dir, coord_t angle){
  19. coord_t C = cos(angle);
  20. coord_t S = sin(angle);
  21. return (particule_coord_t){C * dir.x - S * dir.y, S * dir.x + C * dir.y};
  22. }
  23. size_t particle_coord_to_index(particule_coord_t particle_coord, size_t width, size_t height){
  24. world_coord_t world_coord = {floor(particle_coord.y), floor(particle_coord.x)};
  25. if(world_coord.i < 0)
  26. world_coord.i = 0;
  27. if(world_coord.j < 0)
  28. world_coord.j = 0;
  29. if(world_coord.i >= height)
  30. world_coord.i = height - 1;
  31. if(world_coord.j >= width)
  32. world_coord.j = width - 1;
  33. return world_coord.i * width + world_coord.j;
  34. }
  35. void particle_update(particle_t *p, terrain_t const * const terrain,
  36. coord_t time_delta, coord_t speed, size_t width, size_t heigth,
  37. coord_t sampling_distance, coord_t sampling_angle, coord_t steering_angle){
  38. p->pos.x += time_delta * speed * p->dir.x;
  39. p->pos.y += time_delta * speed * p->dir.y;
  40. // Remain in [0, width[
  41. if(p->pos.x < 0){
  42. p->pos.x = - p->pos.x;
  43. p->dir.x = - p->dir.x;
  44. }
  45. if(p->pos.y < 0){
  46. p->pos.y = - p->pos.y;
  47. p->dir.y = - p->dir.y;
  48. }
  49. if(p->pos.x >= width){
  50. p->pos.x = 2 * width - p->pos.x;
  51. p->dir.x = - p->dir.x;
  52. }
  53. if(p->pos.y >= heigth){
  54. p->pos.y = 2 * heigth - p->pos.y;
  55. p->dir.y = - p->dir.y;
  56. }
  57. particule_coord_t dir_left = rotate(p->dir, sampling_angle * M_PI / 180.0f);
  58. particule_coord_t dir_right = rotate(p->dir, -sampling_angle * M_PI / 180.0f);
  59. float pheromone_ahead = terrain[particle_coord_to_index(bit_ahead(p->pos, p->dir, sampling_distance), width, heigth)].pheromone;
  60. float pheromone_left = terrain[particle_coord_to_index(bit_ahead(p->pos, dir_left, sampling_distance), width, heigth)].pheromone;
  61. float pheromone_rigth = terrain[particle_coord_to_index(bit_ahead(p->pos, dir_right, sampling_distance), width, heigth)].pheromone;
  62. if(pheromone_left > pheromone_ahead && pheromone_left > pheromone_rigth)
  63. p->dir = rotate(p->dir, steering_angle * M_PI / 180.0f);
  64. else if(pheromone_rigth > pheromone_ahead)
  65. p->dir = rotate(p->dir, -steering_angle * M_PI / 180.0f);
  66. p->dir = rotate(p->dir, steering_angle * 0.2 * (2*rand()/RAND_MAX-1) * time_delta * M_PI / 180.0f);
  67. }
  68. #endif //PARTICLES