小弟正在用VC++写一个位图旋转的程序,但是看了它的理论后头都大了,书上是这样说的:
“设图像旋转前的中心坐标是(a,b),旋转后的中心坐标是(c,d)...”看到这里就很模糊了,书上
开始说的是让图像绕它的中心旋转,为什么它旋转后的中心坐标又不一样呢?应该都是(a,b)啊!而且,书上刚把图像从磁盘里读出来显示在屏幕上时,图像的左上角是和屏幕的左上角重合的。
而它旋转后图像没有被“遮住”一部分,而是向下和向右移动一点后完全显示出来的,请问
这样算是绕图像中心旋转吗?!谢谢!!

解决方案 »

  1.   

    给个现成的给你,看一下,关健是DC的位图不为空就可以搭/*-----------------------------------------------------------------------------    功    能:旋转图像(以中间点为原点转)    参数说明:iDegree为要旋转的度数    返 回 值:    说    明:  2006-10-27 16:22:41 pxx
      ---------------------------------------------------------------------------*/
    void CSafeDC::Rotate(int iDegree)
    {
    if ((iDegree % 360)  ==  0){
    return;
    }
    CBitmap *pBitmap = GetCurrentBitmap();
    BITMAP bitmap;
    if (pBitmap->GetBitmap(&bitmap) == 0) {
    TRACE("get BITMAP error!\n");
    return ;
    }

    int iBitCount = GetDeviceCaps(/*this->GetSafeHdc(),*/ BITSPIXEL)/8;
    int iTotalByte = bitmap.bmWidth * bitmap.bmHeight * iBitCount;
    BYTE *pSrcByte = new BYTE[iTotalByte];
    BYTE *pNewByte = new BYTE[iTotalByte];
    if (pSrcByte == NULL) {
    AfxMessageBox("allocate memry fail!");
    return ;
    }
    memset(pSrcByte, 0, sizeof(BYTE)*iTotalByte);
    memset(pNewByte, 0, sizeof(BYTE)*iTotalByte);
    // 取得前景位图数据
    int iGetCount = pBitmap->GetBitmapBits(iTotalByte, pSrcByte);
    TRACE("get :%d\n", iGetCount);
    int ibmHeight = bitmap.bmHeight;
    int ibmWidth = bitmap.bmWidth;
    int iHalfHeight = ibmHeight/2;
    int iHalfWidth = ibmWidth/2;
    float x2=0.0;
    float y2=0.0;
    for(int i = 0; i < ibmHeight; i++)
    {
    for(int j = 0; j < ibmWidth; j++)
    {
    // i,j为目标,找到他要取的数据点
    float x1 = j - iHalfWidth; // 转为数学座标系
    float y1 = iHalfHeight - i; // 转为数学座标系
    TurnDegree(iDegree, x1, y1, x2, y2);
    int iX2 = x2 + iHalfWidth/* + 0.5*/; // 转为屏幕坐标
    int iY2 = iHalfHeight - y2/* + 0.5*/; // 转为屏幕坐标
    if (iX2 >= 0 && iX2 < ibmWidth && iY2 >=0 && iY2 < ibmHeight ) { int iIndexTarge = (i * ibmWidth + j) * iBitCount;
    int iIndexGet = (iY2 * ibmWidth + iX2) * iBitCount;
    for(int k = 0; k < iBitCount; k++)
    {
    pNewByte[iIndexTarge + k] = pSrcByte[iIndexGet + k];
    }
    //SetPixel(y1,x1, RGB(255,255,255));
    } }
    } int iReturn = pBitmap->SetBitmapBits(iTotalByte, pNewByte);
    if (NULL != pSrcByte) {
    delete []pSrcByte;
    pSrcByte = NULL;
    }
    if (NULL != pNewByte) {
    delete []pNewByte;
    pNewByte = NULL;
    }
    return;
    }/*-----------------------------------------------------------------------------    功    能:旋转坐标计算    参数说明:iDegree 为要转的度数
              x1,y1 为 要转的坐标
      x2,y2为转之后的坐标    返 回 值:    说    明:  2006-10-27 16:22:35
      ---------------------------------------------------------------------------*/
    void CSafeDC::TurnDegree(int iDegree, float x1, float y1, float &x2, float &y2)
    {
    if(fabs(x1) < 0.0001 && fabs(y1) < 0.0001)
    {
    x2 = 0;
    y2 = 0;
    return;
    }
    float r = sqrt( x1 * x1 + y1 * y1);
    if(fabs(y1) < 0.0001)
    {

    float dDegree = iDegree * PI / 180  ;
    float dCaluDegree = 0.0;
    if(x1 > 0)
    {
    dCaluDegree =   dDegree;

    }
    else
    {
    dCaluDegree =  PI + dDegree;

    }
    x2 = r * cos(dCaluDegree);
    y2 = r * sin(dCaluDegree);

    }

    else
    {
    float dDegree = iDegree * PI / 180  ;
    float dCaluDegree = y1/fabs(y1) * acos(x1 / r) + ( (1-y1/fabs(y1)) ) * PI + dDegree;
    x2 = r * cos(dCaluDegree);
    y2 = r * sin(dCaluDegree);
    }
    }
      

  2.   

    是因为如果就在原来的画布上以中心转的话就会有一部份转到画布上去了,然实图片的旋转一定是要以一个中心来转的,你可以这样想,开一个大些的画布,还是以原来画布中心转,只不过绘制时还是要往下往右移才能显示完全,你可以看下photoshop里如何转就会明白了
      

  3.   

    旋转成功了,我还是按照原DIB中心旋转的,也就是只涉及两个坐标系,当然有一部分被挡住了
    这几天我有点忙,还没来得及做3个坐标的。
    非常感谢你!!