你如何从转换matrix中提取方向?

我有一个4×4的变换matrixM,我想要找出一个由M变换的球体的形状(球体在原点,半径为1)

我知道我可以通过乘以(0,0,0,1)来find中心。

然而,由于M可以挤压和旋转球体,所以半径成为问题。 我怎样才能找出椭球的新半径? 有什么方法可以find方向?

更具体地说,我需要知道包围变换球体的边界球的大小。 换句话说,| M * V – M *(0,0,0,1)|的最大值是多less,其中V是一个单位向量(原始球体上的一个点)。

在math上,你所问的数量被称为操作员标准 。 不幸的是,没有简单的公式。 如果这是一个完全一般的仿射变换 – 例如,如果它可以以任意顺序任意组合旋转和不一致的尺度,那么恐怕没有什么可以使用,而是使用奇异值分解 。 如果将SVD应用于matrix,则最大奇异值将是所得椭球的最大半径。 其他奇异值也将是其他两个半径,并且SVD过程也可以为您提取轴的方向。

实施SVD并不是因为心脏模糊,因为它涉及到find特征值。 如果所有你想要的是奇异值本身,它们是M ^ T * M特征值的平方根。所以如果你有一个3×3的特征值求解方便,或者你不介意写一个,你可以使用它。 如果你想提取轴的方向,那么它也会变得更加复杂,因为你必须find特征向量。 在那个维基百科文章中,有一个链接到SVD的链接列表,其中一个可以在你的项目中使用。

如果matrix的forms受到限制,最多只发生一次非均匀缩放,并且是第一个应用的变换,即在使用列向量时是最右边的,那么可以将其简化为仅查看转换的轴向量。 在这种情况下,即单一的非均匀尺度,随后是任何旋转,reflection和均匀尺度的顺序 – 只看轴vector将会给你正确的答案。

也许从matrix中提取比例因子,然后使用其分量的最大值。 使用SRT(比例旋转 – 平移)matrix,你可以这样做:

glm::mat4 m = ...; // Extract col vectors of the matrix glm::vec3 col1(m[0][0], m[0][1], m[0][2]); glm::vec3 col2(m[1][0], m[1][1], m[1][2]); glm::vec3 col3(m[2][0], m[2][1], m[2][2]); //Extract the scaling factors glm::vec3 scaling; scaling.x = glm::length(col1); scaling.y = glm::length(col2); scaling.z = glm::length(col3); float scaleFactor = MAX(scaling.x, MAX(scaling.y, scaling.z)); 

(基于http://wklej.org/id/950061/ – 名称是decomposeTRS而不是decomposeSRT,因为我使用的名字是在OpenGL中乘以matrix的顺序)。

现在你可以通过scaleFactor乘以原始的球体半径,你有你的边界球。