From 2764155d15eeca9715b2428fa8653cc35ed7cb79 Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Fri, 24 Sep 2010 17:28:48 -0300 Subject: [PATCH] Increase dynamic range of rotation and follow "far from center = faster" paradigm. - solidify/overlap.c (scroll_event): make weighting of rotation exponential, so we can both adjust precisely and spin rapidly. Also reverse weighting to rotate more quickly on the outside. - solidify/style.h (SLOWEST_ROT, FASTEST_ROT): parameters for weighting of rotation --- solidify/overlap.c | 23 +++++++++++++++++++++-- solidify/style.h | 2 ++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/solidify/overlap.c b/solidify/overlap.c index cebf03c..960fc47 100644 --- a/solidify/overlap.c +++ b/solidify/overlap.c @@ -362,24 +362,43 @@ static gboolean scroll_event(GtkWidget *widget, GdkEventScroll *event, int dy = event->y-sy(s)/2; double r = hypot(dx, dy); double rc = r_center(s); + double rs, rot; int center = r < rc; int osd = osd_proximity(s, dx, dy); if (r < 1) return TRUE; + + /* + * rot goes exponentially from SLOWEST_ROT*rs to FASTEST_ROT for + * r = rc to rs, with rs being half the canvas diagonal. + * + * The values are picked such that we achieve sufficient precision at + * a reasonably large distance from the circle (for accidently entering + * the circle would change the mode) but can also spin quickly, e.g., + * when a 180 degrees rotation is needed. + * + * First, normalize to 0 ... 1 + * Then, we start at exp(0) and end at + * exp(ln(SLOWEST_ROT*rs/FASTEST_ROT))) + */ + rs = hypot(sx(s), sy(s))/2; + rot = (r-rc)/(rs-rc); + rot = SLOWEST_ROT*rs*exp(-rot*log(SLOWEST_ROT*rs/FASTEST_ROT)); + switch (event->direction) { case GDK_SCROLL_UP: if (center) shift(&s->a->m, dx, dy, 1); else - rotate(&s->a->m, dx > 0 ? r : -r); + rotate(&s->a->m, dx > 0 ? rot : -rot); draw_image(darea, s, osd); break; case GDK_SCROLL_DOWN: if (center) shift(&s->a->m, dx, dy, -1); else - rotate(&s->a->m, dx > 0 ? -r : r); + rotate(&s->a->m, dx > 0 ? -rot : rot); draw_image(darea, s, osd); break; default: diff --git a/solidify/style.h b/solidify/style.h index 14bb978..e678b15 100644 --- a/solidify/style.h +++ b/solidify/style.h @@ -23,6 +23,8 @@ extern GdkGC *gc_osd; #define LEVEL_CENTER_DIV 5 /* fraction of diagonal */ #define OVERLAP_BORDER 10 /* pixels around min. drawing area */ #define OVERLAP_CENTER_DIV 5 /* fraction of diagonal */ +#define SLOWEST_ROT 3 /* thrice the half-diagonal */ +#define FASTEST_ROT 2 /* one pixel in distance of 2 pixels */ void init_style(GdkDrawable *da);