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