求经2D仿射矩阵变换后圆的AABB及椭圆旋转角计算方法
问题解答
1. 如何通过共轭半直径计算椭圆的旋转角?
椭圆的旋转角是其主轴(长轴或短轴)与x轴的夹角,可通过共轭半直径对应的二次型矩阵特征向量求解,步骤如下:
计算步骤
- 用共轭半直径
f1、f2构造列向量矩阵M:M = [[f1.x, f2.x], [f1.y, f2.y]] - 计算矩阵
M与其转置的乘积MMt:MMt = [[f1.x² + f2.x², f1.x*f1.y + f2.x*f2.y], [f1.x*f1.y + f2.x*f2.y, f1.y² + f2.y²]] - 对于这个2x2对称矩阵,其特征向量的角度就是椭圆的旋转角
θ,满足:
其中tan(2θ) = 2*b / (a - d)a = f1.x² + f2.x²,b = f1.x*f1.y + f2.x*f2.y,d = f1.y² + f2.y² - 用反正切函数计算最终旋转角:
注:ellipse.rotation = 0.5 * atan2(2*b, a - d)atan2(y, x)能正确处理全象限角度,避免普通tan函数的象限歧义。
2. 无需转换为椭圆,直接计算变换后圆的AABB的方法
存在更高效的直接计算方式,核心是利用仿射变换对单位向量的极值特性:
计算步骤
假设仿射变换矩阵matrix的线性部分(剥离平移)为L = [[m00, m01], [m10, m11]],平移部分为(tx, ty):
- 计算变换后的圆心
C':
若使用齐次矩阵,直接执行C'.x = m00*circle.center.x + m01*circle.center.y + tx C'.y = m10*circle.center.x + m11*circle.center.y + tymatrix * circle.center即可得到C'。 - 计算x、y方向的最大扩展量:
- x方向:
dx = circle.radius * sqrt(m00² + m01²) - y方向:
dy = circle.radius * sqrt(m10² + m11²)
这里的平方根是矩阵对应行的L2范数,代表线性变换作用在单位向量上时,该分量的最大绝对值。
- x方向:
- 直接得出AABB边界:
min_x = C'.x - dx max_x = C'.x + dx min_y = C'.y - dy max_y = C'.y + dy
原理说明
圆上任意点可表示为circle.center + circle.radius * (cosθ, sinθ),经仿射变换后x分量为C'.x + circle.radius*(m00*cosθ + m01*sinθ)。其中m00*cosθ + m01*sinθ的最大值为sqrt(m00² + m01²)(由柯西不等式推导),最小值为其相反数,因此用该值乘以半径即可得到x方向的总扩展,y方向同理。
内容的提问来源于stack exchange,提问作者HankMoody
相关产品推荐
相关产品推荐

