mandelbrot

simple mandelbrot visualizer
Index Commits Files Refs README LICENSE
main.c (2440B)
   1 #include "sdl_extra.h"
   2 #include <stdbool.h>
   3 #include <complex.h>
   4 
   5 #define BG_COLOR    0x191919FF
   6 #define MAX_IT        500
   7 
   8 #define DEFAULT_WIN_WIDTH     1024
   9 #define DEFAULT_WIN_HEIGHT     720
  10 
  11 #define WIDTH    640
  12 #define HEIGHT    480
  13 
  14 #define UNHEX(color) \
  15     ((color) >> (8 * 3)) & 0xFF, \
  16     ((color) >> (8 * 2)) & 0xFF, \
  17     ((color) >> (8 * 1)) & 0xFF, \
  18     ((color) >> (8 * 0)) & 0xFF
  19 
  20 #define Re(z)    creal(z)
  21 #define Im(z)    cimag(z)
  22 
  23 float map(float x, float in_min, float in_max, float out_min, float out_max) {
  24     return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
  25 }
  26 
  27 size_t get_iterations(const float complex z0) {
  28     size_t it;
  29     float complex z = 0.0 + 0.0 * I;
  30 
  31     for(it = 0; (it <= MAX_IT) && (Re(z)*Re(z) + Im(z)*Im(z) <= 4); it++)
  32         z = Re(z)*Re(z) - Im(z)*Im(z) + Re(z0) + (2*Re(z)*Im(z) + Im(z0)) * I;
  33 
  34     return it;
  35 }
  36 
  37 void render_mandelbrot(int win_w, int win_h, int width, int height, SDL_Renderer *rend) {
  38     size_t i, j, it;
  39     float complex z0;
  40     float fg;
  41     for(i = 0; i < width; i++) {
  42         for(j = 0; j < height; j++) {
  43             z0 = map(i, 0, width, -2.50, 1.50) + map(j, 0, height, -1.00, 1.00) * I;
  44 
  45             it = get_iterations(z0);
  46 
  47             fg = map(it, 0, MAX_IT, 0, 1);
  48             uint8_t b = map(sqrt(fg), 0, 1, 0, 255);
  49 
  50             uint32_t color = (b << 24) + (b << 16) + (b << 8) + 0xFF;
  51 
  52             if(it == MAX_IT) {
  53                 color = (0xFF << 24) + (0x00 << 16) + (0x00 << 8) + 0x00;
  54                 printf("MAX_IT reached\n");
  55             }
  56 
  57             SDL_SetRenderDrawColor(rend, UNHEX(color));
  58             SDL_RenderDrawPoint(rend,
  59                     (win_w / 2) - (width / 2) + i,
  60                     (win_h / 2) - (height / 2) + j);
  61         }
  62     }
  63 }
  64 
  65 int main (int argc, char *argv[]) {
  66     SDL_Window *win;
  67     SDL_Renderer *rend;
  68     SDL_Event event;
  69 
  70     status_t st;
  71     bool run = true;
  72     int win_w = DEFAULT_WIN_WIDTH, win_h = DEFAULT_WIN_HEIGHT;
  73 
  74     if((st = SDL_setup(&win, &rend)) != OK) {
  75         fprintf(stderr, "%s: couldn't initialize SDL2", argv[0]);
  76         return st;
  77     }
  78 
  79     while(run) {
  80         while(SDL_PollEvent(&event)) {
  81             switch(event.type) {
  82                 case SDL_QUIT:
  83                     run = false;
  84                     break;
  85                 case SDL_WINDOWEVENT:
  86                     switch(event.window.event) {
  87                     case SDL_WINDOWEVENT_RESIZED:
  88                         win_w = event.window.data1;
  89                         win_h = event.window.data2;
  90 
  91                         SDL_SetRenderDrawColor(rend, UNHEX(BG_COLOR));
  92                         SDL_RenderClear(rend);
  93 
  94                         render_mandelbrot(win_w, win_h, 1600, 800, rend);
  95 
  96                         SDL_RenderPresent(rend);
  97                         break;
  98                     default: break;
  99                 }
 100                 default: break;
 101             }
 102         }
 103 
 104     }
 105 
 106     SDL_cleanup(win, rend);
 107     return 0;
 108 }