从模型视图矩阵中提取比例矩阵
extracting scale matrix from modelview matrix
我们如何从模型视图矩阵中提取比例矩阵?现在我正在计算每一列的长度,但是当比例为负时它会失败。
这是我的代码:
float xs =
matrix[0][0] * matrix[0][1] * matrix[0][2] * matrix[0][3] < 0 ?
-1 : 1;
float ys =
matrix[1][0] * matrix[1][1] * matrix[1][2] * matrix[1][3] < 0 ?
-1 : 1;
float zs =
matrix[2][0] * matrix[2][1] * matrix[2][2] * matrix[2][3] < 0 ?
-1 : 1;
glm::vec3 new_scale;
new_scale.x = xs* glm::sqrt(
matrix[0][0] * matrix[0][0] + matrix[0][1] * matrix[0][1]
+ matrix[0][2] * matrix[0][2]);
new_scale.y = ys* glm::sqrt(
matrix[1][0] * matrix[1][0] + matrix[1][1] * matrix[1][1]
+ matrix[1][2] * matrix[1][2]);
new_scale.z = zs* glm::sqrt(
matrix[2][0] * matrix[2][0] + matrix[2][1] * matrix[2][1]
+ matrix[2][2] * matrix[2][2]);
例如:
float []mat={0.032254f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, -0.0052254f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.4332254f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f};
参见 。您提取 scale 的方式是可以的。那么标志呢?如果您的转换包含旋转,您当前的方法将不起作用...
另一个问题是你不知道哪个比例被取反,哪个不是因为如果你取反单轴你可以得到相同的结果如果你取反任何其他轴并旋转以匹配位置。如果你否定 2 个轴,你会得到具有不同旋转的原始矩阵。
你能做的最好的事情就是检测你的矩阵是否反转了 1 轴或 3 轴:
为原始未失真矩阵创建符号table
例如单位矩阵,但如果您有不同的起点,请使用它
sz0=dot(cross(X0,Y0),Z0);
sy0=dot(cross(Z0,X0),Y0);
sx0=dot(cross(Y0,Z0),X0);
其中 X0,Y0,Z0
是从起点矩阵中提取的轴向量
计算当前矩阵的符号
sz1=dot(cross(X1,Y1),Z1);
sy1=dot(cross(Z1,X1),Y1);
sx1=dot(cross(Y1,Z1),X1);
其中 X1,Y1,Z1
是从实际矩阵中提取的轴向量
比较符号并推断出哪些轴刻度为负
if (sx0*sx1<0)||(sy0*sy1<0)||(sz0*sz1<0)
则一个或所有 3 个轴被取反,但您无法知道是哪一个……而且所有 3 个符号比较应该有相同的结果。
[edit1] 澄清
X=(matrix[0][0],matrix[0][1],matrix[0][2])
dot(a,b)=a.x*b.x+a.y*b.y+a.z*b.z
是向量的标量乘法(点积)
c=cross(a,b) ... c.x=a.y*b.z+a.z*b.y c.y=a.z*b.x+a.x*b.z c.z=a.x*b.y+a.y*b.x
是向量乘法(叉积)
因此,当您计算两个向量的交叉时,您会得到垂直于两个操作数的向量。由于矩阵轴向量应该与 multipliyng 2 轴垂直,因此您得到第三个轴。点积只是比较原始和计算出的第三轴是否在同一方向......这种方式在旋转时不变
我们如何从模型视图矩阵中提取比例矩阵?现在我正在计算每一列的长度,但是当比例为负时它会失败。 这是我的代码:
float xs =
matrix[0][0] * matrix[0][1] * matrix[0][2] * matrix[0][3] < 0 ?
-1 : 1;
float ys =
matrix[1][0] * matrix[1][1] * matrix[1][2] * matrix[1][3] < 0 ?
-1 : 1;
float zs =
matrix[2][0] * matrix[2][1] * matrix[2][2] * matrix[2][3] < 0 ?
-1 : 1;
glm::vec3 new_scale;
new_scale.x = xs* glm::sqrt(
matrix[0][0] * matrix[0][0] + matrix[0][1] * matrix[0][1]
+ matrix[0][2] * matrix[0][2]);
new_scale.y = ys* glm::sqrt(
matrix[1][0] * matrix[1][0] + matrix[1][1] * matrix[1][1]
+ matrix[1][2] * matrix[1][2]);
new_scale.z = zs* glm::sqrt(
matrix[2][0] * matrix[2][0] + matrix[2][1] * matrix[2][1]
+ matrix[2][2] * matrix[2][2]);
例如:
float []mat={0.032254f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, -0.0052254f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.4332254f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f};
参见
另一个问题是你不知道哪个比例被取反,哪个不是因为如果你取反单轴你可以得到相同的结果如果你取反任何其他轴并旋转以匹配位置。如果你否定 2 个轴,你会得到具有不同旋转的原始矩阵。
你能做的最好的事情就是检测你的矩阵是否反转了 1 轴或 3 轴:
为原始未失真矩阵创建符号table
例如单位矩阵,但如果您有不同的起点,请使用它
sz0=dot(cross(X0,Y0),Z0); sy0=dot(cross(Z0,X0),Y0); sx0=dot(cross(Y0,Z0),X0);
其中
X0,Y0,Z0
是从起点矩阵中提取的轴向量计算当前矩阵的符号
sz1=dot(cross(X1,Y1),Z1); sy1=dot(cross(Z1,X1),Y1); sx1=dot(cross(Y1,Z1),X1);
其中
X1,Y1,Z1
是从实际矩阵中提取的轴向量比较符号并推断出哪些轴刻度为负
if
(sx0*sx1<0)||(sy0*sy1<0)||(sz0*sz1<0)
则一个或所有 3 个轴被取反,但您无法知道是哪一个……而且所有 3 个符号比较应该有相同的结果。
[edit1] 澄清
X=(matrix[0][0],matrix[0][1],matrix[0][2])
dot(a,b)=a.x*b.x+a.y*b.y+a.z*b.z
是向量的标量乘法(点积)c=cross(a,b) ... c.x=a.y*b.z+a.z*b.y c.y=a.z*b.x+a.x*b.z c.z=a.x*b.y+a.y*b.x
是向量乘法(叉积)
因此,当您计算两个向量的交叉时,您会得到垂直于两个操作数的向量。由于矩阵轴向量应该与 multipliyng 2 轴垂直,因此您得到第三个轴。点积只是比较原始和计算出的第三轴是否在同一方向......这种方式在旋转时不变