home *** CD-ROM | disk | FTP | other *** search
- /*
- * modtrans.c -- transformation modifying function for edtrans().
- *
- * 9 july 1989 Olle Olsson.
- */
-
- #include <math.h>
- #include "edtrans.h"
-
-
- void modtrans( tp, ap, mv_scl )
- transform *tp; /* the transform to modify */
- area *ap; /* limiting area */
- int mv_scl; /* move/scale or rotate/skew flag */
- {
- struct gm_status gs0, gs; /* mouse status */
- double dxr, dyr; /* relative movements */
- double t; /* tmp */
- double dr; /* tmp for rotate */
- enum /* modifying function */
- {
- move, scale, rotate, skew
- } fcn = mv_scl ? move : rotate;
-
- /* read the start position, clear the mickey counters and wait for button up */
- gm_getpos( &gs0 );
- gm_getmickey( &gs );
- wbup();
-
- for (;;)
- {
- /* read the status, stop if the 'end' button is pressed */
- gm_getpos( &gs );
- if (gs.gm_pbutton & BEND)
- break;
-
- /* function flip? */
- if (gs.gm_pbutton & BFLIP)
- {
- switch (fcn)
- {
- case move: fcn = scale; break;
- case scale: fcn = move; break;
- case rotate: fcn = skew; break;
- case skew: fcn = rotate; break;
- }
- wbup();
-
- /* don't check movement */
- continue;
- }
-
- /* Since the mouse driver believes it moves a point
- * it will stop at zero and maximum.
- * Read the mouse movement directly instead of the screen coordinates.
- */
- gm_getmickey( &gs );
-
- /* moved? (y is upside down) */
- dxr = gs.gm_xpos / (double) getmaxx();
- dyr = -gs.gm_ypos / (double) getmaxy();
-
- if (!dxr && !dyr)
- continue;
-
- /* erase the transform */
- xdistrans( tp, ap );
-
- switch (fcn)
- {
- case move: /* move the transform */
- tp -> b1 += ap -> xlen * dxr;
- tp -> b2 += ap -> ylen * dyr;
- break;
-
- case scale: /* scale the transform */
- tp -> a11 *= 1 + dxr;
- tp -> a21 *= 1 + dxr;
- tp -> a12 *= 1 + dyr;
- tp -> a22 *= 1 + dyr;
- break;
-
- case rotate: /* rotate the transform */
- /* multiply by a rotation matrix */
- /* the rotation will be around the origin */
- /* use only mouse x movement for rotation */
- /* find cos( arcsin( dxr ) ) */
- if (fabs( dxr ) >= .99)
- dxr = (dxr > 0) ? .99 : -.99;
-
- dr = sqrt( 1 - dxr * dxr );
-
- t = tp -> a11 * dr - tp -> a21 * dxr;
- tp -> a21 = tp -> a21 * dr + tp -> a11 * dxr;
- tp -> a11 = t;
- t = tp -> a12 * dr - tp -> a22 * dxr;
- tp -> a22 = tp -> a22 * dr + tp -> a12 * dxr;
- tp -> a12 = t;
-
- break;
-
- case skew: /* skew the transform */
- /* x */
- if (fabs( tp -> a11 ) > fabs( tp -> a12 ))
- dr = tp -> a11 * dxr;
- else
- dr = tp -> a12 * dxr;
-
- tp -> a11 += dr;
- tp -> a12 -= dr;
-
- /* y */
- if (fabs( tp -> a21 ) > fabs( tp -> a22 ))
- dr = tp -> a21 * dyr;
- else
- dr = tp -> a22 * dyr;
-
- tp -> a21 += dr;
- tp -> a22 -= dr;
-
- break;
- }
-
- /* redraw it */
- xdistrans( tp, ap );
- }
-
- /* restore the position */
- gm_setpos( gs0.gm_xpos, gs0.gm_ypos );
-
- wbup();
- }
-
-
-