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