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