参考博客:https://blog.csdn.net/faithmy509/article/details/80235631
推导公式图解
平面中,一个点(x,y)绕任意点(x0,y0)逆时针旋转a度后的坐标(r_x,r_y)
r_x= (x - x0)*cos(a) - (y - y0)*sin(a) + x0 ;
r_y= (x - x0)*sin(a) + (y - y0)*cos(a) +y0 ;
平面中,一个点(x,y)绕任意点(dx,dy)顺时针旋转a度后的坐标(r_x,r_y)
r_x= (x - x0)*cos(a) - (y - y0)*sin(-a) + x0 ;
r_y= (x - x0)*sin(-a) + (y - y0)*cos(a) +y0 ;
C++实现
#include <math.h>
#include <iostream>
#include <stdio.h>
#include <fstream>
#include <vector>
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#define PI 3.141592654
using namespace std;
using namespace cv;
struct point {
double x;
double y;
};
void rotatePoint(double angle, point &rotate_pt, point origin_pt, point center_pt)
{
double x0 = center_pt.x;
double y0 = center_pt.y;
double x = origin_pt.x;
double y = origin_pt.y;
rotate_pt.x = (x - x0) * cos(angle* PI / 180) - (y - y0) * sin(angle* PI / 180) + x0;
rotate_pt.y = (x - x0) * sin(angle* PI / 180) + (y - y0) * cos(angle* PI / 180) + y0;
}
int main() {
Mat m_image = Mat(500, 500, CV_8UC3, Scalar(0, 0, 0));
vector<point> origin_line;
double angle = -25;
for(int i = 0; i <= 500 ; i+=10)
{
point temp_pt;
temp_pt.x = i;
temp_pt.y = 2 *i + 4;
origin_line.push_back(temp_pt);
circle(m_image, cvPoint(temp_pt.x, temp_pt.y), 3, Scalar(255, 255, 255), -1);//白色点
}
for (int i = 0; i < origin_line.size(); i++)
{
point origin_pt,center_pt, rotate_pt;
origin_pt.x = origin_line[i].x;
origin_pt.y = origin_line[i].y;
center_pt.x = origin_line[0].x;
center_pt.y = origin_line[0].y;
rotatePoint(angle,rotate_pt, origin_pt,center_pt);
circle(m_image, cvPoint(rotate_pt.x, rotate_pt.y), 2, Scalar(0, 0, 255), -1);//红色点
}
imshow("rotate",m_image);
waitKey();
return 0;
}
运行后可得到下列图像:
白色是原始线段,红色是旋转后的线段,由于opencv的坐标系的Y轴和我们正常的坐标系相反,所以角度输入为负时看起来逆时针旋转,实际上在正常的坐标系下是上述推导和公式是正确的.