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