计算多边形角度的边界矩形

时间:2009-05-20 18:53:03

标签: algorithm graphics geometry

我需要以任意角度确定多边形的边界矩形。这张照片说明了我需要做的事情:

alt text http://kevlar.net/RotatedBoundingRectangle.png

对于简单的2d多边形,我需要在不同的角度确定粉红色矩形。

非常感谢任何解决方案!

修改

感谢您的回答,一旦我得到正确的中心点,我就让它工作了。你们真棒!

5 个答案:

答案 0 :(得分:7)

要获得具有特定角度的边界框,请将该多边形相反旋转该角度。然后,您可以使用最小/最大x / y坐标来获得一个简单的边界框,并按角度旋转以获得最终结果。

从您的评论中,您似乎遇到了获取多边形中心点的问题。多边形的中心应该是每个点的坐标和的平均值。所以对于点P1,...,PN,计算:

xsum = p1.x + ... + pn.x;
ysum = p1.y + ... + pn.y;
xcenter = xsum / n;
ycenter = ysum / n;

为了完成这项工作,我还为所涉及的轮换添加了一些公式。要围绕中心点(cx,cy)旋转点(x,y),请执行以下操作:

// Translate center to (0,0)
xt = x - cx;
yt = y - cy;
// Rotate by angle alpha (make sure to convert alpha to radians if needed)
xr = xt * cos(alpha) - yt * sin(alpha);
yr = xt * sin(alpha) + yt * cos(alpha);
// Translate back to (cx, cy)
result.x = xr + cx;
result.y = yr + cx;

答案 1 :(得分:3)

要获得最小的矩形,您应该获得正确的角度。这可以通过碰撞检测中使用的算法来实现:定向边界框。 基本步骤:

获取所有顶点坐标 建立协方差矩阵
找到特征值
投影特征值空间中的所有顶点
在每个特征值空间中找到最大值和最小值。

有关更多信息,只需google OBB“colision detection”

Ps:如果您只是投影所有顶点并找到最大值和最小值,则表示您正在制作AABB(轴对齐边界框)。它更容易,并且需要更少的计算工作量,但不保证最小的盒子。

答案 2 :(得分:2)

我正在将您的问题解释为“对于给定的2D多边形,如何计算预定方向角度的边界矩形的位置?”

我会通过相对于方向角旋转多边形来做到这一点,然后使用任何适合于存储多边形点的结构的搜索算法,在两个基本方向上使用简单搜索其最大和最小点。 in。(简而言之,您需要找到最高和最低X值,以及最高和最低Y值。)

然后最小值和最大值定义你的矩形。

您可以在不首先旋转多边形的情况下执行相同的操作,但搜索最小和最大点必须更复杂。

答案 3 :(得分:1)

答案 4 :(得分:0)

这是@schnaader的答案的python实现。 给定一个具有x和y坐标的点集,以及将这些点绑定到矩形的角度,该函数将返回一个包含四个角的点集(以及第一个角的重复)。

def BoundingRectangleAnglePoints(x,y, alphadeg):
    #convert to radians and reverse direction    
    alpha = np.radians(alphadeg)
    
    #calculate center
    cx = np.mean(x)
    cy = np.mean(y)

    #Translate center to (0,0)
    xt = x - cx
    yt = y - cy

    #Rotate by angle alpha (make sure to convert alpha to radians if needed)
    xr = xt * np.cos(alpha) - yt * np.sin(alpha)
    yr = xt * np.sin(alpha) + yt * np.cos(alpha)

    #Find the min and max in rotated space
    minx_r = np.min(xr)
    miny_r = np.min(yr)
    maxx_r = np.max(xr)
    maxy_r = np.max(yr)
    #Set up  the minimum and maximum points of the bounding rectangle    
    xbound_r = np.asarray([minx_r, minx_r, maxx_r, maxx_r,minx_r])
    ybound_r = np.asarray([miny_r, maxy_r, maxy_r, miny_r,miny_r])
    
    #Rotate and Translate back to (cx, cy)
    xbound = (xbound_r * np.cos(-alpha) - ybound_r * np.sin(-alpha))+cx
    ybound = (xbound_r * np.sin(-alpha) + ybound_r * np.cos(-alpha))+cy
  
    return xbound, ybound