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