RGB图像任意角度旋转

本文介绍了RGB图像在C++中进行任意角度旋转的数学推导及代码实现,包括坐标变换公式、边界点计算和旋转后的图像尺寸调整。提供了一个名为`Rotate`的函数,用于完成图像旋转操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

推导:

 

x = r cos(b);

y = r sin(b);                 _ _ _ _ _ _ _ _ (1)

 

x’ =  r cos(a+b);

y’ =  r sin(a+b);            _ _ _ _ _ _ _ _ (2)

 

 

 cos(a+b) = cos(a)cos(b)-sin(a)sin(b);

sin(a+b) = sin(a)cos(b)+cos(a)sin(b);   _ _ _ _ _ _ _ _ (3)

 

 将(3)代入(2):

x’ =  r cos(a)cos(b)  - r sin(a)sin(b);

y’ =  r sin(a)cos(b)  + r cos(a)sin(b);       _ _ _ _ _ _ _ _ (4)

 

 

将(1)代入(4):

x’ =  x cos(a)  - y sin(a);

y’ =  x sin(a)  + y cos(a);    _ _ _ _ _ _ _ _ (5)

 

 根据(5)求对应源坐标:

x = x’ cos(a)  +  y’ sin(a);

y = -x’ sin(a)  +  y’ cos(a);



代码:

BYTE*  Rotate(BYTE* pSrc,BYTE* pDest,int nWidth,int nHeight,int& nResW,int& nResH,double dAngel)
{
double cos_angle = cos(dAngel);
double sin_angle = sin(dAngel);


POINT p1={0,0};
POINT p2={nWidth,0};
POINT p3={0,nHeight};
POINT p4={nWidth,nHeight};
POINTF newP1,newP2,newP3,newP4, leftTop, rightTop, leftBottom, rightBottom;


newP1.x = (float)p1.x;
newP1.y = (float)p1.y;
newP2.x = (float)(p2.x*cos_angle - p2.y*sin_angle);
newP2.y = (float)(p2.x*sin_angle + p2.y*cos_angle);
newP3.x = (float)(p3.x*cos_angle - p3.y*sin_angle);
newP3.y = (float)(p3.x*sin_angle + p3.y*cos_angle);
newP4.x = (float)(p4.x*cos_angle - p4.y*sin_angle);
newP4.y = (float)(p4.x*sin_angle + p4.y*cos_angle);


leftTop.x = min(min(newP1.x,newP2.x),min(newP3.x,newP4.x));
leftTop.y = min(min(newP1.y,newP2.y),min(newP3.y,newP4.y));
rightBottom.x = max(max(newP1.x,newP2.x),max(newP3.x,newP4.x));
rightBottom.y = max(max(newP1.y,newP2.y),max(newP3.y,newP4.y));
leftBottom.x = leftTop.x;
leftBottom.y = rightBottom.y;
rightTop.x = rightBottom.x;
rightTop.y = leftTop.y;


nResW = (int) floor(0.5f + rightTop.x - leftTop.x);
nResH=  (int) floor(0.5f + leftBottom.y - leftTop.y);


BYTE* pRet = new BYTE[nResW*nResH*3];


int nOldStride = nWidth*3;
int nNewStride = nResW*3;


int x,y,newX,newY,oldX,oldY;


for (y = (int)leftTop.y, newY = 0; y<=(int)leftBottom.y; y++,newY++)
{
int nNewPosY = newY*nNewStride;
for (x = (int)leftTop.x, newX = 0; x<=(int)rightTop.x; x++,newX++)
{
oldX = (int)(x*cos_angle + y*sin_angle + 0.5);
oldY = (int)(y*cos_angle - x*sin_angle + 0.5);


if(IsPointInside(oldX,oldY,nWidth,nHeight))
{
int nNewPosX = newX*3;

int nOldPos = oldY*nOldStride + oldX*3;

if (nOldPos >= 0)
{
pRet[nNewPosY + nNewPosX]     = pSrc[nOldPos];
pRet[nNewPosY + nNewPosX + 1] = pSrc[nOldPos + 1];
pRet[nNewPosY + nNewPosX + 2] = pSrc[nOldPos + 2];
}
}


}
}
return pRet;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值