Next: RECView.h Header Listing Up: The REC Header and Previous: REC-F data flow

## REC operators and predicates

The only thing complicated amongst the REC definitions is the scheme for reflecting a polygon in one of its edges. To begin with, the formula for a line between two points (x1,y1) and (x2,y2) in a plane is conveniently written in in the form

(x2 - x1) y = (y2 - y1) x + (y1 x2 - y2 x1).

Matrixwise, the formula for reflecting the point (x0,y0) in the line a x + b y + c = 0 is

These two formulas have been transcribed into C and coded into the function refen(n), which consults the list of vertices of the current polygon to get edge n to perform the reflection.

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*             definition of REC operators and predicates                  */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

int rec(z) char *z; {if (rec_c(z,rprg,PLEN,dtbl)==1) rec_x(rprg);}

void ropln() {edge--; refen((edge+pgon) % pgon);}   /* reflect in last edge */

void roplo() {int i;				      /* offset the polygon */
for (i=0; i<pgon; i++)
pointbase[i][0]=pointbase[i][0]/pointbase[i][2]+20.0;
pointbase[i][1]=pointbase[i][1]/pointbase[i][2];
pointbase[i][2]=1.0;
}

void roplp() {                                               /* pop fpolygon */
if (plev<0) return;
roplo();
plev--;
}

void ropuc() {int i;                                        /* draw polygon */
PSsetgray(NX_BLACK);
PSmoveto(pointbase[pgon-1][0]/pointbase[pgon-1][2]+exoff,
pointbase[pgon-1][1]/pointbase[pgon-1][2]+wyoff);
for (i=0; i<pgon; i++) {
PSlineto(pointbase[i][0]/pointbase[i][2]+exoff,
pointbase[i][1]/pointbase[i][2]+wyoff);}
}

void ropuk() {int i, j;                                /* turn 60 deg right */
pgon = 3;
edge = 0;
for (i=0; i<pgon; i++) for (j=0; j<3; j++) pointbase[i][j] = isosrt[i][j];
}

void ropul() {int i, j;                                /* turn 60 deg right */
pgon = 3;
edge = 0;
for (i=0; i<pgon; i++) for (j=0; j<3; j++) pointbase[i][j] = halftr[i][j];
}

void ropun() {edge++; refen(edge % pgon);}           /* reflect in next edge */

void ropuo() {int i, j;                                 /* read top  polygon */
for (i=0; i<pgon; i++) for (j=0; j<3; j++)
pointbase[i][j]=polystack[plev][i][j];
}

void ropup() {int i, j;                                      /* push polygon */
plev++;
if (plev>=HMAX) return;
for (i=0; i<pgon; i++) for (j=0; j<3; j++)
polystack[plev][i][j]=pointbase[i][j];
}

void refen(nn) int nn; {                                /* reflect in edge n */
int i, m, n;
double aa, bb, cc, x, y, ex1, ex2, wy1, wy2, rr, m11, m12, m21, m22;
n = nn % pgon;
m = (n + 1) % pgon;
ex1 = pointbase[n][0]/pointbase[n][2];
ex2 = pointbase[m][0]/pointbase[m][2];
wy1 = pointbase[n][1]/pointbase[n][2];
wy2 = pointbase[m][1]/pointbase[m][2];
aa = wy1 - wy2;
bb = ex2 - ex1;
cc = wy2 * ex1 - wy1 * ex2;
rr = aa * aa + bb * bb;
m11 =  bb * bb - aa * aa;
m12 = -2.0 * aa * bb;
m21 =  m12;
m22 = -m11;
for (i=0; i<pgon; i++) {
x = (m11 * pointbase[i][0] + m12 * pointbase[i][1])
/pointbase[i][2];
y = (m21 * pointbase[i][0] + m22 * pointbase[i][1])
/pointbase[i][2];
pointbase[i][0] = (x - 2.0 * aa * cc)/rr;
pointbase[i][1] = (y - 2.0 * bb * cc)/rr;
pointbase[i][2] = 1.0;
}
}

void ropur() {int n;                                    /* reflect in edge n */
n = *r_pc++ - '0';
if (n < 0 || n > pgon-1) return; else {edge=n; refen(n);};
}

void roput() {int i, j;                                           /* rhombus */
pgon = 4;
edge = 0;
for (i=0; i<pgon; i++) for (j=0; j<3; j++) pointbase[i][j]=rhombus[i][j];
}

void ropuu() {int i, j;                                        /* snubsquare */
pgon = 5;
edge = 0;
for (i=0; i<pgon; i++) for (j=0; j<3; j++) pointbase[i][j]=snubsq[i][j];
}

void ropux() {int c, i; double th, dth;                   /* regular polygon */
c = *r_pc++ - '0';
if (c < 1 || c > 12) return;
pgon = c;
edge = pgon-1;
dth = (2 * PI)/((double)(pgon));
for (i=0, th=-0.5*dth; i<pgon; i++, th+=dth) {
pointbase[i][0] = cos(th);
pointbase[i][1] = sin(th);
pointbase[i][2] = 1.0/scale;
}
}