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