|
|
Microsoft Windows NT Build 328 10-12-1992
/******************************************************************************\
*
* MODULE: PAINT.C
*
* PURPOSE: This is the module responsible for painting the SPINCUBE
* custom control. When Paint() is called, the SPINCUBEINFO
* associated with the calling window is queried; this will
* provide the current X, Y, and Z rotation angles for the
* polyhedron we'll draw. Using these angles we compute the
* 3x2 transformation matrix (there's no need for a 3x3
* matrix since we never look at the Z-values of tranformed
* points). Next, we compute the normalized polyhedron
* vertices based on our current window size, and then
* tranform them the using the above matrix. We begin draw-
* ing by erasing the window and drawing an outline. Then
* we walk through the facet list, drawing each facet whose
* outward normal faces us (using parallel projection).
*
* FUNCTIONS: Paint() - the paint routine
* ComputeXform() - computes 3x2 trnaformation matrix
* given x, y, and z rotation angles
* XformVertices() - transforms normalized polyhedron
* vertices using above matrix
*
*
* Microsoft Developer Support
* Copyright (c) 1992 Microsoft Corporation
*
\******************************************************************************/
#include <windows.h>
#include <math.h>
#include "spincube.h"
#include "paint.h"
/******************************************************************************\
*
* FUNCTION: Paint
*
* INPUTS: hWnd - Handle of the window to draw into.
*
* GLOBAL VARS: m - Contains transformation matrix.
* v - Vertices of normalized polyhedron.
* xv - Contains points to transform; results stored here.
* facets - A list if integers (indexes into xv) describing
* the facets of the polyhedron.
*
* COMMENTS: Draws a polyhedron in the window.
*
\******************************************************************************/
void Paint (HWND hWnd)
{
HANDLE hSCI;
PSPINCUBEINFO pSCI;
RECT rect;
int i;
LONG scale;
PAINTSTRUCT ps;
HBRUSH hBrush, hBrushSave;
int facetIndex, numPoints;
POINT polygn[MAX_POINTS_PER_FACET];
POINT vector1, vector2;
COLORREF crColor;
hSCI = (HANDLE) GetWindowLong (hWnd, GWL_SPINCUBEDATA);
pSCI = (PSPINCUBEINFO) LocalLock (hSCI);
ComputeXform (pSCI->xRotAngle, pSCI->yRotAngle, pSCI->zRotAngle);
//
// if inMotion increment the rotation angles and release the memory
//
if (pSCI->inMotion)
{
if ((pSCI->xRotAngle += XROT_INCREMENT) > (float) 6.28)
pSCI->xRotAngle = (float) 0.0;
if ((pSCI->yRotAngle += YROT_INCREMENT) > (float) 6.28)
pSCI->yRotAngle = (float) 0.0;
if ((pSCI->zRotAngle += ZROT_INCREMENT) > (float) 6.28)
pSCI->zRotAngle = (float) 0.0;
}
LocalUnlock (hSCI);
GetWindowRect (hWnd, &rect);
//
// The rectangle we get back is in Desktop coordinates, so we need to
// modify it to reflect coordinates relative to this window.
//
rect.right -= rect.left;
rect.bottom -= rect.top;
rect.left = rect.top = 0;
//
// Determine a "best fit" scale factor for our polyhedron
//
scale = (rect.right > rect.bottom) ? rect.bottom/4 : rect.right/4;
for (i = 0; i < NUMVERTICES; i++)
{
xv[i] = v[i];
xv[i].x *= scale;
xv[i].y *= scale;
xv[i].z *= scale;
}
XformVertices (rect.right/2, rect.bottom/2);
BeginPaint (hWnd, &ps);
//
// Draw the window frame & background
//
SelectObject (ps.hdc, GetStockObject (GRAY_BRUSH));
Rectangle (ps.hdc, (int)rect.left, (int)rect.top, (int)rect.right,
(int)rect.bottom);
//
// Draw the polyhedron. We'll walk through the facets list and compute
// the normal for each facet- if the normal has z > 0, then the facet
// faces us and we'll draw it. Note that this algorithim is ONLY valid
// for scenes with a single, convex polyhedron.
//
crColor = 0x00000f;
for (i = 0, facetIndex = 0; i < NUMFACETS; i++)
{
vector1.x = xv[facets[facetIndex + 1]].x - xv[facets[facetIndex]].x;
vector1.y = xv[facets[facetIndex + 1]].y - xv[facets[facetIndex]].y;
vector2.x = xv[facets[facetIndex + 2]].x - xv[facets[facetIndex + 1]].x;
vector2.y = xv[facets[facetIndex + 2]].y - xv[facets[facetIndex + 1]].y;
for (numPoints = 0; facets[facetIndex] != -1; numPoints++, facetIndex++)
{
polygn[numPoints].x = xv[facets[facetIndex]].x;
polygn[numPoints].y = xv[facets[facetIndex]].y;
}
crColor = crColor << 4;
facetIndex++; /* skip over the -1's in the facets list */
if ((vector1.x*vector2.y - vector1.y*vector2.x) > 0)
{
hBrush = CreateSolidBrush (crColor);
hBrushSave = (HBRUSH) SelectObject (ps.hdc, hBrush);
Polygon (ps.hdc, &polygn[0], numPoints);
SelectObject (ps.hdc, hBrushSave);
DeleteObject (hBrush);
}
}
EndPaint (hWnd, &ps);
}
/******************************************************************************\
*
* FUNCTION: ComputeXform
*
* INPUTS: xRotAngle - Angle to rotate about X axis.
* yRotAngle - Angle to rotate about Y axis.
* zRotAngle - Angle to rotate about Z axis.
*
* GLOBAL VARS: m - Resulting transformation stored here.
*
* COMMENTS: Computes a 3x2 tranformation matrix which rotates about
* the Z axis, the Y axis, and the X axis, respectively.
*
\******************************************************************************/
void ComputeXform (float xRotAngle, float yRotAngle, float zRotAngle)
{
float sinX, cosX, sinY, cosY, sinZ, cosZ;
sinX = (float) sin ((double) xRotAngle);
cosX = (float) cos ((double) xRotAngle);
sinY = (float) sin ((double) yRotAngle);
cosY = (float) cos ((double) yRotAngle);
sinZ = (float) sin ((double) zRotAngle);
cosZ = (float) cos ((double) zRotAngle);
m[0][0] = cosY*cosZ;
m[0][1] = -cosY*sinZ;
m[0][2] = sinY;
m[1][0] = sinX*sinY*cosZ + cosX*sinZ;
m[1][1] = -sinX*sinY*sinZ + cosX*cosZ;
m[1][2] = -sinX*cosY;
}
/******************************************************************************\
*
* FUNCTION: XformVertices
*
* INPUTS: xCenterWindow - Horizontal midpoint of the window.
* yCenterWindow - Vertical midpoint of the window.
*
* GLOBAL VARS: m - Contains transformation matrix.
* xv - Contains points to transform; results stored here.
*
* COMMENTS: Points are computed as: xv[i]' = m * xv[i].
* The values xCenterWindow and yCenterWindow are then added
* to translate each point so that it positioned relative to
* the center of the window.
*
\******************************************************************************/
void XformVertices (int xCenterWindow, int yCenterWindow)
{
int i;
for (i = 0; i < NUMVERTICES; i++)
{
LONG tempX;
tempX = (LONG) (m[0][0]*xv[i].x + m[0][1]*xv[i].y + m[0][2]*xv[i].z)
+ xCenterWindow;
xv[i].y = (LONG) (m[1][0]*xv[i].x + m[1][1]*xv[i].y + m[1][2]*xv[i].z)
+ yCenterWindow;
xv[i].x = tempX;
}
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.