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 / ((double)(y2 - y_1));
 57:   else R_y2_y_1 = 0.0;
 58:   if (y3 != y_1) R_y3_y_1 = 1.0 / ((double)(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 = ((double)(y - y_1)) * R_y2_y_1;
 68:     lc    = (int)(lfrac * (t2_t1) + t1);
 69:     lx    = (int)(lfrac * (x2_x1) + x1);
 70:     /* Right color is (y-y_1)/(y3-y_1) * (t3-t1) + t1 */
 71:     rfrac = ((double)(y - y_1)) * R_y3_y_1;
 72:     rc    = (int)(rfrac * (t3_t1) + t1);
 73:     rx    = (int)(rfrac * (x3_x1) + 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 / ((double)(y3 - y2));
110:   else R_y3_y2 = 0.0;
111:   if (y3 != y_1) R_y3_y_1 = 1.0 / ((double)(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 = ((double)(y - y2)) * R_y3_y2;
118:     lc    = (int)(lfrac * (t3_t2) + t2);
119:     lx    = (int)(lfrac * (x3_x2) + x2);
120:     /* Right color is (y-y_1)/(y3-y_1) * (t3-t1) + t1 */
121:     rfrac = ((double)(y - y_1)) * R_y3_y_1;
122:     rc    = (int)(rfrac * (t3_t1) + t1);
123:     rx    = (int)(rfrac * (x3_x1) + 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: }