xref: /petsc/src/sys/classes/draw/impls/x/xtone.c (revision a8f51744601f91dc30d5f98153b1ecd91eebb0e5)
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