Skip to content

Instantly share code, notes, and snippets.

@slembcke
Created April 28, 2022 08:58
Show Gist options
  • Save slembcke/ba9051a6e1812a544af5d3fdceb2c2be to your computer and use it in GitHub Desktop.
Save slembcke/ba9051a6e1812a544af5d3fdceb2c2be to your computer and use it in GitHub Desktop.
Fractalis zooming
static void do_zoom(AppState* app, tina* coro, int button, double direction){
if(glfwGetMouseButton(app->window, button) != GLFW_PRESS) return;
Camera* cam = &app->camera;
double speed = 0;
double t0 = glfwGetTime();
while(glfwGetMouseButton(app->window, button) == GLFW_PRESS){
double t1 = glfwGetTime();
double dt = t1 - t0;
t0 = t1;
speed = fmin(speed + 3*dt, 3);
double zoom = exp(direction*speed*dt);
vec2 mouse; glfwGetCursorPos(app->window, &mouse.x, &mouse.y);
vec2 pivot = affine_point(input_transform(app), mouse);
Affine t = {1, 0, 0, 1, -pivot.x, -pivot.y};
t = affine_mul((Affine){zoom, 0, 0, zoom, pivot.x, pivot.y}, t);
Camera cam = app->camera;
app->camera.a = cam.a*t.a + cam.c*t.b;
app->camera.b = cam.b*t.a + cam.d*t.b;
app->camera.c = cam.a*t.c + cam.c*t.d;
app->camera.d = cam.b*t.c + cam.d*t.d;
app->camera.x = fx_add(&app->camera.x, (fx[]){d_to_fx(cam.a*t.x + cam.c*t.y)});
app->camera.y = fx_add(&app->camera.y, (fx[]){d_to_fx(cam.b*t.x + cam.d*t.y)});
double scale = (hypot(cam.a, cam.b) + hypot(cam.c, cam.d))/TILE_SIZE;
printf("scale: %e\n", scale);
app->dirty = true;
tina_yield(coro, 0);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment