Я считаю, что угол alpha
(отмечен зеленым на изображении) - это то, что вы ищете.Предполагая, что самая низкая точка прямоугольника равна O(0, 0)
, этот угол можно легко рассчитать как cos -1 (a / sqrt (a ^ 2 + b ^ 2)), где B(a,b)
- точкас наименьшим положительным уклоном .Что касается D ≠ O (где D - точка с наименьшей координатой оси Y), просто переместите все это на вектор OD
так, чтобы D = O.
Не забудьте отдельно обработатьслучай, когда прямоугольник уже выровнен по оси, когда вы можете получить деление на ноль.
Мой псевдокод:
struct Point
{
double x, y, angle;
Point (double x, double y): x(x), y(y) {}
};
bool SortByY (Point a, Point b)
{
return a.y < b.y;
}
bool SortByAngle (Point a, Point b)
{
return a.angle < b.angle;
}
double GetRotationAngle(vector<Point> points)
{
sort (points.begin(), points.end(), SortByY);
// If there are 2 points lie on the same y-axis coordinates, simply return 0
if (points[0].y == points[1].y) return 0;
Point D = points[0];
for (int i=1; i<4; i++)
{
// Move the whole thing by vector OD
double a = points[i].x -= D.x;
double b = points[i].y -= D.y;
// Keep in mind that in C++, the acos function returns value in radians, you may need to convert to degrees for your purposes.
points[i].angle = acos(a / sqrt(a*a+b*b));
}
sort (points.begin()+1, points.end(), SortByAngle);
return points[1].angle;
}