📄 paint.cpp
字号:
iX = pSCI->rcCubeBoundary.left < ps.rcPaint.left ?
pSCI->rcCubeBoundary.left : ps.rcPaint.left;
iY = pSCI->rcCubeBoundary.top < ps.rcPaint.top ?
pSCI->rcCubeBoundary.top : ps.rcPaint.top;
iCX = (pSCI->rcCubeBoundary.right > ps.rcPaint.right ?
pSCI->rcCubeBoundary.right : ps.rcPaint.right) - iX;
iCY = (pSCI->rcCubeBoundary.bottom > ps.rcPaint.bottom ?
pSCI->rcCubeBoundary.bottom : ps.rcPaint.bottom) - iY;
EndPaint(hwnd, &ps);
ps.hdc = GetDC(hwnd);
BitBlt(ps.hdc, iX, iY, iCX, iCY, pSCI->hdcCompat, iX, iY, SRCCOPY);
ReleaseDC(hwnd, ps.hdc);
}
/******************************************************************************\
*
* FUNCTION: TransformVertices
*
* INPUTS: hwnd - control window handle
* pWindowRect - pointer to RECT describing control's dimensions
* pSCI - pointer to control's SPINCUBEINFO structure
* fScaleFactor - scale factor for use in this window
*
\******************************************************************************/
void TransformVertices(
HWND hwnd,
RECT *pWindowRect,
PSPINCUBEINFO pSCI,
LONG lScaleFactor
)
{
int i;
int iWindowDepth = pWindowRect->right > pWindowRect->bottom ?
pWindowRect->right : pWindowRect->bottom;
RECT WindowRect;
float fDepthScale;
int iNewTranslationInc = (Random() % 10) + 2;
float fNewRotationInc = (float) 0.01 * ((Random() % 30) + 2);
WindowRect.left = - (WindowRect.right = pWindowRect->right >> 1);
WindowRect.top = - (WindowRect.bottom = pWindowRect->bottom >> 1);
//
// Initiailize the bounding rectangle with max/min vals
//
pSCI->rcCubeBoundary.left =
pSCI->rcCubeBoundary.top = 100000; // big positive value
pSCI->rcCubeBoundary.right =
pSCI->rcCubeBoundary.bottom = -100000; // small negative value
//
// First scale, then rotate, then translate each vertex.
// Keep track of the maximum & minimum values bounding the
// vertices in the x,y plane for use later in bounds checking.
//
// Note: we don't bother computing z values after the scale,
// as they are only really necessary for the rotation. If we
// were doing real bounds checking we'd need it, but this code
// simply uses the pSCI->iCurrentZTranslation to determine
// the z-boundaries.
//
for (i = 0; i < NUMVERTICES; i++)
{
LONG tempX;
//
// Copy the static vertices into a temp array
//
gXformedVertices[i] = gNormalizedVertices[i];
//
// The scale...
//
gXformedVertices[i].x *= lScaleFactor;
gXformedVertices[i].y *= lScaleFactor;
gXformedVertices[i].z *= lScaleFactor;
//
// The rotation...
//
ComputeRotationTransformation(pSCI->fCurrentXRotation,
pSCI->fCurrentYRotation,
pSCI->fCurrentZRotation);
tempX = (LONG) (gM[0][0] * gXformedVertices[i].x +
gM[0][1] * gXformedVertices[i].y +
gM[0][2] * gXformedVertices[i].z);
gXformedVertices[i].y = (LONG) (gM[1][0] * gXformedVertices[i].x +
gM[1][1] * gXformedVertices[i].y +
gM[1][2] * gXformedVertices[i].z);
gXformedVertices[i].x = tempX;
//
// The translation...
//
gXformedVertices[i].x += pSCI->iCurrentXTranslation;
gXformedVertices[i].y += pSCI->iCurrentYTranslation;
//
// Check if we have new max or min vals
//
if (pSCI->rcCubeBoundary.left > gXformedVertices[i].x)
{
pSCI->rcCubeBoundary.left = gXformedVertices[i].x;
}
if (pSCI->rcCubeBoundary.right < gXformedVertices[i].x)
{
pSCI->rcCubeBoundary.right = gXformedVertices[i].x;
}
if (pSCI->rcCubeBoundary.top > gXformedVertices[i].y)
{
pSCI->rcCubeBoundary.top = gXformedVertices[i].y;
}
if (pSCI->rcCubeBoundary.bottom < gXformedVertices[i].y)
{
pSCI->rcCubeBoundary.bottom = gXformedVertices[i].y;
}
}
//
// Now for some bounds checking, change translation & rotation increments
// if we hit a "wall". Also so the gbHitBoundary flag so we remember
// to flash the cube when we draw it.
//
if (pSCI->rcCubeBoundary.left < WindowRect.left)
{
pSCI->iCurrentXTranslationInc = iNewTranslationInc;
pSCI->fCurrentZRotationInc = fNewRotationInc;
}
else if (pSCI->rcCubeBoundary.right > WindowRect.right)
{
pSCI->iCurrentXTranslationInc = -iNewTranslationInc;
pSCI->fCurrentZRotationInc = -fNewRotationInc;
}
if (pSCI->rcCubeBoundary.top < WindowRect.top)
{
pSCI->iCurrentYTranslationInc = iNewTranslationInc;
pSCI->fCurrentXRotationInc = fNewRotationInc;
}
else if (pSCI->rcCubeBoundary.bottom > WindowRect.bottom)
{
pSCI->iCurrentYTranslationInc = -iNewTranslationInc;
pSCI->fCurrentXRotationInc = -fNewRotationInc;
}
if (pSCI->iCurrentZTranslation < (int) lScaleFactor<<1)
{
pSCI->iCurrentZTranslationInc = iNewTranslationInc;
pSCI->fCurrentYRotationInc = fNewRotationInc;
}
else if (pSCI->iCurrentZTranslation > (iWindowDepth - (int) lScaleFactor))
{
pSCI->iCurrentZTranslationInc = -iNewTranslationInc;
pSCI->fCurrentYRotationInc = -fNewRotationInc;
}
//
// Now a kludgy scale based on depth (iCurrentZTranslation) of the center
// point of the polyhedron
//
fDepthScale = ((float) iWindowDepth) /
((float) (iWindowDepth + pSCI->iCurrentZTranslation));
pSCI->rcCubeBoundary.left = (LONG)(fDepthScale* pSCI->rcCubeBoundary.left);
pSCI->rcCubeBoundary.right = (LONG)(fDepthScale* pSCI->rcCubeBoundary.right);
pSCI->rcCubeBoundary.top = (LONG)(fDepthScale* pSCI->rcCubeBoundary.top);
pSCI->rcCubeBoundary.bottom = (LONG)(fDepthScale* pSCI->rcCubeBoundary.bottom);
for (i = 0; i < NUMVERTICES; i++)
{
gXformedVertices[i].x = (LONG) (fDepthScale * gXformedVertices[i].x);
gXformedVertices[i].y = (LONG) (fDepthScale * gXformedVertices[i].y);
}
//
// If currently in motion then increment the current rotation & tranlation
//
if (IN_MOTION(hwnd))
{
pSCI->fCurrentXRotation += pSCI->fCurrentXRotationInc;
pSCI->fCurrentYRotation += pSCI->fCurrentYRotationInc;
pSCI->fCurrentZRotation += pSCI->fCurrentZRotationInc;
pSCI->iCurrentXTranslation += pSCI->iCurrentXTranslationInc;
pSCI->iCurrentYTranslation += pSCI->iCurrentYTranslationInc;
pSCI->iCurrentZTranslation += pSCI->iCurrentZTranslationInc;
}
//
// Up to this point all coordinates are relative to a window whose
// center is at (0,0). Now we'll translate appropriately...
//
pSCI->rcCubeBoundary.left += pWindowRect->right >> 1;
pSCI->rcCubeBoundary.right += pWindowRect->right >> 1;
pSCI->rcCubeBoundary.top += pWindowRect->bottom >> 1;
pSCI->rcCubeBoundary.bottom += pWindowRect->bottom >> 1;
for (i = 0; i < NUMVERTICES; i++)
{
gXformedVertices[i].x += pWindowRect->right >> 1;
gXformedVertices[i].y += pWindowRect->bottom >> 1;
}
//
// Since FillRect's are inclusive-exclusive (there'll be leftovers
// from the last cube we drew otherwise)...
//
pSCI->rcCubeBoundary.right++;
pSCI->rcCubeBoundary.bottom++;
//
// Finally, adjust the rcCubeBoundary such that it fits entirely within
// the acutal control window. The reason for this is that when calling
// InvalidateRect from SpincubeWndProc\case_WM_TIMER we may get
// a different PAINSTRUCT.rcPaint (since InvalidateRect clips the passed
// in rect to the window bounds) and our abouve test to memcmp() will
// fail.
//
if (pSCI->rcCubeBoundary.left < 0)
{
pSCI->rcCubeBoundary.left = 0;
}
if (pSCI->rcCubeBoundary.top < 0)
{
pSCI->rcCubeBoundary.top = 0;
}
if (pSCI->rcCubeBoundary.right > pWindowRect->right)
{
pSCI->rcCubeBoundary.right = pWindowRect->right;
}
if (pSCI->rcCubeBoundary.bottom > pWindowRect->bottom)
{
pSCI->rcCubeBoundary.bottom = pWindowRect->bottom;
}
}
/******************************************************************************\
*
* FUNCTION: ComputeRotationTransformation
*
* INPUTS: fRotationX - Angle to rotate about X axis.
* fRotationY - Angle to rotate about Y axis.
* fRotationZ - Angle to rotate about Z axis.
*
* COMMENTS: Computes a 3x2 tranformation matrix which rotates about
* the Z axis, the Y axis, and the X axis, respectively.
*
\******************************************************************************/
void ComputeRotationTransformation (
float fRotationX,
float fRotationY,
float fRotationZ
)
{
float sinX, cosX, sinY, cosY, sinZ, cosZ;
sinX = (float) sin ((double) fRotationX);
cosX = (float) cos ((double) fRotationX);
sinY = (float) sin ((double) fRotationY);
cosY = (float) cos ((double) fRotationY);
sinZ = (float) sin ((double) fRotationZ);
cosZ = (float) cos ((double) fRotationZ);
gM[0][0] = cosY*cosZ;
gM[0][1] = -cosY*sinZ;
gM[0][2] = sinY;
gM[1][0] = sinX*sinY*cosZ + cosX*sinZ;
gM[1][1] = -sinX*sinY*sinZ + cosX*cosZ;
gM[1][2] = -sinX*cosY;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -