我需要了解矩阵乘法在这个 C++ 程序中是如何发生的

问题描述 投票:0回答:1

这是从 Austin Morlan 的 ECS 示例中获得的代码。


class Mat44
{
public:
    Mat44()
    {
        //@formatter:off
        m[0][0] = 1.0f; m[0][1] = 0.0f; m[0][2] = 0.0f; m[0][3] = 0.0f;
        m[1][0] = 0.0f; m[1][1] = 1.0f; m[1][2] = 0.0f; m[1][3] = 0.0f;
        m[2][0] = 0.0f; m[2][1] = 0.0f; m[2][2] = 1.0f; m[2][3] = 0.0f;
        m[3][0] = 0.0f; m[3][1] = 0.0f; m[3][2] = 0.0f; m[3][3] = 1.0f;
        //@formatter:on
    }


    Mat44 operator*(Mat44 const& rhs)
    {
        Mat44 result;

        for (int row = 0; row < 4; ++row)
        {
            for (int col = 0; col < 4; ++col)
            {
                float sum = 0.0f;

                for (int i = 0; i < 4; ++i)
                {
                    sum += m[row][i] * rhs.m[i][col];
                }

                result.m[row][col] = sum;
            }
        }

        return result;
    }


    Vec4 operator*(Vec4 const& rhs)
    {
        return Vec4(
            (rhs.x * m[0][0]) + (rhs.y * m[0][1]) + (rhs.z * m[0][2]) + (rhs.w * m[0][3]),
            (rhs.x * m[1][0]) + (rhs.y * m[1][1]) + (rhs.z * m[1][2]) + (rhs.w * m[1][3]),
            (rhs.x * m[2][0]) + (rhs.y * m[2][1]) + (rhs.z * m[2][2]) + (rhs.w * m[2][3]),
            (rhs.x * m[3][0]) + (rhs.y * m[3][1]) + (rhs.z * m[3][2]) + (rhs.w * m[3][3]));
    }


    float m[4][4];
};


问题:

  1. 请简单地向我解释一下 for 循环中发生了什么? (我的理解:对于每一行,列都被完全遍历,声明一个变量 sum 来存储乘法的结果,然后设置一个索引(多维数组的跟踪器)来跟踪遍历的每个索引,本质上是一种排序如果到目前为止我是正确的,我无法从这里开始,也许有更好的方法来帮助我理解这里发生的事情?

  2. 这些是 GLM 库隐藏的抽象吗?

  3. 我的CPP知识是中级的,我无法理解为什么操作符重载需要一个参数

  4. 最后,对于Vec4类,我什至不知道发生了什么?

c++ game-development glm-math cmath
1个回答
0
投票

对于运算符重载,如果声明为类成员的二元运算符隐式采用

*this
的一个参数,即对象本身,因此仅使用一个参数进行声明。例如。
Mat44 operator*(Mat44 const& rhs)
允许使用以下代码:

   Mat44 a{}, b{};
   Mat44 c = a * b; // Mat44::operator* is called for `a`

同样的情况也发生在

Vec4

以此类推,一元运算符(增量除外)作为成员声明时根本不带参数,因为它们显然只有一个。 运算符重载是C++中的一个基本主题,不是可选的。

Mat44::operator*
表示矩阵乘法。向量是矩阵的一种情况,其中一维等于 1(根据具体情况,它是向量列或向量行)。传统上将向量表示为单独的类,因为多种优化和规则会影响它,并且语义上向量列和向量行是等效的。

这些不是“隐藏的抽象”,而是部分常见的数学知识。在常规课程中,您将在实际学习编程之前了解这一点。由于

a*b
不等于
b*a
,如果它们是矩阵,则运算符必须是成员以确保运算顺序。计算机图形学很大程度上依赖于“线性代数”,尤其是。向量数学。

© www.soinside.com 2019 - 2024. All rights reserved.