1ae7e3b26SLisandro Dalcin 2ae7e3b26SLisandro Dalcin /* 3ae7e3b26SLisandro Dalcin Code for drawing color interpolated triangles using X-windows. 4ae7e3b26SLisandro Dalcin */ 5ae7e3b26SLisandro Dalcin #include <../src/sys/classes/draw/impls/x/ximpl.h> 6ae7e3b26SLisandro Dalcin 709440f25SLisandro Dalcin PETSC_INTERN PetscErrorCode PetscDrawInterpolatedTriangle_X(PetscDraw_X *, int, int, int, int, int, int, int, int, int); 809440f25SLisandro Dalcin 9ae7e3b26SLisandro Dalcin #define SHIFT_VAL 6 10ae7e3b26SLisandro Dalcin 11d71ae5a4SJacob Faibussowitsch 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) 12d71ae5a4SJacob Faibussowitsch { 13ae7e3b26SLisandro Dalcin PetscReal rfrac, lfrac; 14ae7e3b26SLisandro Dalcin PetscReal R_y2_y_1, R_y3_y_1, R_y3_y2; 15ae7e3b26SLisandro Dalcin int lc, rc = 0, lx, rx = 0, xx, y, c; 16ae7e3b26SLisandro Dalcin int rc_lc, rx_lx, t2_t1, x2_x1, t3_t1, x3_x1, t3_t2, x3_x2; 17ae7e3b26SLisandro Dalcin 18ae7e3b26SLisandro Dalcin PetscFunctionBegin; 19ae7e3b26SLisandro Dalcin /* 20ae7e3b26SLisandro Dalcin Is triangle even visible in window? 21ae7e3b26SLisandro Dalcin */ 223ba16761SJacob Faibussowitsch if (x1 < 0 && x2 < 0 && x3 < 0) PetscFunctionReturn(PETSC_SUCCESS); 233ba16761SJacob Faibussowitsch if (y_1 < 0 && y2 < 0 && y3 < 0) PetscFunctionReturn(PETSC_SUCCESS); 243ba16761SJacob Faibussowitsch if (x1 > win->w && x2 > win->w && x3 > win->w) PetscFunctionReturn(PETSC_SUCCESS); 253ba16761SJacob Faibussowitsch if (y_1 > win->h && y2 > win->h && y3 > win->h) PetscFunctionReturn(PETSC_SUCCESS); 26ae7e3b26SLisandro Dalcin 27ae7e3b26SLisandro Dalcin t1 = t1 << SHIFT_VAL; 28ae7e3b26SLisandro Dalcin t2 = t2 << SHIFT_VAL; 29ae7e3b26SLisandro Dalcin t3 = t3 << SHIFT_VAL; 30ae7e3b26SLisandro Dalcin 31ae7e3b26SLisandro Dalcin /* Sort the vertices */ 329371c9d4SSatish Balay #define SWAP(a, b) \ 33*a8f51744SPierre Jolivet do { \ 349371c9d4SSatish Balay int _a; \ 359371c9d4SSatish Balay _a = a; \ 369371c9d4SSatish Balay a = b; \ 379371c9d4SSatish Balay b = _a; \ 38*a8f51744SPierre Jolivet } while (0) 39ae7e3b26SLisandro Dalcin if (y_1 > y2) { 409371c9d4SSatish Balay SWAP(y_1, y2); 419371c9d4SSatish Balay SWAP(t1, t2); 429371c9d4SSatish Balay SWAP(x1, x2); 43ae7e3b26SLisandro Dalcin } 44ae7e3b26SLisandro Dalcin if (y_1 > y3) { 459371c9d4SSatish Balay SWAP(y_1, y3); 469371c9d4SSatish Balay SWAP(t1, t3); 479371c9d4SSatish Balay SWAP(x1, x3); 48ae7e3b26SLisandro Dalcin } 49ae7e3b26SLisandro Dalcin if (y2 > y3) { 509371c9d4SSatish Balay SWAP(y2, y3); 519371c9d4SSatish Balay SWAP(t2, t3); 529371c9d4SSatish Balay SWAP(x2, x3); 53ae7e3b26SLisandro Dalcin } 54da81f932SPierre Jolivet /* This code is decidedly non-optimal; it is intended to be a start at 55ae7e3b26SLisandro Dalcin an implementation */ 56ae7e3b26SLisandro Dalcin 57ae7e3b26SLisandro Dalcin if (y2 != y_1) R_y2_y_1 = 1.0 / ((double)(y2 - y_1)); 58ae7e3b26SLisandro Dalcin else R_y2_y_1 = 0.0; 59ae7e3b26SLisandro Dalcin if (y3 != y_1) R_y3_y_1 = 1.0 / ((double)(y3 - y_1)); 60ae7e3b26SLisandro Dalcin else R_y3_y_1 = 0.0; 61ae7e3b26SLisandro Dalcin t2_t1 = t2 - t1; 62ae7e3b26SLisandro Dalcin x2_x1 = x2 - x1; 63ae7e3b26SLisandro Dalcin t3_t1 = t3 - t1; 64ae7e3b26SLisandro Dalcin x3_x1 = x3 - x1; 65ae7e3b26SLisandro Dalcin for (y = y_1; y <= y2; y++) { 66ae7e3b26SLisandro Dalcin /* PetscDraw a line with the correct color from t1-t2 to t1-t3 */ 67ae7e3b26SLisandro Dalcin /* Left color is (y-y_1)/(y2-y_1) * (t2-t1) + t1 */ 68ae7e3b26SLisandro Dalcin lfrac = ((double)(y - y_1)) * R_y2_y_1; 69ae7e3b26SLisandro Dalcin lc = (int)(lfrac * (t2_t1) + t1); 70ae7e3b26SLisandro Dalcin lx = (int)(lfrac * (x2_x1) + x1); 71ae7e3b26SLisandro Dalcin /* Right color is (y-y_1)/(y3-y_1) * (t3-t1) + t1 */ 72ae7e3b26SLisandro Dalcin rfrac = ((double)(y - y_1)) * R_y3_y_1; 73ae7e3b26SLisandro Dalcin rc = (int)(rfrac * (t3_t1) + t1); 74ae7e3b26SLisandro Dalcin rx = (int)(rfrac * (x3_x1) + x1); 75ae7e3b26SLisandro Dalcin /* PetscDraw the line */ 76ae7e3b26SLisandro Dalcin rc_lc = rc - lc; 77ae7e3b26SLisandro Dalcin rx_lx = rx - lx; 78ae7e3b26SLisandro Dalcin if (rx > lx) { 79ae7e3b26SLisandro Dalcin for (xx = lx; xx <= rx; xx++) { 80ae7e3b26SLisandro Dalcin c = (((xx - lx) * (rc_lc)) / (rx_lx) + lc) >> SHIFT_VAL; 81ae7e3b26SLisandro Dalcin PetscDrawXiSetColor(win, c); 82ae7e3b26SLisandro Dalcin XDrawPoint(win->disp, PetscDrawXiDrawable(win), win->gc.set, xx, y); 83ae7e3b26SLisandro Dalcin } 84ae7e3b26SLisandro Dalcin } else if (rx < lx) { 85ae7e3b26SLisandro Dalcin for (xx = lx; xx >= rx; xx--) { 86ae7e3b26SLisandro Dalcin c = (((xx - lx) * (rc_lc)) / (rx_lx) + lc) >> SHIFT_VAL; 87ae7e3b26SLisandro Dalcin PetscDrawXiSetColor(win, c); 88ae7e3b26SLisandro Dalcin XDrawPoint(win->disp, PetscDrawXiDrawable(win), win->gc.set, xx, y); 89ae7e3b26SLisandro Dalcin } 90ae7e3b26SLisandro Dalcin } else { 91ae7e3b26SLisandro Dalcin c = lc >> SHIFT_VAL; 92ae7e3b26SLisandro Dalcin PetscDrawXiSetColor(win, c); 93ae7e3b26SLisandro Dalcin XDrawPoint(win->disp, PetscDrawXiDrawable(win), win->gc.set, lx, y); 94ae7e3b26SLisandro Dalcin } 95ae7e3b26SLisandro Dalcin } 96ae7e3b26SLisandro Dalcin 97ae7e3b26SLisandro Dalcin /* For simplicity,"move" t1 to the intersection of t1-t3 with the line y=y2. 98ae7e3b26SLisandro Dalcin We take advantage of the previous iteration. */ 993ba16761SJacob Faibussowitsch if (y2 >= y3) PetscFunctionReturn(PETSC_SUCCESS); 100ae7e3b26SLisandro Dalcin if (y_1 < y2) { 101ae7e3b26SLisandro Dalcin t1 = rc; 102ae7e3b26SLisandro Dalcin y_1 = y2; 103ae7e3b26SLisandro Dalcin x1 = rx; 104ae7e3b26SLisandro Dalcin 105ae7e3b26SLisandro Dalcin t3_t1 = t3 - t1; 106ae7e3b26SLisandro Dalcin x3_x1 = x3 - x1; 107ae7e3b26SLisandro Dalcin } 108ae7e3b26SLisandro Dalcin t3_t2 = t3 - t2; 109ae7e3b26SLisandro Dalcin x3_x2 = x3 - x2; 110ae7e3b26SLisandro Dalcin if (y3 != y2) R_y3_y2 = 1.0 / ((double)(y3 - y2)); 111ae7e3b26SLisandro Dalcin else R_y3_y2 = 0.0; 112ae7e3b26SLisandro Dalcin if (y3 != y_1) R_y3_y_1 = 1.0 / ((double)(y3 - y_1)); 113ae7e3b26SLisandro Dalcin else R_y3_y_1 = 0.0; 114ae7e3b26SLisandro Dalcin 115ae7e3b26SLisandro Dalcin for (y = y2; y <= y3; y++) { 116ae7e3b26SLisandro Dalcin /* PetscDraw a line with the correct color from t2-t3 to t1-t3 */ 117ae7e3b26SLisandro Dalcin /* Left color is (y-y_1)/(y2-y_1) * (t2-t1) + t1 */ 118ae7e3b26SLisandro Dalcin lfrac = ((double)(y - y2)) * R_y3_y2; 119ae7e3b26SLisandro Dalcin lc = (int)(lfrac * (t3_t2) + t2); 120ae7e3b26SLisandro Dalcin lx = (int)(lfrac * (x3_x2) + x2); 121ae7e3b26SLisandro Dalcin /* Right color is (y-y_1)/(y3-y_1) * (t3-t1) + t1 */ 122ae7e3b26SLisandro Dalcin rfrac = ((double)(y - y_1)) * R_y3_y_1; 123ae7e3b26SLisandro Dalcin rc = (int)(rfrac * (t3_t1) + t1); 124ae7e3b26SLisandro Dalcin rx = (int)(rfrac * (x3_x1) + x1); 125ae7e3b26SLisandro Dalcin /* PetscDraw the line */ 126ae7e3b26SLisandro Dalcin rc_lc = rc - lc; 127ae7e3b26SLisandro Dalcin rx_lx = rx - lx; 128ae7e3b26SLisandro Dalcin if (rx > lx) { 129ae7e3b26SLisandro Dalcin for (xx = lx; xx <= rx; xx++) { 130ae7e3b26SLisandro Dalcin c = (((xx - lx) * (rc_lc)) / (rx_lx) + lc) >> SHIFT_VAL; 131ae7e3b26SLisandro Dalcin PetscDrawXiSetColor(win, c); 132ae7e3b26SLisandro Dalcin XDrawPoint(win->disp, PetscDrawXiDrawable(win), win->gc.set, xx, y); 133ae7e3b26SLisandro Dalcin } 134ae7e3b26SLisandro Dalcin } else if (rx < lx) { 135ae7e3b26SLisandro Dalcin for (xx = lx; xx >= rx; xx--) { 136ae7e3b26SLisandro Dalcin c = (((xx - lx) * (rc_lc)) / (rx_lx) + lc) >> SHIFT_VAL; 137ae7e3b26SLisandro Dalcin PetscDrawXiSetColor(win, c); 138ae7e3b26SLisandro Dalcin XDrawPoint(win->disp, PetscDrawXiDrawable(win), win->gc.set, xx, y); 139ae7e3b26SLisandro Dalcin } 140ae7e3b26SLisandro Dalcin } else { 141ae7e3b26SLisandro Dalcin c = lc >> SHIFT_VAL; 142ae7e3b26SLisandro Dalcin PetscDrawXiSetColor(win, c); 143ae7e3b26SLisandro Dalcin XDrawPoint(win->disp, PetscDrawXiDrawable(win), win->gc.set, lx, y); 144ae7e3b26SLisandro Dalcin } 145ae7e3b26SLisandro Dalcin } 1463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 147ae7e3b26SLisandro Dalcin } 148