代码之家  ›  专栏  ›  技术社区  ›  SpliFF

按向量缩放自定义矩阵类

  •  0
  • SpliFF  · 技术社区  · 14 年前

    我对矩阵数学很差,但我有一种情况,我需要衡量一。矩阵是 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]); }
    

    }

    2 回复  |  直到 14 年前
        1
  •  0
  •   Timo    14 年前

    我查看了您提供的API链接,在此基础上,我将如何实现矩阵类的缩放方法,使之与现有的TraseAe()和RoSATE()方法一致。也就是说,它与一个缩放矩阵做右侧乘法运算。

    尽管我个人觉得有点奇怪,因为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;
    }
    
        2
  •  2
  •   duffymo    14 年前

    我不清楚你想衡量什么。是矩阵本身,还是用它来缩放另一个向量?

    如果你说的是三维空间中的一个向量,我不明白4x4矩阵是如何成为你想要的。使用矩阵缩放三维空间中的向量意味着将缩放因子放在矩阵的对角线上;非对角线元素为零。

    当你链接到一个4x4矩阵的时候,你把我搞糊涂了。你确定这就是你想要的吗?

    我想你想要这个:

    alt text

    下面是一些伪代码来说明它是如何完成的:

    for (int i = 0; i < 3; ++i)
    {
        v_prime[i] = c[i]*v[i];
    }
    

    如果要缩放3x3矩阵,它将如下所示:

    alt text

    下面是一些伪代码来说明它是如何完成的:

    for (int i = 0; i < 3; ++i)
    {
        for (int j = 0; j < 3; ++j)
        {
            m_prime[i][j] = c[i]*m[i][j];
        }
    }
    

    请注意,这两个解决方案都来自于您的声明,即您的缩放向量有三个组件。如果不是这样的话,所有的赌注都是空的。