home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume10 / lemming / part02 / lemspecial.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-08-05  |  4.3 KB  |  221 lines

  1. /*
  2.  * lemspecial.c - extra functions for random applications
  3.  *
  4.  * copyright (c) by Alan W. Paeth, 1987. All rights reserved.
  5.  */
  6.  
  7. #include "lem.h"
  8. #include <math.h>
  9.  
  10. specialfunc()
  11.     {
  12.     char ch;
  13.     msgpost("<F>lip <C>cw <M>agnify <R>otate <S>tretch <A>lign: ");
  14.     ch = getstroke();
  15.     switch(UC(ch))
  16.     {
  17.     case 'F': flip(); break;
  18.     case 'C': ccw(); break;
  19.     case 'M': magnify(); break;
  20.     case 'R': rotate(); break;
  21.     case 'S': stretch(); break;
  22.     case 'A': align(); break;
  23.     default: msgpost("unknown transformation"); break;
  24.     }
  25.     }
  26.  
  27. transform(m11, m12, m21, m22)
  28.     float m11, m12, m21, m22;
  29.     {
  30.     int i;
  31. /*
  32.  * record inverse transformation and set undo flag for undoing
  33.  */
  34.     undo = UNDOAFF;
  35.     unx = markx;
  36.     uny = marky;
  37.     un11 = m11;
  38.     un12 = m12;
  39.     un21 = m21;
  40.     un22 = m22;
  41. /*
  42.  * now do the transformations
  43.  */
  44.  forobjects
  45.     {
  46.     if (Osel)
  47.         {
  48.         objectop(i, SEL, DEL);
  49.         objmove(i, -markx, -marky);
  50.         objaffine(i, m11, m12, m21, m22);
  51.         objmove(i,  markx,  marky);
  52.         objresize(i);
  53.         objectop(i, DEL, SEL);
  54.         }
  55.     }
  56.     }
  57.  
  58. flip()
  59.     {
  60.     if (markon)
  61.     {
  62.     transform(-1.0, 0.0, 0.0, 1.0, 1);
  63.     msgpost("flip done");
  64.     }
  65.     else msgpost("flip -- no mark present");
  66.     }
  67.  
  68. ccw()
  69.     {
  70.     if (markon)
  71.     {
  72.     transform(0.0, -1.0, 1.0, 0.0, 0);
  73.     msgpost("ccw turn done");
  74.     }
  75.     else msgpost("ccw -- no mark present");
  76.     }
  77.  
  78. magnify()
  79.     {
  80.     int x1, y1, x2, y2, xs, ys, xe, ye;
  81.     float mag, outlen;
  82.     if (findmark(&x1, &y1, &x2, &y2))
  83.     {
  84.     xs = x2-markx;
  85.     ys = y2-marky;
  86.     xe = x1-markx;
  87.     ye = y1-marky;
  88.     outlen = xs*xs+ys*ys;
  89.     if (outlen != 0.0)
  90.         {
  91.         mag = sqrt((float)(xe*xe+ye*ye)/outlen);
  92.         mag = (mag < 0.1) ? 0.1 : (mag > 10.0 ? 10.0 : mag);
  93.         transform(mag, 0.0, 0.0, mag, 1);
  94.         msgpost("magnify done");
  95.         }
  96.     msgpost("null magnify ignored");
  97.     }
  98.     }
  99.  
  100. stretch()
  101.     {
  102.     int x1, y1, x2, y2, xs, ys, xe, ye;
  103.     float xmag, ymag;
  104.     if (findmark(&x1, &y1, &x2, &y2))
  105.     {
  106.     xs = x2-markx;
  107.     ys = y2-marky;
  108.     xe = x1-markx;
  109.     ye = y1-marky;
  110.     xmag = (xs == 0) ? 1.0 : (float)(xe)/xs;
  111.     ymag = (ys == 0) ? 1.0 : (float)(ye)/ys;
  112.     xmag = (xmag < 0.1) ? 0.1 : (xmag > 10.0 ? 10.0 : xmag);
  113.     ymag = (ymag < 0.1) ? 0.1 : (ymag > 10.0 ? 10.0 : ymag);
  114.     transform(xmag, 0.0, 0.0, ymag, 1);
  115.     msgpost("stretch done");
  116.     }
  117.     }
  118.  
  119. rotate()
  120.     {
  121.     int x1, y1, x2, y2, xs, ys, xe, ye;
  122.     float s, c, hy;
  123.     if (findmark(&x1, &y1, &x2, &y2))
  124.     {
  125.     xs = x2-markx;
  126.     ys = y2-marky;
  127.     xe = x1-markx;
  128.     ye = y1-marky;
  129.     hy = sqrt((float)( (xs*xs + ys*ys) * (xe*xe + ye*ye) ));
  130.     if (hy != 0.0)
  131.         {
  132.         c =  (xs*xe+ys*ye)/hy;
  133.         s =  (xs*ye-xe*ys)/hy;
  134.         transform(c, -s, s, c, 0);
  135.         msgpost("rotate done");
  136.         }
  137.     else msgpost("null rotation ignored");
  138.     }
  139.     }
  140.  
  141. align()
  142.     {
  143.     int x1, y1, x2, y2, xs, ys, xe, ye, scale;
  144.     float m11, m12, m21, m22, det;
  145.     if (findmark(&x1, &y1, &x2, &y2))
  146.     {
  147.     xs = x2-markx;
  148.     ys = y2-marky;
  149.     xe = x1-markx;
  150.     ye = y1-marky;
  151.     scale = MAX(MAX(ABS(xs),ABS(ys)),MAX(ABS(xe),ABS(ye)));
  152.     det = xe*ys - xs*ye; 
  153.     m11 = (float)( ys*scale)/det;
  154.     m12 = (float)(-xs*scale)/det;
  155.     m21 = (float)(-ye*scale)/det;
  156.     m22 = (float)( xe*scale)/det;
  157.     transform(m11, m12, m21, m22, 1);
  158.     msgpost("align done");
  159.     }
  160.     }
  161.     
  162. findmark(x1, y1, x2, y2)
  163.     int *x1, *y1, *x2, *y2;
  164.     {
  165.     int i, s, e, arrow, straight;
  166.     arrow = straight = 0;
  167.     if (!markon)
  168.     {
  169.     msgpost("transform: no mark present");
  170.     return(0);
  171.     }
  172.     else
  173.     {
  174.     forobjects
  175.         {
  176.         if (Otype != LINE) continue;
  177.         s = (Oxs == markx) && (Oys == marky);
  178.         e = (Oxe == markx) && (Oye == marky);
  179.         if (s || e) 
  180.         {
  181.         switch (Oalign)
  182.             {
  183. case ALIGNCENT:        *x1 = s ? Oxe : Oxs;
  184.             *y1 = s ? Oye : Oys;
  185.             straight++;
  186.             break;
  187. case ALIGNLEFT:        if (s)
  188.             {
  189.             msgpost("transform: arrowhead at origin");
  190.             return(0);
  191.             }
  192.             *x2 = Oxs;
  193.             *y2 = Oys;
  194.             arrow++;
  195.             break;
  196. case ALIGNRGHT:        if (e)
  197.             {
  198.             msgpost("transform: arrowhead at origin");
  199.             return(0);
  200.             }
  201.             *x2 = Oxe;
  202.             *y2 = Oye;
  203.             arrow++;
  204.             break;
  205.             }
  206.         }
  207.         }
  208.     }
  209.     if ((arrow == 1) && (straight == 1)) return(1);
  210. /*
  211.  * errors 
  212.  */
  213.     if (arrow+straight == 0)
  214.     msgpost("transform: no basis vectors at mark");
  215.     else if (arrow != 1)
  216.     msgpost("transform: exactly one arrow basis vector needed");
  217.     else if (straight != 1)
  218.     msgpost("transform: exactly one non-arrow basis vector needed");
  219.     return(0);
  220.     }
  221.