0

我对矩阵数学很糟糕,但我有一种情况需要缩放一个。该矩阵是此处定义的自定义类的一个实例,我的缩放对象是一个包含 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]); }

}

4

2 回答 2

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];
    }
}

请注意,这两种解决方案都遵循您的声明,即您的缩放向量具有三个分量。如果不是这种情况,所有的赌注都被取消了。

于 2010-11-28T02:05:41.877 回答
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;
}
于 2010-11-28T05:32:29.813 回答