Actual source code: xtone.c


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

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

  9: #define SHIFT_VAL 6

 11: 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)
 12: {
 13:   PetscReal rfrac,lfrac;
 14:   PetscReal R_y2_y_1,R_y3_y_1,R_y3_y2;
 15:   int       lc,rc = 0,lx,rx = 0,xx,y,c;
 16:   int       rc_lc,rx_lx,t2_t1,x2_x1,t3_t1,x3_x1,t3_t2,x3_x2;

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

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

 30:   /* Sort the vertices */
 31: #define SWAP(a,b) {int _a; _a=a; a=b; b=_a;}
 32:   if (y_1 > y2) {
 33:     SWAP(y_1,y2);SWAP(t1,t2); SWAP(x1,x2);
 34:   }
 35:   if (y_1 > y3) {
 36:     SWAP(y_1,y3);SWAP(t1,t3); SWAP(x1,x3);
 37:   }
 38:   if (y2 > y3) {
 39:     SWAP(y2,y3);SWAP(t2,t3); SWAP(x2,x3);
 40:   }
 41:   /* This code is decidely non-optimal; it is intended to be a start at
 42:    an implementation */

 44:   if (y2 != y_1) R_y2_y_1 = 1.0/((double)(y2-y_1));
 45:   else R_y2_y_1 = 0.0;
 46:   if (y3 != y_1) R_y3_y_1 = 1.0/((double)(y3-y_1));
 47:   else R_y3_y_1 = 0.0;
 48:   t2_t1 = t2 - t1;
 49:   x2_x1 = x2 - x1;
 50:   t3_t1 = t3 - t1;
 51:   x3_x1 = x3 - x1;
 52:   for (y=y_1; y<=y2; y++) {
 53:     /* PetscDraw a line with the correct color from t1-t2 to t1-t3 */
 54:     /* Left color is (y-y_1)/(y2-y_1) * (t2-t1) + t1 */
 55:     lfrac = ((double)(y-y_1)) * R_y2_y_1;
 56:     lc    = (int)(lfrac * (t2_t1) + t1);
 57:     lx    = (int)(lfrac * (x2_x1) + x1);
 58:     /* Right color is (y-y_1)/(y3-y_1) * (t3-t1) + t1 */
 59:     rfrac = ((double)(y - y_1)) * R_y3_y_1;
 60:     rc    = (int)(rfrac * (t3_t1) + t1);
 61:     rx    = (int)(rfrac * (x3_x1) + x1);
 62:     /* PetscDraw the line */
 63:     rc_lc = rc - lc;
 64:     rx_lx = rx - lx;
 65:     if (rx > lx) {
 66:       for (xx=lx; xx<=rx; xx++) {
 67:         c = (((xx-lx) * (rc_lc)) / (rx_lx) + lc) >> SHIFT_VAL;
 68:         PetscDrawXiSetColor(win,c);
 69:         XDrawPoint(win->disp,PetscDrawXiDrawable(win),win->gc.set,xx,y);
 70:       }
 71:     } else if (rx < lx) {
 72:       for (xx=lx; xx>=rx; xx--) {
 73:         c = (((xx-lx) * (rc_lc)) / (rx_lx) + lc) >> SHIFT_VAL;
 74:         PetscDrawXiSetColor(win,c);
 75:         XDrawPoint(win->disp,PetscDrawXiDrawable(win),win->gc.set,xx,y);
 76:       }
 77:     } else {
 78:       c = lc >> SHIFT_VAL;
 79:       PetscDrawXiSetColor(win,c);
 80:       XDrawPoint(win->disp,PetscDrawXiDrawable(win),win->gc.set,lx,y);
 81:     }
 82:   }

 84:   /* For simplicity,"move" t1 to the intersection of t1-t3 with the line y=y2.
 85:      We take advantage of the previous iteration. */
 86:   if (y2 >= y3) return 0;
 87:   if (y_1 < y2) {
 88:     t1  = rc;
 89:     y_1 = y2;
 90:     x1  = rx;

 92:     t3_t1 = t3 - t1;
 93:     x3_x1 = x3 - x1;
 94:   }
 95:   t3_t2 = t3 - t2;
 96:   x3_x2 = x3 - x2;
 97:   if (y3 != y2) R_y3_y2 = 1.0/((double)(y3-y2));
 98:   else R_y3_y2 = 0.0;
 99:   if (y3 != y_1) R_y3_y_1 = 1.0/((double)(y3-y_1));
100:   else R_y3_y_1 = 0.0;

102:   for (y=y2; y<=y3; y++) {
103:     /* PetscDraw a line with the correct color from t2-t3 to t1-t3 */
104:     /* Left color is (y-y_1)/(y2-y_1) * (t2-t1) + t1 */
105:     lfrac = ((double)(y-y2)) * R_y3_y2;
106:     lc    = (int)(lfrac * (t3_t2) + t2);
107:     lx    = (int)(lfrac * (x3_x2) + x2);
108:     /* Right color is (y-y_1)/(y3-y_1) * (t3-t1) + t1 */
109:     rfrac = ((double)(y - y_1)) * R_y3_y_1;
110:     rc    = (int)(rfrac * (t3_t1) + t1);
111:     rx    = (int)(rfrac * (x3_x1) + x1);
112:     /* PetscDraw the line */
113:     rc_lc = rc - lc;
114:     rx_lx = rx - lx;
115:     if (rx > lx) {
116:       for (xx=lx; xx<=rx; xx++) {
117:         c = (((xx-lx) * (rc_lc)) / (rx_lx) + lc) >> SHIFT_VAL;
118:         PetscDrawXiSetColor(win,c);
119:         XDrawPoint(win->disp,PetscDrawXiDrawable(win),win->gc.set,xx,y);
120:       }
121:     } else if (rx < lx) {
122:       for (xx=lx; xx>=rx; xx--) {
123:         c = (((xx-lx) * (rc_lc)) / (rx_lx) + lc) >> SHIFT_VAL;
124:         PetscDrawXiSetColor(win,c);
125:         XDrawPoint(win->disp,PetscDrawXiDrawable(win),win->gc.set,xx,y);
126:       }
127:     } else {
128:       c = lc >> SHIFT_VAL;
129:       PetscDrawXiSetColor(win,c);
130:       XDrawPoint(win->disp,PetscDrawXiDrawable(win),win->gc.set,lx,y);
131:     }
132:   }
133:   return 0;
134: }