next up previous
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

\begin{eqnarray*}\left[ \begin{array}{c} x'_0 \\ y'_0 \end{array} \right] & = & ...
...t[ \begin{array}{c} 2 a c \\ 2 b c \end{array} \right] \right).
\end{eqnarray*}


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;
                }
}



Microcomputadoras
2000-09-28