1
0
Fork 0
forked from len0rd/rockbox

Fractals: Prevent zooming more than deepest possible zoom

This prevent the mandelbrost set from being trashed if zooming too much


git-svn-id: svn://svn.rockbox.org/rockbox/trunk@24264 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Tomer Shalev 2010-01-17 21:15:56 +00:00
parent 5b94d44cc0
commit ab450a81ec
3 changed files with 25 additions and 12 deletions

View file

@ -167,7 +167,7 @@ enum plugin_status plugin_start(const void* parameter)
if (lastbutton != FRACTAL_ZOOM_OUT_PRE) if (lastbutton != FRACTAL_ZOOM_OUT_PRE)
break; break;
#endif #endif
ops->zoom(-1); if (!ops->zoom(-1))
redraw = REDRAW_FULL; redraw = REDRAW_FULL;
break; break;
@ -180,7 +180,7 @@ enum plugin_status plugin_start(const void* parameter)
#ifdef FRACTAL_ZOOM_IN2 #ifdef FRACTAL_ZOOM_IN2
case FRACTAL_ZOOM_IN2: case FRACTAL_ZOOM_IN2:
#endif #endif
ops->zoom(1); if (!ops->zoom(1))
redraw = REDRAW_FULL; redraw = REDRAW_FULL;
break; break;

View file

@ -47,7 +47,7 @@ struct fractal_ops
int (*calc)(struct fractal_rect *rect, int (*button_yield_cb)(void *ctx), int (*calc)(struct fractal_rect *rect, int (*button_yield_cb)(void *ctx),
void *button_yield_ctx); void *button_yield_ctx);
void (*move)(int dx, int dy); void (*move)(int dx, int dy);
void (*zoom)(int factor); int (*zoom)(int factor);
int (*precision)(int d); int (*precision)(int d);
}; };

View file

@ -96,7 +96,7 @@ static int mandelbrot_calc_high_prec(struct fractal_rect *rect,
static void mandelbrot_move(int dx, int dy); static void mandelbrot_move(int dx, int dy);
static void mandelbrot_zoom(int factor); static int mandelbrot_zoom(int factor);
static int mandelbrot_precision(int d); static int mandelbrot_precision(int d);
@ -109,13 +109,15 @@ struct fractal_ops mandelbrot_ops =
.precision = mandelbrot_precision, .precision = mandelbrot_precision,
}; };
#define LOG2_OUT_OF_BOUNDS -32767
static int ilog2_fp(long value) /* calculate integer log2(value_fp_6.26) */ static int ilog2_fp(long value) /* calculate integer log2(value_fp_6.26) */
{ {
int i = 0; int i = 0;
if (value <= 0) if (value <= 0)
{ {
return -32767; return LOG2_OUT_OF_BOUNDS;
} }
else if (value > (1L << 26)) else if (value > (1L << 26))
{ {
@ -136,18 +138,24 @@ static int ilog2_fp(long value) /* calculate integer log2(value_fp_6.26) */
return i; return i;
} }
static void recalc_parameters(void) static int recalc_parameters(void)
{ {
ctx.x_step = (ctx.x_max - ctx.x_min) / LCD_WIDTH; ctx.x_step = (ctx.x_max - ctx.x_min) / LCD_WIDTH;
ctx.x_delta = X_DELTA(ctx.x_step);
ctx.y_step = (ctx.y_max - ctx.y_min) / LCD_HEIGHT; ctx.y_step = (ctx.y_max - ctx.y_min) / LCD_HEIGHT;
ctx.step_log2 = ilog2_fp(MIN(ctx.x_step, ctx.y_step));
if (ctx.step_log2 == LOG2_OUT_OF_BOUNDS)
return 1; /* out of bounds */
ctx.x_delta = X_DELTA(ctx.x_step);
ctx.y_delta = Y_DELTA(ctx.y_step); ctx.y_delta = Y_DELTA(ctx.y_step);
ctx.y_delta = (ctx.y_step * LCD_HEIGHT) / 8; ctx.y_delta = (ctx.y_step * LCD_HEIGHT) / 8;
ctx.step_log2 = ilog2_fp(MIN(ctx.x_step, ctx.y_step));
ctx.max_iter = MAX(15, -15 * ctx.step_log2 - 45); ctx.max_iter = MAX(15, -15 * ctx.step_log2 - 45);
ctx.ops->calc = (ctx.step_log2 <= -10) ? ctx.ops->calc = (ctx.step_log2 <= -10) ?
mandelbrot_calc_high_prec : mandelbrot_calc_low_prec; mandelbrot_calc_high_prec : mandelbrot_calc_low_prec;
return 0;
} }
static void mandelbrot_init(void) static void mandelbrot_init(void)
@ -368,8 +376,9 @@ static void mandelbrot_move(int dx, int dy)
ctx.y_max += d_y; ctx.y_max += d_y;
} }
static void mandelbrot_zoom(int factor) static int mandelbrot_zoom(int factor)
{ {
int res;
long factor_x = (long)factor * ctx.x_delta; long factor_x = (long)factor * ctx.x_delta;
long factor_y = (long)factor * ctx.y_delta; long factor_y = (long)factor * ctx.y_delta;
@ -378,7 +387,11 @@ static void mandelbrot_zoom(int factor)
ctx.y_min += factor_y; ctx.y_min += factor_y;
ctx.y_max -= factor_y; ctx.y_max -= factor_y;
recalc_parameters(); res = recalc_parameters();
if (res) /* zoom not possible, revert */
mandelbrot_zoom(-factor);
return res;
} }
static int mandelbrot_precision(int d) static int mandelbrot_precision(int d)