|
|
1.1 root 1: /************************************************************************\
2: *
3: * MODULE: PAINT.C
4: *
5: * PURPOSE: This is the module responsible for painting the SPINCUBE
6: * custom control. When Paint() is called, the SPINCUBEINFO
7: * associated with the calling window is queried; this will
8: * provide the current X, Y, and Z rotation angles for the
9: * polyhedron we'll draw. Using these angles we compute the
10: * 3x2 transformation matrix (there's no need for a 3x3
11: * matrix since we never look at the Z-values of tranformed
12: * points). Next, we compute the normalized polyhedron
13: * vertices based on our current window size, and then
14: * tranform them the using the above matrix. We begin draw-
15: * ing by erasing the window and drawing an outline. Then
16: * we walk through the facet list, drawing each facet whose
17: * outward normal faces us (using parallel projection).
18: *
19: * FUNCTIONS: Paint() - the paint routine
20: * ComputeXform() - computes 3x2 trnaformation matrix
21: * given x, y, and z rotation angles
22: * XformVertices() - transforms normalized polyhedron
23: * vertices using above matrix
24: *
25: \************************************************************************/
26:
27: #include <windows.h>
28: #include <math.h>
29: #include "spincube.h"
30: #include "paint.h"
31:
32:
33:
34: /************************************************************************\
35: *
36: * FUNCTION: Paint
37: *
38: * INPUTS: hWnd - Handle of the window to draw into.
39: *
40: * GLOBAL VARS: m - Contains transformation matrix.
41: * v - Vertices of normalized polyhedron.
42: * xv - Contains points to transform; results stored here.
43: * facets - A list if integers (indexes into xv) describing
44: * the facets of the polyhedron.
45: *
46: * COMMENTS: Draws a polyhedron in the window.
47: *
48: \************************************************************************/
49:
50: void Paint (HWND hWnd)
51: {
52: HANDLE hSCI;
53: PSPINCUBEINFO pSCI;
54: RECT rect;
55: int i;
56: LONG scale;
57: PAINTSTRUCT ps;
58: HBRUSH hBrush, hBrushSave;
59: int facetIndex, numPoints;
60: POINT polygn[MAX_POINTS_PER_FACET];
61: POINT vector1, vector2;
62: COLORREF crColor;
63:
64: hSCI = (HANDLE) GetWindowLong (hWnd, GWL_SPINCUBEDATA);
65: pSCI = (PSPINCUBEINFO) LocalLock (hSCI);
66:
67: ComputeXform (pSCI->xRotAngle, pSCI->yRotAngle, pSCI->zRotAngle);
68:
69: /**********************************************************************\
70: * If inMotion increment the rotation angles and release the memory
71: \**********************************************************************/
72:
73: if (pSCI->inMotion)
74: {
75: if ((pSCI->xRotAngle += XROT_INCREMENT) > (float) 6.28)
76: pSCI->xRotAngle = (float) 0.0;
77: if ((pSCI->yRotAngle += YROT_INCREMENT) > (float) 6.28)
78: pSCI->yRotAngle = (float) 0.0;
79: if ((pSCI->zRotAngle += ZROT_INCREMENT) > (float) 6.28)
80: pSCI->zRotAngle = (float) 0.0;
81: }
82: LocalUnlock (hSCI);
83:
84: GetWindowRect (hWnd, &rect);
85:
86: /**********************************************************************\
87: * The rectangle we get back is in Desktop coordinates, so we need to
88: * modify it to reflect coordinates relative to this window.
89: \**********************************************************************/
90:
91: rect.right -= rect.left;
92: rect.bottom -= rect.top;
93: rect.left = rect.top = 0;
94:
95: /**********************************************************************\
96: * Determine a "best fit" scale factor for our polyhedron
97: \**********************************************************************/
98:
99: scale = (rect.right > rect.bottom) ? rect.bottom/4 : rect.right/4;
100: for (i = 0; i < NUMVERTICES; i++)
101: {
102: xv[i] = v[i];
103: xv[i].x *= scale;
104: xv[i].y *= scale;
105: xv[i].z *= scale;
106: }
107:
108: XformVertices (rect.right/2, rect.bottom/2);
109:
110: BeginPaint (hWnd, &ps);
111:
112: /**********************************************************************\
113: * Draw the window frame & background
114: \**********************************************************************/
115:
116: SelectObject (ps.hdc, GetStockObject (GRAY_BRUSH));
117: Rectangle (ps.hdc, (int)rect.left, (int)rect.top, (int)rect.right,
118: (int)rect.bottom);
119:
120: /**********************************************************************\
121: * Draw the polyhedron. We'll walk through the facets list and compute
122: * the normal for each facet- if the normal has z > 0, then the facet
123: * faces us and we'll draw it. Note that this algorithim is ONLY valid
124: * for scenes with a single, convex polyhedron.
125: \**********************************************************************/
126:
127: crColor = 0x00000f;
128:
129: for (i = 0, facetIndex = 0; i < NUMFACETS; i++)
130: {
131: vector1.x = xv[facets[facetIndex + 1]].x - xv[facets[facetIndex]].x;
132: vector1.y = xv[facets[facetIndex + 1]].y - xv[facets[facetIndex]].y;
133: vector2.x = xv[facets[facetIndex + 2]].x - xv[facets[facetIndex + 1]].x;
134: vector2.y = xv[facets[facetIndex + 2]].y - xv[facets[facetIndex + 1]].y;
135:
136: for (numPoints = 0; facets[facetIndex] != -1; numPoints++, facetIndex++)
137: {
138: polygn[numPoints].x = xv[facets[facetIndex]].x;
139: polygn[numPoints].y = xv[facets[facetIndex]].y;
140: }
141:
142: crColor = crColor << 4;
143:
144: facetIndex++; /* skip over the -1's in the facets list */
145: if ((vector1.x*vector2.y - vector1.y*vector2.x) > 0)
146: {
147: hBrush = CreateSolidBrush (crColor);
148: hBrushSave = (HBRUSH) SelectObject (ps.hdc, hBrush);
149:
150: Polygon (ps.hdc, &polygn[0], numPoints);
151:
152: SelectObject (ps.hdc, hBrushSave);
153: DeleteObject (hBrush);
154:
155: }
156: }
157: EndPaint (hWnd, &ps);
158: }
159:
160:
161:
162: /************************************************************************\
163: *
164: * FUNCTION: ComputeXform
165: *
166: * INPUTS: xRotAngle - Angle to rotate about X axis.
167: * yRotAngle - Angle to rotate about Y axis.
168: * zRotAngle - Angle to rotate about Z axis.
169: *
170: * GLOBAL VARS: m - Resulting transformation stored here.
171: *
172: * COMMENTS: Computes a 3x2 tranformation matrix which rotates about
173: * the Z axis, the Y axis, and the X axis, respectively.
174: *
175: \************************************************************************/
176:
177: void ComputeXform (float xRotAngle, float yRotAngle, float zRotAngle)
178: {
179: float sinX, cosX, sinY, cosY, sinZ, cosZ;
180:
181: sinX = (float) sin ((double) xRotAngle);
182: cosX = (float) cos ((double) xRotAngle);
183: sinY = (float) sin ((double) yRotAngle);
184: cosY = (float) cos ((double) yRotAngle);
185: sinZ = (float) sin ((double) zRotAngle);
186: cosZ = (float) cos ((double) zRotAngle);
187:
188: m[0][0] = cosY*cosZ;
189: m[0][1] = -cosY*sinZ;
190: m[0][2] = sinY;
191: m[1][0] = sinX*sinY*cosZ + cosX*sinZ;
192: m[1][1] = -sinX*sinY*sinZ + cosX*cosZ;
193: m[1][2] = -sinX*cosY;
194: }
195:
196:
197:
198: /************************************************************************\
199: *
200: * FUNCTION: XformVertices
201: *
202: * INPUTS: xCenterWindow - Horizontal midpoint of the window.
203: * yCenterWindow - Vertical midpoint of the window.
204: *
205: * GLOBAL VARS: m - Contains transformation matrix.
206: * xv - Contains points to transform; results stored here.
207: *
208: * COMMENTS: Points are computed as: xv[i]' = m * xv[i].
209: * The values xCenterWindow and yCenterWindow are then added
210: * to translate each point so that it positioned relative to
211: * the center of the window.
212: *
213: \************************************************************************/
214:
215: void XformVertices (int xCenterWindow, int yCenterWindow)
216: {
217: int i;
218:
219: for (i = 0; i < NUMVERTICES; i++)
220: {
221: LONG tempX;
222:
223: tempX = (LONG) (m[0][0]*xv[i].x + m[0][1]*xv[i].y + m[0][2]*xv[i].z)
224: + xCenterWindow;
225: xv[i].y = (LONG) (m[1][0]*xv[i].x + m[1][1]*xv[i].y + m[1][2]*xv[i].z)
226: + yCenterWindow;
227: xv[i].x = tempX;
228: }
229: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.