From c33a92b00494936a1ba352ada8e61a203d7b5b54 Mon Sep 17 00:00:00 2001 From: Timo Kokkonen Date: Wed, 4 May 2011 22:16:39 +0300 Subject: [PATCH] Zoom where the mouse cursor points into This makes zooming into interesting points much easier Signed-off-by: Timo Kokkonen --- mandelbrot.c | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/mandelbrot.c b/mandelbrot.c index eaca707..a00be93 100644 --- a/mandelbrot.c +++ b/mandelbrot.c @@ -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 { @@ -127,6 +128,8 @@ static int read_events(struct context *ctx) delayed_exit++; break; case SDL_MOUSEMOTION: + ctx->mx = event.motion.x; + ctx->my = event.motion.y; if (!ctx->scroll_enabled) break; @@ -157,6 +160,7 @@ 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; @@ -164,12 +168,37 @@ static void loop(struct context *ctx) 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 (%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)); } -- 2.45.0