algorithm - 给定 4 个点,如何计算矩形的旋转角度
问题描述
我有一组二维点。我对其协方差进行了特征向量估计。转换到新的基础并在那里找到边界框。为简单起见,在下面给出八度的代码。点数如下: 点数变量,形状为 Nx2
mycov = cov(points);
[V, E] = eig(mycov);
new_basis_points = V*points';
然后在代码中我估计每个轴的最大值和最小值并设置四个点:
points = [[minX, minY],
[minX, maxY],
[maxX, minY],
[maxX, maxY]];
现在我转换回旧的基础:
old_basis_bounding_box = V'*points';
这些计算是正确的,我在旧的基础上得到了四个角点。但现在我想估计矩形在其边和 X 轴之间的旋转角度。
问题是,点的顺序old_basis_bounding_box
没有定义。所以我不确定选择哪两个点来进行角度估计。
我应该如何进行?
解决方案
我相信角度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;
}
推荐阅读
- caching - 执行“a=5”时缓存和 DRAM 会发生什么?
- c# - 如何防止旧版本的 C# dll 运行
- python - Python groupby 多索引
- graphql - 如何仅从 Prisma / GraphQL 查询中获取过滤后的数据
- html - 如何在 CSS 中的形状上放置一个按钮?
- javascript - 如何在echarts中显示总和堆栈栏
- sql-server - Azure SQL Managed Instance - Create Credential not supported
- c# - 有没有办法在 C# 中使用全局计时器?一种可用于多种形式的
- azure - List of all Resources in my Azure Subscription + IAM Access Control Credentials
- java - MockMVC - How to check the content of a JWT token in a spring security integration test with org.hamcrest.Matcher