home *** CD-ROM | disk | FTP | other *** search
- /*
- * lemspecial.c - extra functions for random applications
- *
- * copyright (c) by Alan W. Paeth, 1987. All rights reserved.
- */
-
- #include "lem.h"
- #include <math.h>
-
- specialfunc()
- {
- char ch;
- msgpost("<F>lip <C>cw <M>agnify <R>otate <S>tretch <A>lign: ");
- ch = getstroke();
- switch(UC(ch))
- {
- case 'F': flip(); break;
- case 'C': ccw(); break;
- case 'M': magnify(); break;
- case 'R': rotate(); break;
- case 'S': stretch(); break;
- case 'A': align(); break;
- default: msgpost("unknown transformation"); break;
- }
- }
-
- transform(m11, m12, m21, m22)
- float m11, m12, m21, m22;
- {
- int i;
- /*
- * record inverse transformation and set undo flag for undoing
- */
- undo = UNDOAFF;
- unx = markx;
- uny = marky;
- un11 = m11;
- un12 = m12;
- un21 = m21;
- un22 = m22;
- /*
- * now do the transformations
- */
- forobjects
- {
- if (Osel)
- {
- objectop(i, SEL, DEL);
- objmove(i, -markx, -marky);
- objaffine(i, m11, m12, m21, m22);
- objmove(i, markx, marky);
- objresize(i);
- objectop(i, DEL, SEL);
- }
- }
- }
-
- flip()
- {
- if (markon)
- {
- transform(-1.0, 0.0, 0.0, 1.0, 1);
- msgpost("flip done");
- }
- else msgpost("flip -- no mark present");
- }
-
- ccw()
- {
- if (markon)
- {
- transform(0.0, -1.0, 1.0, 0.0, 0);
- msgpost("ccw turn done");
- }
- else msgpost("ccw -- no mark present");
- }
-
- magnify()
- {
- int x1, y1, x2, y2, xs, ys, xe, ye;
- float mag, outlen;
- if (findmark(&x1, &y1, &x2, &y2))
- {
- xs = x2-markx;
- ys = y2-marky;
- xe = x1-markx;
- ye = y1-marky;
- outlen = xs*xs+ys*ys;
- if (outlen != 0.0)
- {
- mag = sqrt((float)(xe*xe+ye*ye)/outlen);
- mag = (mag < 0.1) ? 0.1 : (mag > 10.0 ? 10.0 : mag);
- transform(mag, 0.0, 0.0, mag, 1);
- msgpost("magnify done");
- }
- msgpost("null magnify ignored");
- }
- }
-
- stretch()
- {
- int x1, y1, x2, y2, xs, ys, xe, ye;
- float xmag, ymag;
- if (findmark(&x1, &y1, &x2, &y2))
- {
- xs = x2-markx;
- ys = y2-marky;
- xe = x1-markx;
- ye = y1-marky;
- xmag = (xs == 0) ? 1.0 : (float)(xe)/xs;
- ymag = (ys == 0) ? 1.0 : (float)(ye)/ys;
- xmag = (xmag < 0.1) ? 0.1 : (xmag > 10.0 ? 10.0 : xmag);
- ymag = (ymag < 0.1) ? 0.1 : (ymag > 10.0 ? 10.0 : ymag);
- transform(xmag, 0.0, 0.0, ymag, 1);
- msgpost("stretch done");
- }
- }
-
- rotate()
- {
- int x1, y1, x2, y2, xs, ys, xe, ye;
- float s, c, hy;
- if (findmark(&x1, &y1, &x2, &y2))
- {
- xs = x2-markx;
- ys = y2-marky;
- xe = x1-markx;
- ye = y1-marky;
- hy = sqrt((float)( (xs*xs + ys*ys) * (xe*xe + ye*ye) ));
- if (hy != 0.0)
- {
- c = (xs*xe+ys*ye)/hy;
- s = (xs*ye-xe*ys)/hy;
- transform(c, -s, s, c, 0);
- msgpost("rotate done");
- }
- else msgpost("null rotation ignored");
- }
- }
-
- align()
- {
- int x1, y1, x2, y2, xs, ys, xe, ye, scale;
- float m11, m12, m21, m22, det;
- if (findmark(&x1, &y1, &x2, &y2))
- {
- xs = x2-markx;
- ys = y2-marky;
- xe = x1-markx;
- ye = y1-marky;
- scale = MAX(MAX(ABS(xs),ABS(ys)),MAX(ABS(xe),ABS(ye)));
- det = xe*ys - xs*ye;
- m11 = (float)( ys*scale)/det;
- m12 = (float)(-xs*scale)/det;
- m21 = (float)(-ye*scale)/det;
- m22 = (float)( xe*scale)/det;
- transform(m11, m12, m21, m22, 1);
- msgpost("align done");
- }
- }
-
- findmark(x1, y1, x2, y2)
- int *x1, *y1, *x2, *y2;
- {
- int i, s, e, arrow, straight;
- arrow = straight = 0;
- if (!markon)
- {
- msgpost("transform: no mark present");
- return(0);
- }
- else
- {
- forobjects
- {
- if (Otype != LINE) continue;
- s = (Oxs == markx) && (Oys == marky);
- e = (Oxe == markx) && (Oye == marky);
- if (s || e)
- {
- switch (Oalign)
- {
- case ALIGNCENT: *x1 = s ? Oxe : Oxs;
- *y1 = s ? Oye : Oys;
- straight++;
- break;
- case ALIGNLEFT: if (s)
- {
- msgpost("transform: arrowhead at origin");
- return(0);
- }
- *x2 = Oxs;
- *y2 = Oys;
- arrow++;
- break;
- case ALIGNRGHT: if (e)
- {
- msgpost("transform: arrowhead at origin");
- return(0);
- }
- *x2 = Oxe;
- *y2 = Oye;
- arrow++;
- break;
- }
- }
- }
- }
- if ((arrow == 1) && (straight == 1)) return(1);
- /*
- * errors
- */
- if (arrow+straight == 0)
- msgpost("transform: no basis vectors at mark");
- else if (arrow != 1)
- msgpost("transform: exactly one arrow basis vector needed");
- else if (straight != 1)
- msgpost("transform: exactly one non-arrow basis vector needed");
- return(0);
- }
-