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