Advertisement
Guest User

Untitled

a guest
Jun 23rd, 2017
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.40 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <assert.h>
  4. #include <stdbool.h>
  5. #include <time.h>
  6.  
  7. #include <math.h>
  8.  
  9. #include <SDL2/SDL.h>
  10.  
  11. #define WINDOW_WIDTH 720
  12. #define WINDOW_HEIGHT 720
  13.  
  14. #define G 9.80665f
  15.  
  16. struct pendulum_t {
  17. double mass;
  18. double lenght;
  19.  
  20. double th;
  21. double th_d;
  22.  
  23. SDL_Point coord;
  24. };
  25.  
  26. typedef struct pendulum_t pendulum_t;
  27.  
  28. pendulum_t PendulumCreate(double mass, double lenght, double th, double th_d) {
  29. pendulum_t p;
  30.  
  31. p.mass = mass;
  32. p.lenght = lenght;
  33. p.th = th;
  34. p.th_d = th_d;
  35.  
  36. p.coord.x = 0;
  37. p.coord.y = 0;
  38.  
  39. return p;
  40. }
  41.  
  42. double ThetaFirstPendulum(pendulum_t p1, pendulum_t p2) {
  43. double m = p1.mass + p2.mass;
  44.  
  45. double a = p2.mass * p1.lenght * p1.th_d * p1.th_d * sin(p2.th - p1.th) * cos(p2.th - p1.th);
  46. double b = p2.mass * G * sin(p2.th) * cos(p2.th - p1.th);
  47. double c = p2.mass * p2.lenght * p2.th_d * p2.th_d * sin(p2.th - p1.th);
  48. double d = -m * G * sin(p1.th);
  49.  
  50. double e = (m * p1.lenght) - p2.mass * p1.lenght * cos(p2.th - p1.th) * cos(p2.th - p1.th);
  51.  
  52. return (a + b + c + d) / e;
  53.  
  54. }
  55.  
  56. double ThetaSecondPendulum(pendulum_t p1, pendulum_t p2) {
  57. double m = p1.mass + p2.mass;
  58.  
  59. double a = -p2.mass * p2.lenght * p2.th_d * p2.th_d * sin(p2.th - p1.th) * cos(p2.th - p1.th);
  60. double b = m * (G * sin(p1.th) * cos(p2.th - p1.th) - p1.lenght * p1.th_d * p1.th_d * sin(p2.th - p1.th) - G * sin(p2.th));
  61. double c = (m * p2.lenght) - p2.mass * p2.lenght * cos(p2.th - p1.th) * cos(p2.th - p1.th);
  62.  
  63. return (a + b) / c;
  64. }
  65.  
  66. int ThFirstPendulumToX(pendulum_t p1) {
  67. return (int)(WINDOW_WIDTH / 2 - sin(p1.th) * p1.lenght);
  68. }
  69.  
  70. int ThFirstPendulumToY(pendulum_t p1) {
  71. return (int)(WINDOW_HEIGHT / 2 + cos(p1.th) * p1.lenght);
  72. }
  73.  
  74. int ThSecondPendulumToX(pendulum_t p1, pendulum_t p2) {
  75. return (int)(ThFirstPendulumToX(p1) - sin(p2.th) * p2.lenght);
  76. }
  77.  
  78. int ThSecondPendulumToY(pendulum_t p1, pendulum_t p2) {
  79. return (int)(ThFirstPendulumToY(p1) + cos(p2.th) * p2.lenght);
  80. }
  81.  
  82. void CalcPosition(pendulum_t *p1, pendulum_t *p2) {
  83. p1->coord.x = (int)ThFirstPendulumToX(*p1);
  84. p1->coord.y = (int)ThFirstPendulumToY(*p1);
  85.  
  86. p2->coord.x = (int)ThSecondPendulumToX(*p1, *p2);
  87. p2->coord.y = (int)ThSecondPendulumToY(*p1, *p2);
  88. }
  89.  
  90. void DrawPendulums(SDL_Renderer *renderer, pendulum_t p1, pendulum_t p2) {
  91. int x1 = p1.coord.x;
  92. int y1 = p1.coord.y;
  93.  
  94. int x2 = p2.coord.x;
  95. int y2 = p2.coord.y;
  96.  
  97. int xoffset = 1;
  98.  
  99. SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
  100.  
  101. SDL_Point points[3] = {
  102. {WINDOW_WIDTH/2, WINDOW_HEIGHT/2},
  103. {x1, y1},
  104. {x2, y2}
  105. };
  106.  
  107. SDL_Point points2[3] = {
  108. {WINDOW_WIDTH/2 + xoffset, WINDOW_HEIGHT/2},
  109. {x1 + xoffset, y1},
  110. {x2 + xoffset, y2}
  111. };
  112.  
  113. SDL_RenderDrawLines(renderer, points, 3);
  114. SDL_RenderDrawLines(renderer, points2, 3);
  115. }
  116.  
  117. void DrawPath(SDL_Renderer *renderer, pendulum_t p) {
  118. static SDL_Point point[2048] = {0};
  119. static int i = 0;
  120.  
  121. point[i].x = p.coord.x;
  122. point[i].y = p.coord.y;
  123.  
  124. if(++i > 2048)
  125. i = 0;
  126.  
  127. SDL_SetRenderDrawColor(renderer, 0, 0, 255, SDL_ALPHA_OPAQUE);
  128. SDL_RenderDrawLines(renderer, point, i);
  129. }
  130.  
  131. void AnimatePendulums(pendulum_t *p1, pendulum_t *p2) {
  132. float dt = 0.05;
  133.  
  134. p1->th_d += ThetaFirstPendulum(*p1, *p2) * dt;
  135. p2->th_d += ThetaSecondPendulum(*p1, *p2) * dt;
  136.  
  137. p1->th += p1->th_d * dt;
  138. p2->th += p2->th_d * dt;
  139. }
  140.  
  141. float RandFloat(float min, float max) {
  142. return min + (((float)rand() / (float)(RAND_MAX / (max - min))));
  143. }
  144.  
  145. void PrintPendulumInfo(pendulum_t p, int i) {
  146. printf("Pendulum %d:", i);
  147.  
  148. printf("\n\t- Lenght: %.3lf\n", p.lenght);
  149. printf("\t- Mass: %.3lf\n\n", p.mass);
  150. }
  151.  
  152. int main(int argc, char *argv[]) {
  153. (void)argc;
  154. (void)argv;
  155.  
  156. assert(SDL_Init(SDL_INIT_VIDEO) == 0);
  157.  
  158. SDL_Window *window = NULL;
  159. SDL_Renderer *renderer = NULL;
  160. SDL_Event event;
  161.  
  162. bool running = true;
  163.  
  164. assert(SDL_CreateWindowAndRenderer(WINDOW_WIDTH, WINDOW_WIDTH, 0,
  165. &window, &renderer) == 0);
  166.  
  167. srand(time(NULL));
  168.  
  169. pendulum_t p1 = PendulumCreate(100, 120, RandFloat(0, 1) * M_PI * 2, (RandFloat(0, 1) - 0.5) * 2);
  170. pendulum_t p2 = PendulumCreate(100, 120, RandFloat(0, 1) * M_PI * 2, (RandFloat(0, 1) - 0.5) * 2);
  171.  
  172. while(running) {
  173. while(SDL_PollEvent(&event)) {
  174. if(event.type == SDL_QUIT) {
  175. running = false;
  176. }
  177.  
  178. switch(event.type) {
  179. case SDL_QUIT:
  180. running = false;
  181. break;
  182. case SDL_KEYDOWN:
  183. switch(event.key.keysym.sym) {
  184. case SDLK_a:
  185. p1.lenght -= 1;
  186. break;
  187. case SDLK_z:
  188. p1.lenght += 1;
  189. break;
  190. case SDLK_e:
  191. p2.lenght -= 1;
  192. break;
  193. case SDLK_r:
  194. p2.lenght += 1;
  195. break;
  196. case SDLK_q:
  197. p1.mass -= 5;
  198. break;
  199. case SDLK_s:
  200. p1.mass += 5;
  201. break;
  202. case SDLK_d:
  203. p2.mass -= 5;
  204. break;
  205. case SDLK_f:
  206. p2.mass += 5;
  207. break;
  208. case SDLK_n:
  209. p1 = PendulumCreate(100, 120, RandFloat(0, 1) * M_PI * 2, (RandFloat(0, 1) - 0.5) * 2);
  210. p2 = PendulumCreate(100, 120, RandFloat(0, 1) * M_PI * 2, (RandFloat(0, 1) - 0.5) * 2);
  211. break;
  212. case SDLK_i:
  213. PrintPendulumInfo(p1, 1);
  214. PrintPendulumInfo(p2, 2);
  215. break;
  216. }
  217. break;
  218. }
  219. }
  220.  
  221. AnimatePendulums(&p1, &p2);
  222.  
  223. CalcPosition(&p1, &p2);
  224.  
  225. SDL_SetRenderDrawColor(renderer, 255, 255, 255, SDL_ALPHA_OPAQUE);
  226. SDL_RenderClear(renderer);
  227.  
  228. DrawPendulums(renderer, p1, p2);
  229. DrawPath(renderer, p2);
  230.  
  231. SDL_RenderPresent(renderer);
  232.  
  233. SDL_Delay(5);
  234. }
  235.  
  236. SDL_DestroyRenderer(renderer);
  237. SDL_DestroyWindow(window);
  238.  
  239. SDL_Quit();
  240. return 0;
  241.  
  242. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement