Actual source code: xtone.c

      1: /*
      2:     Code for drawing color interpolated triangles using X-windows.
      3: */
      4: #include <../src/sys/classes/draw/impls/x/ximpl.h>

      6: PETSC_INTERN PetscErrorCode PetscDrawInterpolatedTriangle_X(PetscDraw_X *, int, int, int, int, int, int, int, int, int);

      8: #define SHIFT_VAL 6

     10: PetscErrorCode PetscDrawInterpolatedTriangle_X(PetscDraw_X *win, int x1, int y_1, int t1, int x2, int y2, int t2, int x3, int y3, int t3)
     11: {
     12:   PetscReal rfrac, lfrac;
     13:   PetscReal R_y2_y_1, R_y3_y_1, R_y3_y2;
     14:   int       lc, rc = 0, lx, rx = 0, xx, y, c;
     15:   int       rc_lc, rx_lx, t2_t1, x2_x1, t3_t1, x3_x1, t3_t2, x3_x2;

     17:   PetscFunctionBegin;
     18:   /*
     19:         Is triangle even visible in window?
     20:   */
     21:   if (x1 < 0 && x2 < 0 && x3 < 0) PetscFunctionReturn(PETSC_SUCCESS);
     22:   if (y_1 < 0 && y2 < 0 && y3 < 0) PetscFunctionReturn(PETSC_SUCCESS);
     23:   if (x1 > win->w && x2 > win->w && x3 > win->w) PetscFunctionReturn(PETSC_SUCCESS);
     24:   if (y_1 > win->h && y2 > win->h && y3 > win->h) PetscFunctionReturn(PETSC_SUCCESS);

     26:   t1 = t1 << SHIFT_VAL;
     27:   t2 = t2 << SHIFT_VAL;
     28:   t3 = t3 << SHIFT_VAL;

     30:   /* Sort the vertices */
     31: #define SWAP(a, b) \
     32:   do { \
     33:     int _a; \
     34:     _a = a; \
     35:     a  = b; \
     36:     b  = _a; \
     37:   } while (0)
     38:   if (y_1 > y2) {
     39:     SWAP(y_1, y2);
     40:     SWAP(t1, t2);
     41:     SWAP(x1, x2);
     42:   }
     43:   if (y_1 > y3) {
     44:     SWAP(y_1, y3);
     45:     SWAP(t1, t3);
     46:     SWAP(x1, x3);
     47:   }
     48:   if (y2 > y3) {
     49:     SWAP(y2, y3);
     50:     SWAP(t2, t3);
     51:     SWAP(x2, x3);
     52:   }
     53:   /* This code is decidedly non-optimal; it is intended to be a start at
     54:    an implementation */

     56:   if (y2 != y_1) R_y2_y_1 = 1.0 / ((PetscReal)(y2 - y_1));
     57:   else R_y2_y_1 = 0.0;
     58:   if (y3 != y_1) R_y3_y_1 = 1.0 / ((PetscReal)(y3 - y_1));
     59:   else R_y3_y_1 = 0.0;
     60:   t2_t1 = t2 - t1;
     61:   x2_x1 = x2 - x1;
     62:   t3_t1 = t3 - t1;
     63:   x3_x1 = x3 - x1;
     64:   for (y = y_1; y <= y2; y++) {
     65:     /* PetscDraw a line with the correct color from t1-t2 to t1-t3 */
     66:     /* Left color is (y-y_1)/(y2-y_1) * (t2-t1) + t1 */
     67:     lfrac = ((PetscReal)(y - y_1)) * R_y2_y_1;
     68:     lc    = (int)(lfrac * ((PetscReal)t2_t1) + (PetscReal)t1);
     69:     lx    = (int)(lfrac * ((PetscReal)x2_x1) + (PetscReal)x1);
     70:     /* Right color is (y-y_1)/(y3-y_1) * (t3-t1) + t1 */
     71:     rfrac = ((PetscReal)(y - y_1)) * R_y3_y_1;
     72:     rc    = (int)(rfrac * ((PetscReal)t3_t1) + (PetscReal)t1);
     73:     rx    = (int)(rfrac * ((PetscReal)x3_x1) + (PetscReal)x1);
     74:     /* PetscDraw the line */
     75:     rc_lc = rc - lc;
     76:     rx_lx = rx - lx;
     77:     if (rx > lx) {
     78:       for (xx = lx; xx <= rx; xx++) {
     79:         c = (((xx - lx) * (rc_lc)) / (rx_lx) + lc) >> SHIFT_VAL;
     80:         PetscDrawXiSetColor(win, c);
     81:         XDrawPoint(win->disp, PetscDrawXiDrawable(win), win->gc.set, xx, y);
     82:       }
     83:     } else if (rx < lx) {
     84:       for (xx = lx; xx >= rx; xx--) {
     85:         c = (((xx - lx) * (rc_lc)) / (rx_lx) + lc) >> SHIFT_VAL;
     86:         PetscDrawXiSetColor(win, c);
     87:         XDrawPoint(win->disp, PetscDrawXiDrawable(win), win->gc.set, xx, y);
     88:       }
     89:     } else {
     90:       c = lc >> SHIFT_VAL;
     91:       PetscDrawXiSetColor(win, c);
     92:       XDrawPoint(win->disp, PetscDrawXiDrawable(win), win->gc.set, lx, y);
     93:     }
     94:   }

     96:   /* For simplicity,"move" t1 to the intersection of t1-t3 with the line y=y2.
     97:      We take advantage of the previous iteration. */
     98:   if (y2 >= y3) PetscFunctionReturn(PETSC_SUCCESS);
     99:   if (y_1 < y2) {
    100:     t1  = rc;
    101:     y_1 = y2;
    102:     x1  = rx;

    104:     t3_t1 = t3 - t1;
    105:     x3_x1 = x3 - x1;
    106:   }
    107:   t3_t2 = t3 - t2;
    108:   x3_x2 = x3 - x2;
    109:   if (y3 != y2) R_y3_y2 = 1.0 / ((PetscReal)(y3 - y2));
    110:   else R_y3_y2 = 0.0;
    111:   if (y3 != y_1) R_y3_y_1 = 1.0 / ((PetscReal)(y3 - y_1));
    112:   else R_y3_y_1 = 0.0;

    114:   for (y = y2; y <= y3; y++) {
    115:     /* PetscDraw a line with the correct color from t2-t3 to t1-t3 */
    116:     /* Left color is (y-y_1)/(y2-y_1) * (t2-t1) + t1 */
    117:     lfrac = ((PetscReal)(y - y2)) * R_y3_y2;
    118:     lc    = (int)(lfrac * ((PetscReal)t3_t2) + (PetscReal)t2);
    119:     lx    = (int)(lfrac * ((PetscReal)x3_x2) + (PetscReal)x2);
    120:     /* Right color is (y-y_1)/(y3-y_1) * (t3-t1) + t1 */
    121:     rfrac = ((PetscReal)(y - y_1)) * R_y3_y_1;
    122:     rc    = (int)(rfrac * ((PetscReal)t3_t1) + (PetscReal)t1);
    123:     rx    = (int)(rfrac * ((PetscReal)x3_x1) + (PetscReal)x1);
    124:     /* PetscDraw the line */
    125:     rc_lc = rc - lc;
    126:     rx_lx = rx - lx;
    127:     if (rx > lx) {
    128:       for (xx = lx; xx <= rx; xx++) {
    129:         c = (((xx - lx) * (rc_lc)) / (rx_lx) + lc) >> SHIFT_VAL;
    130:         PetscDrawXiSetColor(win, c);
    131:         XDrawPoint(win->disp, PetscDrawXiDrawable(win), win->gc.set, xx, y);
    132:       }
    133:     } else if (rx < lx) {
    134:       for (xx = lx; xx >= rx; xx--) {
    135:         c = (((xx - lx) * (rc_lc)) / (rx_lx) + lc) >> SHIFT_VAL;
    136:         PetscDrawXiSetColor(win, c);
    137:         XDrawPoint(win->disp, PetscDrawXiDrawable(win), win->gc.set, xx, y);
    138:       }
    139:     } else {
    140:       c = lc >> SHIFT_VAL;
    141:       PetscDrawXiSetColor(win, c);
    142:       XDrawPoint(win->disp, PetscDrawXiDrawable(win), win->gc.set, lx, y);
    143:     }
    144:   }
    145:   PetscFunctionReturn(PETSC_SUCCESS);
    146: }