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