分别计算matrix转换组件

可以计算用于构建matrix的平移,旋转和缩放吗?

我的意思是如果我有matrixM ,我可以计算它代表的旋转,缩放和平移吗?

当然,我可以单独保存matrix中的每个组件,但是我可以从matrix数据中恢复这些信息吗?

假设以下matrix乘法约定,其中M是要分解的matrix, pvariables表示点为列向量,其中w坐标为1 …

 p_transformed = M * p_local ┌ ┐ M = | m00 m01 m02 m03 | assumed to be decomposible into | m10 m11 m12 m13 | M = T * R * S | m20 m21 m22 m23 | such that that... | 0 0 0 1 | └ ┘ p_transformed = T * R * S * p_local ┌ ┐ T = | 1 0 0 tx | Translation by (tx, ty, tz) | 0 1 0 ty | | 0 0 1 tz | | 0 0 0 1 | └ ┘ ┌ ┐ S = | sx 0 0 0 | Axis-aligned scale by (sx, sy, sz) | 0 sy 0 0 | | 0 0 sz 0 | | 0 0 0 1 | └ ┘ R = Rotation matrix (orthonormal) 

然后可以计算翻译T ,旋转R和比例S ,其结果与M相同。

但是我们不能保证这些将会是原来用于创建 M 的相同的值 ,我们将在下面看到。

由于四舍五入的错误,您也可能会失去精度 ,所以您应该避免MT R S之间重复往返转换 ,例如在关卡编辑器中布置对象时,随时进行保存和加载。

这也适用于在运行时更新dynamic对象的转换。 能够从原始翻译,旋转和缩放值重建matrix将帮助您避免有害的舍入误差 。

所以, 几乎可以肯定值得保留额外的内存来存储您的原始转换参数 ,无论是从用户的角度来看,还是为了准确性和稳定性。

也就是说,如果是以只读方式使用的东西,或者需要从仅包含组合matrix的烘焙数据重建转换参数,则可以这样做…


首先,提取翻译组件是直接&明确的:

 tx = m03 ty = m13 tz = m23 

该尺度可以计算为基vector乘以M的长度:

 sx = || M * (1, 0, 0, 0) || (and similarly for sy, sz) = || (m00, m10, m20) || = sqrt(m00 * m00 + m10 * m10 + m20 * m20) 

如果你的秤可能是负面的,那么你有一个额外的复杂性来解决。 任何一个轴上的reflection与不同轴上的reflection结合适当的旋转是相同的,两个轴上的reflection相当于纯旋转。

所以,你需要select一个约定来解决这个问题。 一种是检测是否存在净reflection(即沿着1或3轴的reflection)并且通过平面确定它应该是沿着x轴的reflection:

 if (dot( cross((m00, m10, m20), (m01, m11, m21)), (m02, m12, m22) ) < 0) then sx *= -1 

(如果sx或任何其他比例为零,那么你正在处理一个平面,线或点投影,所以我们可以表示为一个旋转,没有reflection)

S中,我们可以把它分开来重建一个合适的R

  ┌ ┐ R = | m00/sx m01/sy m03/sz 0 | | m10/sx m11/sy m13/sz 0 | | m20/sx m21/sy m23/sz 0 | | 0 0 0 1 | └ ┘ 

请注意,如果sxsysz一个为零,那么您需要将对应的列replace为其他两列的叉积,以避免被零除错误。

如果两个轴的比例为零,则可以select与其余轴正交的两个任意单位vector。 如果所有三个轴都具有零刻度,则可以让R = Identity因为一个点是一个点而不管旋转。

通过构造R 应该是一个正交旋转matrix,但是在实践中,数值误差可能导致它偏离,所以包括一个对其进行正交归一化的误差校正步骤可能是一个合理的预防措施。

如果需要的话,可以使用通常的方法将该旋转matrix转换成等效的单位四元数或欧拉角三元组,所以在这里我不做详细说明。

您可以乘以平移,旋转和缩放matrix来获得一个最终的移动matrix。

如果你问如何从多个平移,旋转和比例matrix的最终产品中提取数值,那么不需要。 这就像试图find一个数字的select除数,比如说16。它可以是4,2,8等。

没有办法做到这一点(得到相同的翻译,旋转,和规模到你的原始值),除非你有以前的matrix,在这种情况下,你可以分裂(例如:说你知道其中一个除数是8。那么,你可以用8除以得到2 – >这个逻辑对于matrix是有点不同的)。

如果你问如何从一个matrix中获得翻译轮换和缩放值,那么这很容易。 这取决于你是使用列主要还是行主要订单。 为此,请使用以下有用的链接: http : //www.codinglabs.net/article_world_view_projection_matrix.aspx

转型:

 TransformxAxis.x TransformyAxis.x TransformzAxis.x Translation.x TranformxAxis.y TransformyAxis.y TransformzAxis.y Translation.y TransformxAxis.z TransformyAxis.z TransformzAxis.z Translation.z 0 0 0 1 

*取决于你是3D还是2D

翻译:

 1 0 0 Translation.x 0 1 0 Translation.y 0 0 1 Translation.z 0 0 0 1 

规模:

 Scale.x 0 0 0 0 Scale.y 0 0 0 0 Scale.z 0 0 0 0 1 

检查所有链接 – >在“转换matrix”下