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