1 2 /* 3 Code for drawing color interpolated triangles using X-windows. 4 */ 5 #include <../src/sys/classes/draw/impls/x/ximpl.h> 6 7 PETSC_INTERN PetscErrorCode PetscDrawInterpolatedTriangle_X(PetscDraw_X*,int,int,int,int,int,int,int,int,int); 8 9 #define SHIFT_VAL 6 10 11 #undef __FUNCT__ 12 #define __FUNCT__ "PetscDrawInterpolatedTriangle_X" 13 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) 14 { 15 PetscReal rfrac,lfrac; 16 PetscReal R_y2_y_1,R_y3_y_1,R_y3_y2; 17 int lc,rc = 0,lx,rx = 0,xx,y,c; 18 int rc_lc,rx_lx,t2_t1,x2_x1,t3_t1,x3_x1,t3_t2,x3_x2; 19 20 PetscFunctionBegin; 21 /* 22 Is triangle even visible in window? 23 */ 24 if (x1 < 0 && x2 < 0 && x3 < 0) PetscFunctionReturn(0); 25 if (y_1 < 0 && y2 < 0 && y3 < 0) PetscFunctionReturn(0); 26 if (x1 > win->w && x2 > win->w && x3 > win->w) PetscFunctionReturn(0); 27 if (y_1 > win->h && y2 > win->h && y3 > win->h) PetscFunctionReturn(0); 28 29 t1 = t1 << SHIFT_VAL; 30 t2 = t2 << SHIFT_VAL; 31 t3 = t3 << SHIFT_VAL; 32 33 /* Sort the vertices */ 34 #define SWAP(a,b) {int _a; _a=a; a=b; b=_a;} 35 if (y_1 > y2) { 36 SWAP(y_1,y2);SWAP(t1,t2); SWAP(x1,x2); 37 } 38 if (y_1 > y3) { 39 SWAP(y_1,y3);SWAP(t1,t3); SWAP(x1,x3); 40 } 41 if (y2 > y3) { 42 SWAP(y2,y3);SWAP(t2,t3); SWAP(x2,x3); 43 } 44 /* This code is decidely non-optimal; it is intended to be a start at 45 an implementation */ 46 47 if (y2 != y_1) R_y2_y_1 = 1.0/((double)(y2-y_1)); 48 else R_y2_y_1 = 0.0; 49 if (y3 != y_1) R_y3_y_1 = 1.0/((double)(y3-y_1)); 50 else R_y3_y_1 = 0.0; 51 t2_t1 = t2 - t1; 52 x2_x1 = x2 - x1; 53 t3_t1 = t3 - t1; 54 x3_x1 = x3 - x1; 55 for (y=y_1; y<=y2; y++) { 56 /* PetscDraw a line with the correct color from t1-t2 to t1-t3 */ 57 /* Left color is (y-y_1)/(y2-y_1) * (t2-t1) + t1 */ 58 lfrac = ((double)(y-y_1)) * R_y2_y_1; 59 lc = (int)(lfrac * (t2_t1) + t1); 60 lx = (int)(lfrac * (x2_x1) + x1); 61 /* Right color is (y-y_1)/(y3-y_1) * (t3-t1) + t1 */ 62 rfrac = ((double)(y - y_1)) * R_y3_y_1; 63 rc = (int)(rfrac * (t3_t1) + t1); 64 rx = (int)(rfrac * (x3_x1) + x1); 65 /* PetscDraw the line */ 66 rc_lc = rc - lc; 67 rx_lx = rx - lx; 68 if (rx > lx) { 69 for (xx=lx; xx<=rx; xx++) { 70 c = (((xx-lx) * (rc_lc)) / (rx_lx) + lc) >> SHIFT_VAL; 71 PetscDrawXiSetColor(win,c); 72 XDrawPoint(win->disp,PetscDrawXiDrawable(win),win->gc.set,xx,y); 73 } 74 } else if (rx < lx) { 75 for (xx=lx; xx>=rx; xx--) { 76 c = (((xx-lx) * (rc_lc)) / (rx_lx) + lc) >> SHIFT_VAL; 77 PetscDrawXiSetColor(win,c); 78 XDrawPoint(win->disp,PetscDrawXiDrawable(win),win->gc.set,xx,y); 79 } 80 } else { 81 c = lc >> SHIFT_VAL; 82 PetscDrawXiSetColor(win,c); 83 XDrawPoint(win->disp,PetscDrawXiDrawable(win),win->gc.set,lx,y); 84 } 85 } 86 87 /* For simplicity,"move" t1 to the intersection of t1-t3 with the line y=y2. 88 We take advantage of the previous iteration. */ 89 if (y2 >= y3) PetscFunctionReturn(0); 90 if (y_1 < y2) { 91 t1 = rc; 92 y_1 = y2; 93 x1 = rx; 94 95 t3_t1 = t3 - t1; 96 x3_x1 = x3 - x1; 97 } 98 t3_t2 = t3 - t2; 99 x3_x2 = x3 - x2; 100 if (y3 != y2) R_y3_y2 = 1.0/((double)(y3-y2)); 101 else R_y3_y2 = 0.0; 102 if (y3 != y_1) R_y3_y_1 = 1.0/((double)(y3-y_1)); 103 else R_y3_y_1 = 0.0; 104 105 for (y=y2; y<=y3; y++) { 106 /* PetscDraw a line with the correct color from t2-t3 to t1-t3 */ 107 /* Left color is (y-y_1)/(y2-y_1) * (t2-t1) + t1 */ 108 lfrac = ((double)(y-y2)) * R_y3_y2; 109 lc = (int)(lfrac * (t3_t2) + t2); 110 lx = (int)(lfrac * (x3_x2) + x2); 111 /* Right color is (y-y_1)/(y3-y_1) * (t3-t1) + t1 */ 112 rfrac = ((double)(y - y_1)) * R_y3_y_1; 113 rc = (int)(rfrac * (t3_t1) + t1); 114 rx = (int)(rfrac * (x3_x1) + x1); 115 /* PetscDraw the line */ 116 rc_lc = rc - lc; 117 rx_lx = rx - lx; 118 if (rx > lx) { 119 for (xx=lx; xx<=rx; xx++) { 120 c = (((xx-lx) * (rc_lc)) / (rx_lx) + lc) >> SHIFT_VAL; 121 PetscDrawXiSetColor(win,c); 122 XDrawPoint(win->disp,PetscDrawXiDrawable(win),win->gc.set,xx,y); 123 } 124 } else if (rx < lx) { 125 for (xx=lx; xx>=rx; xx--) { 126 c = (((xx-lx) * (rc_lc)) / (rx_lx) + lc) >> SHIFT_VAL; 127 PetscDrawXiSetColor(win,c); 128 XDrawPoint(win->disp,PetscDrawXiDrawable(win),win->gc.set,xx,y); 129 } 130 } else { 131 c = lc >> SHIFT_VAL; 132 PetscDrawXiSetColor(win,c); 133 XDrawPoint(win->disp,PetscDrawXiDrawable(win),win->gc.set,lx,y); 134 } 135 } 136 PetscFunctionReturn(0); 137 } 138