X-Git-Url: http://git.itanic.dy.fi/?p=mandelbrot;a=blobdiff_plain;f=mandelbrot.c;h=9ca242101ae1bad4a2f98aa5e89387dee82f36f0;hp=926b6af0a827be7f7b3ed99db094c35bf2d0a27f;hb=HEAD;hpb=de02d2ee032bad5bdfb8d5aa05f13784ae6afe06 diff --git a/mandelbrot.c b/mandelbrot.c index 926b6af..9ca2421 100644 --- a/mandelbrot.c +++ b/mandelbrot.c @@ -6,10 +6,12 @@ struct context { struct SDL_Surface *screen; - double origo_x, origo_y; - int motion_x, motion_y; - double zoom; + long double origo_x, origo_y; + int motion_x, motion_y; /* mouse motion */ + int mx, my; /* mouse position */ + long double zoom; int scroll_enabled; + int zooms; }; static void putpixel(struct SDL_Surface *screen, const int x, const int y, @@ -26,9 +28,9 @@ static void putpixel(struct SDL_Surface *screen, const int x, const int y, #define MAX_ITERATION 1000 -int get_mandelbrot_iterations(double x0, double y0) +int get_mandelbrot_iterations(long double x0, long double y0) { - double x = 0, y = 0, xtemp; + long double x = 0, y = 0, xtemp; int iteration = 0; while ((x * x + y * y < 2 * 2) && iteration < MAX_ITERATION) { @@ -43,18 +45,16 @@ int get_mandelbrot_iterations(double x0, double y0) return iteration; } -int draw_mandelbrot(struct SDL_Surface *screen, double x1, double x2, - double y1, double y2) +int draw_mandelbrot(struct SDL_Surface *screen, long double x1, long double x2, + long double y1, long double y2) { - double x0, y0, xlen, ylen, xstep, ystep; + long double x0, y0, xlen, ylen, xstep, ystep; int iteration, xs, ys; - printf("Drawing area (%f, %f)(%f, %f)\n", x1, y1, x2, y2); - xlen = x2 - x1; ylen = y2 - y1; - xstep = xlen / (double)screen->w; - ystep = ylen / (double)screen->h; + xstep = xlen / (long double)screen->w; + ystep = ylen / (long double)screen->h; y0 = y1; #pragma omp parallel for private(xs, ys, x0, y0) @@ -78,6 +78,8 @@ int draw_mandelbrot(struct SDL_Surface *screen, double x1, double x2, return 0; } +#define ZOOM_FACTOR 1.5 + static int read_events(struct context *ctx) { SDL_Event event; @@ -112,10 +114,10 @@ static int read_events(struct context *ctx) break; case SDL_MOUSEBUTTONDOWN: if (event.button.button == 4) { - ctx->zoom *= 1.5; - exit++; + ctx->zooms++; + delayed_exit++; } else if (event.button.button == 5) { - ctx->zoom /= 1.5; + ctx->zooms--; delayed_exit++; } else { ctx->scroll_enabled = 1; @@ -123,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; @@ -154,19 +158,48 @@ quit: static void loop(struct context *ctx) { - double aspect_ratio; + 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; - draw_mandelbrot(ctx->screen, - ctx->origo_x - aspect_ratio / ctx->zoom, - ctx->origo_x + aspect_ratio / ctx->zoom, - ctx->origo_y - 1 / ctx->zoom, - ctx->origo_y + 1 / ctx->zoom); + 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)); }