我对矩阵数学很糟糕,但我有一种情况需要扩展一个。矩阵是custom class defined here的一个实例,我的缩放对象是一个包含3个浮点数(x,y,z)的向量。我想要的是我需要的实际代码,而不是一般性的解释,因为我已经走了那条路,只是不理解所涉及的数学。幸运的是,一旦我可以扩展矩阵,我想要完成的工作是相当微不足道的。
这里要澄清的是我正在更新的代码。它遍历链接对象的层次结构,具有相对变换和更新mat&绝对变换:
void LocalModelPiece::GetPiecePosIter(CMatrix44f* mat) const
{
if (parent) {
parent->GetPiecePosIter(mat);
}
if (pos.x || pos.y || pos.z) { mat->Translate(pos.x, pos.y, pos.z); }
// --> My problem is here. There is no Scale() method, I need one. <--
if (scale.x!=1.0f || scale.y!=1.0f || scale.z!=1.0f) { mat->Scale(scale.x, scale.y, scale.z); }
if (rot[1]) { mat->RotateY(-rot[1]); }
if (rot[0]) { mat->RotateX(-rot[0]); }
if (rot[2]) { mat->RotateZ(-rot[2]); }
}
答案 0 :(得分:2)
我不清楚你想扩展什么。它是矩阵本身,还是打算用它来扩展另一个向量?
如果你在谈论3D空间中的矢量,我不会看到4x4矩阵如何成为你想要的。使用矩阵在3D空间中缩放矢量意味着将缩放因子放在矩阵的对角线上;非对角元素为零。
当您链接到4x4矩阵时,您会感到困惑。你确定那是你想要的吗?
我想你想要这个:
这里有一些伪代码来展示它是如何完成的:
for (int i = 0; i < 3; ++i)
{
v_prime[i] = c[i]*v[i];
}
如果你想缩放3x3矩阵,它看起来像这样:
这里有一些伪代码来展示它是如何完成的:
for (int i = 0; i < 3; ++i)
{
for (int j = 0; j < 3; ++j)
{
m_prime[i][j] = c[i]*m[i][j];
}
}
请注意,这两个解决方案都遵循您的缩放向量有三个组件的说法。如果情况并非如此,那么所有投注都会被取消。
答案 1 :(得分:0)
我查看了您提供的API链接,基于此,我将如何为矩阵类实现缩放方法,以便与现有的Translate()和Rotate()方法保持一致。也就是说,它使用缩放矩阵进行右侧乘法。
虽然我个人认为它有点奇怪,因为API使用OpenGL样式矩阵。这意味着右侧乘法在矩阵中存在的所有其他变换之前应用新变换,其中左侧乘法将在其他变换之后应用它。所以我不确定这是不是你想要的。您可能必须以相反的顺序进行所有转换,或者自己进行左侧乘法。
void CMatrix44f::Scale(float scalex, float scaley, float scaley)
{
/* the function should be equivalent to doing this:
CMatrix44f scalemat;
scalemat[0] = scalex;
scalemat[5] = scaley;
scalemat[10] = scalez;
*this = Mul(scalemat);
*/
m[0] *= scalex;
m[1] *= scalex;
m[2] *= scalex;
m[3] *= scalex;
m[4] *= scaley;
m[5] *= scaley;
m[6] *= scaley;
m[7] *= scaley;
m[8] *= scalez;
m[9] *= scalez;
m[10] *= scalez;
m[11] *= scalez;
}