我正在尝试分解一个齐次坐标变换矩阵,它是这些变换矩阵的结果(按其书写顺序应用):非均匀缩放 -> 旋转 -> 翻译我从生成 4x4 变换矩阵(最后一列的前三个值),但我找不到提取旋转和缩放矩阵的方法。
我在网上找到了以下矩阵分解算法:
- 将比例因子计算为矩阵的前三个基向量(列或行)的大小
- 将前三个基向量除以这些值(从而对它们进行归一化)
- 矩阵的左上角 3x3 部分现在表示旋转(您可以按原样使用它,也可以将其转换为四元数形式)
- 平移是矩阵的第四个基向量(在齐次坐标中 - 这将是您感兴趣的前三个元素)
这是我的java实现
public void decompose(Vec3 translation, Vec4 rotationAxisAndAngle, Vec3 scale) {
translation = this.getTranslation();
Vec3 c0 = new Vec3(values[ 0], values[ 1], values[ 2]);
Vec3 c1 = new Vec3(values[ 4], values[ 5], values[ 6]);
Vec3 c2 = new Vec3(values[ 8], values[ 9], values[10]);
scale.x = Vec3.len(c0.x, c0.y, c0.z);
scale.y = Vec3.len(c1.x, c1.y, c1.z);
scale.z = Vec3.len(c2.x, c2.y, c2.z);
Matrix4 mat = new Matrix4();
mat.values[ 0] = c0.x / scale.x; mat.values[ 4] = c1.x / scale.y; mat.values[ 8] = c2.x / scale.z; mat.values[12] = 0;
mat.values[ 1] = c0.y / scale.x; mat.values[ 5] = c1.y / scale.y; mat.values[ 9] = c2.y / scale.z; mat.values[13] = 0;
mat.values[ 2] = c0.z / scale.x; mat.values[ 6] = c1.z / scale.y; mat.values[10] = c2.z / scale.z; mat.values[14] = 0;
mat.values[ 3] = 0; mat.values[ 7] = 0; mat.values[11] = 0; mat.values[15] = 1;
rotationAxisAndAngle = mat.toAxisAngle();
System.out.println("<Transform translation=\"" + translation.x + " " + translation.y + " " + translation.z + "\">");
System.out.println("<Transform rotation=\"" + rotationAxisAndAngle.x + " " + rotationAxisAndAngle.y + " " + rotationAxisAndAngle.z + " " + rotationAxisAndAngle.w + "\">");
System.out.println("<Transform scale=\"" + scale.x + " " + scale.y + " " + scale.z + "\">");
}
但是它检索到的轴角和比例因子是不正确的。
它出什么问题了?