变换圆的边界框

问题描述 投票:0回答:1

我正在尝试计算通过二维仿射矩阵进行变换的圆的轴对齐边界框,该矩阵可以包含任何操作(平移、旋转、缩放、倾斜)。

我认为最好的方法是用矩阵变换圆并获得旋转的椭圆,但我不知道如何正确执行。到目前为止,我所拥有的是一个可以计算旋转椭圆(未附加)的边界框的代码和一个可以将圆部分转换为椭圆的代码(中心和半径,但缺少椭圆旋转):

transformCircle(in matrix, in circle, out ellipse) {
    ellipse.center = matrix * circle.center

    // Calculate conjugated half-diameters
    f1 = matrix * vec2(circle.radius, 0)
    f2 = matrix * vec2(0, circle.radius)
    r = f1.x^2 + f1.y^2 + f2.x^2 + f2.y^2
    s = cross(f1, f2)
    p = sqrt(r + 2*s)
    q = sqrt(r - 2*s)

    ellipse.radiusX = 0.5 * (p + q)
    ellipse.radiusY = 0.5 * (p - q)

    ellipse.rotation = ???;  // Need help here
}

Conjugated half-diameters

我的问题是:

  • 如何根据共轭半直径计算椭圆旋转?
  • 或者,如果可能的话,如何计算由没有椭圆的二维矩阵变换的圆的 AABB?
math graphics geometry 2d
1个回答
0
投票

感谢@Mike'Pomax'Kamermans 在评论中提供了一些公式的链接,其中的答案之一包含椭圆旋转所需的公式。

为了将来的参考和搜索此内容的人们,将 2D 圆转换为 2D 旋转椭圆的完整伪代码,我将圆与任意 2D 仿射变换矩阵相乘是这样的:

transformCircle(in matrix, in circle, out ellipse) {
    ellipse.center = matrix * circle.center

    // Calculate conjugated half-diameters
    f1 = matrix * vec2(circle.radius, 0)
    f2 = matrix * vec2(0, circle.radius)

    f1x2 = f1.x^2
    f1y2 = f1.y^2
    f2x2 = f2.x^2
    f2y2 = f2.y^2;

    r = f1x2 + f1y2 + f2x2 + f2y2
    s = cross(f1, f2)
    p = sqrt(r + 2*s)
    q = sqrt(r - 2*s)

    ellipse.radiusX = 0.5 * (p + q)
    ellipse.radiusY = 0.5 * (p - q)

    ellipse.rotation = acos((f1x2 + f2x2 - f1y2 - f2y2) / sqrt(r^2 - 4 * s^2)) * 0.5
}
© www.soinside.com 2019 - 2024. All rights reserved.