home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / grafik / vifs / modtrans.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-07-09  |  2.9 KB  |  135 lines

  1. /*
  2.  *    modtrans.c  --  transformation modifying function for edtrans().
  3.  *
  4.  *    9 july 1989  Olle Olsson.
  5.  */
  6.  
  7. #include <math.h>
  8. #include "edtrans.h"
  9.  
  10.  
  11. void modtrans( tp, ap, mv_scl )
  12. transform *tp;        /* the transform to modify */
  13. area *ap;        /* limiting area */
  14. int mv_scl;        /* move/scale or rotate/skew flag */
  15. {
  16. struct gm_status gs0, gs;    /* mouse status */
  17. double dxr, dyr;        /* relative movements */
  18. double t;            /* tmp */
  19. double dr;            /* tmp for rotate */
  20. enum                 /* modifying function */
  21.     {
  22.     move, scale, rotate, skew
  23.     } fcn = mv_scl ? move : rotate;
  24.  
  25. /* read the start position, clear the mickey counters and wait for button up */
  26. gm_getpos( &gs0 );
  27. gm_getmickey( &gs );
  28. wbup();
  29.  
  30. for (;;)
  31.     {
  32.     /* read the status, stop if the 'end' button is pressed */
  33.     gm_getpos( &gs );
  34.     if (gs.gm_pbutton & BEND)
  35.         break;
  36.  
  37.     /* function flip? */
  38.     if (gs.gm_pbutton & BFLIP)
  39.         {
  40.         switch (fcn)
  41.             {
  42.             case move:    fcn = scale;    break;
  43.             case scale:    fcn = move;    break;
  44.             case rotate:    fcn = skew;    break;
  45.             case skew:    fcn = rotate;    break;
  46.             }
  47.         wbup();
  48.  
  49.         /* don't check movement */
  50.         continue;
  51.         }
  52.  
  53.     /* Since the mouse driver believes it moves a point
  54.      * it will stop at zero and maximum.
  55.      * Read the mouse movement directly instead of the screen coordinates.
  56.      */
  57.     gm_getmickey( &gs );
  58.  
  59.     /* moved?   (y is upside down) */
  60.     dxr =  gs.gm_xpos / (double) getmaxx();
  61.     dyr = -gs.gm_ypos / (double) getmaxy();
  62.  
  63.     if (!dxr && !dyr)
  64.         continue;
  65.  
  66.     /* erase the transform */
  67.     xdistrans( tp, ap );
  68.  
  69.     switch (fcn)
  70.         {
  71.         case move:    /* move the transform */
  72.             tp -> b1 += ap -> xlen * dxr;
  73.             tp -> b2 += ap -> ylen * dyr;
  74.             break;
  75.  
  76.         case scale:    /* scale the transform */
  77.                     tp -> a11 *= 1 + dxr;
  78.             tp -> a21 *= 1 + dxr;
  79.             tp -> a12 *= 1 + dyr;
  80.             tp -> a22 *= 1 + dyr;
  81.             break;
  82.  
  83.         case rotate:    /* rotate the transform */
  84.             /* multiply by a rotation matrix */
  85.             /* the rotation will be around the origin */
  86.             /* use only mouse x movement for rotation */
  87.             /* find cos( arcsin( dxr ) ) */
  88.             if (fabs( dxr ) >= .99)
  89.                 dxr = (dxr > 0) ? .99 : -.99;
  90.  
  91.             dr = sqrt( 1 - dxr * dxr );
  92.  
  93.             t         = tp -> a11 * dr - tp -> a21 * dxr;
  94.              tp -> a21 = tp -> a21 * dr + tp -> a11 * dxr;
  95.             tp -> a11 = t;
  96.              t         = tp -> a12 * dr - tp -> a22 * dxr;
  97.             tp -> a22 = tp -> a22 * dr + tp -> a12 * dxr;
  98.             tp -> a12 = t;
  99.  
  100.             break;
  101.  
  102.         case skew:    /* skew the transform */
  103.             /* x */
  104.             if (fabs( tp -> a11 ) > fabs( tp -> a12 ))
  105.                 dr = tp -> a11 * dxr;
  106.             else
  107.                 dr = tp -> a12 * dxr;
  108.  
  109.             tp -> a11 += dr;
  110.             tp -> a12 -= dr;
  111.  
  112.             /* y */
  113.             if (fabs( tp -> a21 ) > fabs( tp -> a22 ))
  114.                 dr = tp -> a21 * dyr;
  115.             else
  116.                 dr = tp -> a22 * dyr;
  117.  
  118.             tp -> a21 += dr;
  119.             tp -> a22 -= dr;
  120.  
  121.             break;
  122.         }
  123.  
  124.     /* redraw it */
  125.     xdistrans( tp, ap );
  126.     }
  127.  
  128. /* restore the position */
  129. gm_setpos( gs0.gm_xpos, gs0.gm_ypos );
  130.  
  131. wbup();
  132. }
  133.  
  134.  
  135.