math - 学习游戏编程(第 2 部分)(数学)

标签 math vector 3d

关闭。这个问题需要更多focused .它目前不接受答案。












想改善这个问题吗?更新问题,使其仅关注一个问题 editing this post .

7年前关闭。




Improve this question




所以,我已经几个月没写 this question ,从那时起我就开始玩弄“原始”C++ D3D、Ogre 和 Irrlicht 图形引擎以及最近的 Microsoft XNA。我已经构建了一些 2D 游戏(主要是俄罗斯方块、星体等旧东西的复制品),并在上述技术中向 3D 世界迈出了一些(非常)小的步骤。

我在创建实际游戏逻辑、抽象对象交互以允许我插入不同形式的控制(计算机、播放器、网络等)、执行线程或我使用的任何其他东西时几乎没有问题从我的日常工作开始 - 这对我来说感觉非常自然。我很少涉及 HLSL 和粒子效果(非常非常基本)。

但是涉及矩阵和向量的 3D 数学(以及 Ogre3D 中的四元数(?),这些真的需要吗?)......真的让我明白,我可以学习例子(例如我从 O'Reilly 购买的 Learning XNA 3.0 书,这是一本很棒的书顺便说一句),我明白为什么以及如何在示例中发生某些事情,但是当我尝试自己做某事时,我觉得我缺乏对此类数学的理解,无法真正掌握它并让我自己动手.

因此,我正在寻找有关学习 3D 数学(主要是)和一些着色器/粒子效果书籍的资源。我更喜欢具有教育意义的资源,并且在诸如向量数学的博士论文之类的东西上放慢速度,这将超出我的脑海。理想的资源应该是在 D3D 中展示这一切的东西。

最佳答案

好的,矩阵/向量计算的快速类(class):

矩阵是在矩形网格中排序的数字集合,例如:

[ 0,  1,  2 ]
[ 2,  3,  5 ]
[ 2,  1,  3 ]
[ 0,  0,  1 ]

上面的矩阵有 4 行 3 列,因此是一个 4 x 3 矩阵。
向量是具有 1 行(行向量)或 1 列(列向量)的矩阵。
正常数称为标量以与矩阵形成对比。

矩阵使用大写字母,标量使用小写字母也很常见。

我们可以用矩阵进行基本计算,但有一些条件。

添加

如果矩阵具有相同的维度,则可以添加矩阵。因此,2x2 矩阵可以添加到 2x2 矩阵,但不能添加到 3x5 矩阵。
[ 1,  2 ] + [ 2,  5 ] = [ 3,  7 ]
[ 2,  4 ]   [ 0,  3 ]   [ 2,  7 ]

您会看到,通过相加,每个单元格中的每个数字都与另一个矩阵中相同位置的数字相加。

矩阵乘法

矩阵可以相乘,但这有点复杂。为了将矩阵 A 与矩阵 B 相乘,您需要将矩阵 A 的每一行中的数字与矩阵 B 中的每一列相乘。 这意味着如果将 axb 矩阵与 acxd 矩阵相乘,b 和 c 必须相等,并且结果矩阵是 axd:
[1,2,3] x [4,6] = [1x4+2x2+3x2, 1x6+2x1+3x3 ] = [4+4+6,  6+2+9  ] = [14, 20]
[1,4,5]   [2,1]   [1x4+4x2+5x2, 1x6+4x1+5x3 ]   [4+8+10, 6+4+15 ]   [22, 25]
          [2,3] 

如您所见,对于矩阵,A x B 不同于 B x A。

矩阵标量乘法

您可以将矩阵与标量相乘。在这种情况下,每个单元格都乘以该数字:
3 x [1,2] = [ 3, 6]
    [4,7]   [12,21]

反转矩阵
矩阵除法是不可能的,但您可以创建矩阵的求逆,使得 A x A-inv 是一个除主对角线外全为零的矩阵:
[ 1, 0, 0 ]
[ 0, 1, 0 ]
[ 0, 0, 1 ]

矩阵求逆只能用方阵完成,这是一项复杂的工作,不需要有结果。

从矩阵 A 开始:
    [ 1, 2, 3 ]
A = [ 1, 3, 4 ]
    [ 2, 5, 1 ]

我们添加 3 个额外的列并用单位矩阵填充它们:
[ 1, 2, 3, 1, 0, 0 ]
[ 1, 3, 4, 0, 1, 0 ]
[ 2, 5, 1, 0, 0, 1 ]

现在我们从第一列开始。我们需要从每一行中减去第一行,这样第一列除了第一行之外只包含零。
为了做到这一点,我们从第二行中减去第一行一次,从第三行中减去两次:
[ 1, 2, 3, 1, 0, 0 ]
[ 0, 1, 1,-1, 1, 0 ]
[ 0, 1,-5,-2, 0, 1 ]

现在我们对第二列重复此操作(第一行两次,第三行一次)
[ 1, 0, 1, 3,-2, 0 ]
[ 0, 1, 1,-1, 1, 0 ]
[ 0, 0,-6,-1,-1, 1 ]

对于第三列,我们有一个小问题。主元数是 -6 而不是 1。但是我们可以通过将整行乘以 -1/6 来解决这个问题:
[ 1, 0, 1,   3,  -2,    0 ]
[ 0, 1, 1,  -1,   1,    0 ]
[ 0, 0, 1, 1/6, 1/6, -1/6 ]

现在我们可以从第一行和第二行中减去第三行:
[ 1, 0, 0, 17/6,-13/6,  1/6 ]
[ 0, 1, 0, -7/6,  5/6,  1/6 ]
[ 0, 0, 1,  1/6,  1/6, -1/6 ]

好的,现在我们有了 A 的逆:
[ 17/6,-13/6,  1/6 ]
[ -7/6,  5/6,  1/6 ]
[  1/6,  1/6, -1/6 ]

我们可以这样写:
      [ 17,-13,  1 ]
1/6 * [ -7,  5,  1 ]
      [  1,  1, -1 ]



    [ 1, 2, 3 ]   [ 17,-13,  1 ]                [ 6, 0, 0 ]    [ 1, 0, 0 ]
A = [ 1, 3, 4 ] x [ -7,  5,  1 ] x 1/6  = 1/6 x [ 0, 6, 0 ] =  [ 0, 1, 0 ]
    [ 2, 5, 1 ]   [  1,  1, -1 ]                [ 0, 0, 6 ]    [ 0, 0, 1 ]

希望这个对你有帮助。

关于math - 学习游戏编程(第 2 部分)(数学),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/487352/

相关文章:

c++ - CUDA:获取 3D 表面的子集

java - 在不损失精度的情况下转换 float 的基数

c++ - HASH 函数和实现多键 HashMap

math - 弹丸的轨迹遇到移动物体(二维)

c++ - 我可以比这更快地将一维 vector 转换为二维 vector 吗?

c++ - 使用运算符重载添加到列表

C++ cin 或 vector clear 不能正常工作

3d - ar.js 3d 模型不显示

javascript - 简单的数学javascript对具有相同变量的所有数据求和

java - 从 .asc 文件开始创建 3D map