1
0
mirror of git://projects.qi-hardware.com/ben-scans.git synced 2024-11-22 10:30:36 +02:00

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
This commit is contained in:
Werner Almesberger 2010-09-24 17:28:48 -03:00
parent 0186959a12
commit 2764155d15
2 changed files with 23 additions and 2 deletions

View File

@ -362,24 +362,43 @@ static gboolean scroll_event(GtkWidget *widget, GdkEventScroll *event,
int dy = event->y-sy(s)/2; int dy = event->y-sy(s)/2;
double r = hypot(dx, dy); double r = hypot(dx, dy);
double rc = r_center(s); double rc = r_center(s);
double rs, rot;
int center = r < rc; int center = r < rc;
int osd = osd_proximity(s, dx, dy); int osd = osd_proximity(s, dx, dy);
if (r < 1) if (r < 1)
return TRUE; 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) { switch (event->direction) {
case GDK_SCROLL_UP: case GDK_SCROLL_UP:
if (center) if (center)
shift(&s->a->m, dx, dy, 1); shift(&s->a->m, dx, dy, 1);
else else
rotate(&s->a->m, dx > 0 ? r : -r); rotate(&s->a->m, dx > 0 ? rot : -rot);
draw_image(darea, s, osd); draw_image(darea, s, osd);
break; break;
case GDK_SCROLL_DOWN: case GDK_SCROLL_DOWN:
if (center) if (center)
shift(&s->a->m, dx, dy, -1); shift(&s->a->m, dx, dy, -1);
else else
rotate(&s->a->m, dx > 0 ? -r : r); rotate(&s->a->m, dx > 0 ? -rot : rot);
draw_image(darea, s, osd); draw_image(darea, s, osd);
break; break;
default: default:

View File

@ -23,6 +23,8 @@ extern GdkGC *gc_osd;
#define LEVEL_CENTER_DIV 5 /* fraction of diagonal */ #define LEVEL_CENTER_DIV 5 /* fraction of diagonal */
#define OVERLAP_BORDER 10 /* pixels around min. drawing area */ #define OVERLAP_BORDER 10 /* pixels around min. drawing area */
#define OVERLAP_CENTER_DIV 5 /* fraction of diagonal */ #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); void init_style(GdkDrawable *da);