⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 paint.c

📁 <Win2k系统编程>源码.次数为国人自编,内容丰富,还是不错的.
💻 C
📖 第 1 页 / 共 2 页
字号:
*  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 = (rand() % 10) + 2;
  float  fNewRotationInc    = (float) 0.01 * ((rand() % 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 + -