YorKnEz

fractals.cpp 2

Apr 3rd, 2022
162
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.17 KB | None | 0 0
  1. #include <SDL2/SDL.h>
  2. #include <stdio.h>
  3. #include <time.h>
  4. #include <math.h>
  5.  
  6. #define TITLE "Fractal"
  7. #define SIZE 512
  8.  
  9. bool quit = false;
  10.  
  11. uint fps = 60;
  12. uint minframetime = 1000 / fps;
  13. uint16_t window_size = SIZE;
  14.  
  15. int convergenceSpeed[SIZE][SIZE];
  16.  
  17. struct Point {
  18. float x, y;
  19. };
  20.  
  21. Point c = { 0.17, -0.58 };
  22. int zoom = window_size / 4;
  23. int roundOffPrecision = 1;
  24.  
  25. void events(SDL_Window *window);
  26.  
  27. void draw(SDL_Renderer *renderer);
  28.  
  29. int computeConvergenceForPoint(int x, int y);
  30.  
  31. void computeConvergence();
  32.  
  33. float roundOff(float value);
  34.  
  35. uint rainbow(uint n);
  36.  
  37. uint wave(uint n);
  38.  
  39. int main(int argc, char **argv) {
  40.  
  41. SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS);
  42.  
  43. SDL_Window *window =
  44. SDL_CreateWindow(
  45. TITLE,
  46. SDL_WINDOWPOS_CENTERED,
  47. SDL_WINDOWPOS_CENTERED,
  48. window_size,
  49. window_size,
  50. SDL_WINDOW_OPENGL);
  51.  
  52. int display_index = SDL_GetWindowDisplayIndex(window);
  53.  
  54. SDL_DisplayMode mode;
  55.  
  56. if (SDL_GetDesktopDisplayMode(display_index, &mode) == 0) {
  57. fps = mode.refresh_rate;
  58. minframetime = 1000 / fps;
  59. }
  60.  
  61. SDL_Renderer *renderer =
  62. SDL_CreateRenderer(
  63. window,
  64. -1,
  65. SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
  66.  
  67. // compute the convergence speed of each point before rendering
  68. computeConvergence();
  69.  
  70. while (!quit) {
  71. int start = SDL_GetTicks();
  72.  
  73. events(window);
  74. draw(renderer);
  75.  
  76. SDL_RenderPresent(renderer);
  77.  
  78. int time = SDL_GetTicks() - start;
  79. int sleepTime = minframetime - time;
  80. if (sleepTime > 0) {
  81. SDL_Delay(sleepTime);
  82. }
  83. }
  84.  
  85. SDL_DestroyRenderer(renderer);
  86. SDL_DestroyWindow(window);
  87. SDL_Quit();
  88.  
  89. fclose(stdout);
  90.  
  91. return 0;
  92. }
  93.  
  94. void events(SDL_Window *window) {
  95. SDL_Event event;
  96.  
  97. while (SDL_PollEvent(&event) != 0) {
  98. if (event.type == SDL_QUIT) {
  99. quit = true;
  100. }
  101. // code for zooming
  102. else if (event.type == SDL_KEYDOWN) {
  103. SDL_Keycode keycode = event.key.keysym.sym;
  104.  
  105. switch (keycode) {
  106. // PgUp is zooming in
  107. case SDLK_PAGEUP:
  108. printf("PgUp key pressed\n");
  109. zoom *= 2;
  110.  
  111. computeConvergence();
  112. break;
  113. // PgDown is zooming out
  114. case SDLK_PAGEDOWN:
  115. printf("PgDown key pressed\n");
  116. zoom /= 2;
  117.  
  118. computeConvergence();
  119. break;
  120. // 0 is for resetting precision
  121. case SDLK_0:
  122. printf("0 key pressed\n");
  123. roundOffPrecision = 1;
  124.  
  125. computeConvergence();
  126. break;
  127. // 1 is for increasing precision
  128. case SDLK_1:
  129. printf("1 key pressed\n");
  130. roundOffPrecision++;
  131.  
  132. computeConvergence();
  133. break;
  134. }
  135. }
  136. }
  137. }
  138.  
  139. void draw(SDL_Renderer *renderer) {
  140. SDL_SetRenderDrawColor(renderer, 255, 236, 179, 255);
  141. SDL_RenderClear(renderer);
  142.  
  143. SDL_SetRenderDrawColor(renderer, 100, 221, 23, 255);
  144. // x axis
  145. SDL_RenderDrawLine(renderer, 0, window_size / 2, window_size, window_size / 2);
  146. // y axis
  147. SDL_RenderDrawLine(renderer, window_size / 2, 0, window_size / 2, window_size);
  148.  
  149. // draw the fractal based on convergenceSpeed
  150. for (int x = 0; x < window_size; x++) {
  151. for (int y = 0; y < window_size; y++) {
  152. if (convergenceSpeed[x][y] > 0) {
  153. // set the color using rainbow funciton
  154. uint color = rainbow(convergenceSpeed[x][y]);
  155.  
  156. // decode the color to RGB values
  157. unsigned int red = (color & 0x00ff0000) >> 16;
  158. unsigned int green = (color & 0x0000ff00) >> 8;
  159. unsigned int blue = (color & 0x000000ff);
  160.  
  161. SDL_SetRenderDrawColor(renderer, red, green, blue, 255);
  162. // SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
  163. SDL_RenderDrawPoint(renderer, x, y);
  164. }
  165. }
  166. }
  167. }
  168.  
  169. int computeConvergenceForPoint(int x, int y) {
  170. // initial Z
  171. Point Z0 = {
  172. ((float)(x) - (float)(window_size) / 2) / zoom,
  173. -((float)(y) - (float)(window_size) / 2) / zoom
  174. };
  175.  
  176. // current Z
  177. Point Z1 = {
  178. Z0.x * Z0.x - Z0.y * Z0.y + c.x,
  179. 2 * Z0.x * Z0.y + c.y
  180. };
  181.  
  182. // next Z
  183. Point Z2;
  184.  
  185. for (int i = 1; i <= 70; i++) {
  186. Z2.x = Z1.x * Z1.x - Z1.y * Z1.y + c.x;
  187. Z2.y = 2 * Z1.x * Z1.y + c.y;
  188.  
  189. // First check if it converged
  190. // If Z1 = Z2 then it converged
  191. if (roundOff(Z1.x) == roundOff(Z2.x) && roundOff(Z1.y) == roundOff(Z2.y)) return i;
  192.  
  193. // Second check if it converged
  194. // There is a case in which Z starts alternating, that means Z0 = Z2
  195. if (roundOff(Z0.x) == roundOff(Z2.x) && roundOff(Z0.y) == roundOff(Z2.y)) return i;
  196.  
  197. // Check if it diverged
  198. if (abs(Z2.x) > 10000000 || abs(Z2.y) > 1000000) return 0;
  199.  
  200. Z0 = Z1;
  201. Z1 = Z2;
  202. }
  203.  
  204. return 71;
  205. }
  206.  
  207. void computeConvergence() {
  208. for (int x = 0; x < window_size; x++) {
  209. for (int y = 0; y < window_size; y++) {
  210. convergenceSpeed[x][y] = computeConvergenceForPoint(x, y);
  211. }
  212. }
  213. }
  214.  
  215. float roundOff(float value) {
  216. float pow_10 = pow(10.0f, (float)roundOffPrecision);
  217. return round(value * pow_10);
  218. }
  219.  
  220. uint rainbow(uint n) {
  221. return (wave(n) << 16) + (wave(n + 85) << 8) + wave(n + 170);
  222. }
  223.  
  224. uint wave(uint n) {
  225. return int(125 * sin(n / 15) + 126);
  226. }
Advertisement
Add Comment
Please, Sign In to add comment