首页 > 解决方案 > 给定 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没有定义。所以我不确定选择哪两个点来进行角度估计。

我应该如何进行?

标签: algorithmoctavebounding-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;
    }

推荐阅读