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