]> git.itanic.dy.fi Git - mandelbrot/blobdiff - mandelbrot.c
Fix broken aspect ratio calculation
[mandelbrot] / mandelbrot.c
index 5dc9aed7f65f8054cc8161e09f874f453d4add28..9ca242101ae1bad4a2f98aa5e89387dee82f36f0 100644 (file)
@@ -7,7 +7,8 @@
 struct context {
        struct SDL_Surface *screen;
        long double origo_x, origo_y;
-       int motion_x, motion_y;
+       int motion_x, motion_y;         /* mouse motion */
+       int mx, my;                     /* mouse position */
        long double zoom;
        int scroll_enabled;
        int zooms;
@@ -77,6 +78,8 @@ int draw_mandelbrot(struct SDL_Surface *screen, long double x1, long double x2,
        return 0;
 }
 
+#define ZOOM_FACTOR    1.5
+
 static int read_events(struct context *ctx)
 {
        SDL_Event event;
@@ -111,11 +114,9 @@ static int read_events(struct context *ctx)
                        break;
                case SDL_MOUSEBUTTONDOWN:
                        if (event.button.button == 4) {
-                               ctx->zoom *= 1.5;
                                ctx->zooms++;
                                delayed_exit++;
                        } else if (event.button.button == 5) {
-                               ctx->zoom /= 1.5;
                                ctx->zooms--;
                                delayed_exit++;
                        } else {
@@ -124,9 +125,11 @@ static int read_events(struct context *ctx)
                        break;
                case SDL_MOUSEBUTTONUP:
                        ctx->scroll_enabled = 0;
-                       exit++;
+                       delayed_exit++;
                        break;
                case SDL_MOUSEMOTION:
+                       ctx->mx = event.motion.x;
+                       ctx->my = event.motion.y;
                        if (!ctx->scroll_enabled)
                                break;
 
@@ -157,19 +160,45 @@ static void loop(struct context *ctx)
 {
        long double aspect_ratio;
        long double x1, x2, y1, y2;
+       int last_zoom;
 
        do {
-               aspect_ratio = ctx->screen->w / ctx->screen->h;
+               aspect_ratio = ctx->screen->w / (long double)ctx->screen->h;
                ctx->origo_x += ctx->motion_x / ctx->zoom / ctx->screen->w;
                ctx->origo_y += ctx->motion_y / ctx->zoom / ctx->screen->h;
                ctx->motion_x = ctx->motion_y = 0;
 
+               if (ctx->zooms != last_zoom) {
+                       int dx, dy;
+
+                       dx = ctx->mx - ctx->screen->w / 2;
+                       dy = ctx->my - ctx->screen->h / 2;
+
+                       if (ctx->zooms > last_zoom) {
+                               ctx->zoom *= ZOOM_FACTOR;
+                               ctx->origo_x += dx / ctx->zoom /
+                                       (long double) ctx->screen->w;
+                               ctx->origo_y += dy / ctx->zoom /
+                                       (long double) ctx->screen->h;
+                       } else {
+                               ctx->origo_x -= dx / ctx->zoom /
+                                       (long double) ctx->screen->w;
+                               ctx->origo_y -= dy / ctx->zoom /
+                                       (long double) ctx->screen->h;
+                               ctx->zoom /= ZOOM_FACTOR;
+                       }
+
+                       last_zoom = ctx->zooms;
+               }
+
                x1 = ctx->origo_x - aspect_ratio / ctx->zoom;
                x2 = ctx->origo_x + aspect_ratio / ctx->zoom;
                y1 = ctx->origo_y - 1 / ctx->zoom;
                y2 = ctx->origo_y + 1 / ctx->zoom;
-               printf("Drawing area (%f, %f)(%f, %f), zoom %d\n",
+
+               printf("Drawing area (%LF, %LF)(%LF, %LF), zoom %d\n",
                        x1, y1, x2, y2, ctx->zooms);
+
                draw_mandelbrot(ctx->screen, x1, x2, y1, y2);
        } while (!read_events(ctx));
 }