第七章:矩陣


第一節:矩陣的數學定義

1.矩陣的定義

  在線性代數中,矩陣就是以行和列形式組成的矩形數字塊(向量是標量的數組,矩陣是向量的數組)。

2.矩陣的記法

  矩陣我們通常使用大中括號來表示,也可以使用豎線的方式來表示,通常用大寫字母來表示矩陣。當使用矩陣的分量時,我們用下標法來表示矩陣的分量,注意的是矩陣的分量是從1開始,而不是0。

  

3.方陣

  行數和列數相同的矩陣稱為方陣。方陣的概念非常重要,通常在3D中使用的矩陣就是2x2,3x3,4x4方陣。

  方陣的對角線元素就是方陣中分量行號和列號相同的元素,例如3x3矩陣中的m11,m22,m33這三個分量就是對角線元素,其他的元素則是非對角線元素

  

4.對角矩陣

  在方陣中,如果非對角元素都為0,則該方陣稱為對角矩陣。例如

  

5.單位矩陣

  在對角矩陣中,如果對角線元素都為1,則該對角矩陣為單位矩陣。單位矩陣是一種特殊的對角矩陣,單位矩陣乘以任意矩陣得到都是原來的矩陣。例如,3D單位矩陣如下

  

6.向量的矩陣含義

  向量也可以看做為矩陣,行向量可以看做是1xn矩陣,列向量可以看做nx1矩陣。

7.矩陣的轉置

  所謂的矩陣的轉置就是將矩陣的行元素變為矩陣的列元素,將矩陣的列元素變為矩陣的行元素,矩陣M的轉置記做MT

  

  行向量的矩陣轉置為列向量,列向量的矩陣轉置為行向量。

  對於任意對角矩陣D,都有DT=D,同樣對於單位矩陣I,都有IT = I。

  對於任意矩陣D,都有(DT=D,即矩陣轉置兩次等於其本身。

8.標量和矩陣的乘法

  標量k和矩陣M相乘會得到一個和原矩陣維數相同的矩陣N,矩陣N的每個元素等於矩陣M的每個元素與標量k相乘,公式如下。

  

9.矩陣與矩陣的乘法

  矩陣的乘法定義為一個r x n矩陣A與一個n x c矩陣B相乘,則得到一個r x c矩陣AB。

  例如一個4 x 2矩陣A與一個2 x 5矩陣B相乘,得到的是一個4x5矩陣AB。

  

  對於新得到的矩陣AB記做C,則矩陣C的每個元素Cij等於矩陣A第i行向量與矩陣B第j列向量的點乘結果。示例如下

  

  矩陣C的元素c24就等於矩陣A的第二行向量與矩陣B的第4行向量的點乘的結果。

10.向量與矩陣的乘法

  因為向量也屬於矩陣,所以也必須要滿足矩陣與矩陣的乘法規則,所以對於行向量而言,行向量要左乘矩陣,對於列向量而言,列向量要右乘矩陣。行向量和列向量與一個相同的矩陣相乘的時候會得到不同的結果,因此我們要注意這是行向量和列向量的區別之一,在進行矩陣運算時特別小心。

  示例如下,對於行向量和列向量而言,得到的結果是不一樣的。

  

  我們覺得使用行向量是比較符合的,以為行向量是左乘矩陣,符合我們的書寫和理解,例如vABC,行向量v乘以3個矩陣得到最后的向量。但是對於ABCh,列向量h要從右往左乘才符合我們的理解。在DX3中使用的是行向量,但是在OpenGL中使用的是列向量,因此在運算前要注意行向量和列向量的轉置才能保證不會出現計算的問題。

第二節:矩陣的幾何解釋

1.2D向量與矩陣相乘的幾何意義

  對於2D向量v乘以矩陣M得到的依然是2D向量,所以我們可以理解矩陣M是對向量v的一種坐標變換。

  

  2D向量由原來的[1 1]變換為了[1 3]在幾何中的表示如下,我們可以將矩陣M的每一行都能解釋為轉換后的基向量。所以原來的向量[1 1]可以被分解為[1 0]和[0 1],矩陣可以分解為[2 1]和[-1 2],那么可以看做基向量x,y軸從向量v變換到矩陣M。

  

  我們發現不光是2D向量v進行了變換,在這一個區域里的點都得到了關於矩陣M的變換。我們可以用下面的小機器人來表示。

  

2.3D向量與矩陣相乘的幾何意義

  3D向量與矩陣相乘表示的含義是一樣的,只不過與3D向量相乘的矩陣是影響的x,y,z三個軸。

  

3.矩陣的幾何意義

  • 向量的幾何意義是一條有向線段,而且向量可以進行三角形法則,所以我們可以將向量進行拆分成坐標軸的加法或者減法。
  • 矩陣我們可以將每一行元素看做一個向量,它用來表示我們最終向量所對應坐標軸的最終狀態,這就是矩陣的幾何意義。
  • 向量與矩陣的乘法本質就是坐標的轉換,其幾何意義就是表示向量拆分后,坐標進行變換,變成矩陣的每一行元素所表示的向量的位置。

第三節:3x3矩陣乘法的編程實現

1.3x3矩陣的乘法實現(頭文件)

#pragma once
#include <iostream>

using namespace std;

class Matrix3x3
{
public:
    /* 3x3矩陣的元素 */
    float m11, m12, m13;
    float m21, m22, m23;
    float m31, m32, m33;
public:
    /* 默認構造函數 */
    Matrix3x3();
public:
    /* 矩陣相乘 */
    Matrix3x3& operator*(const Matrix3x3& otherMatrix);
public:
    /* 打印矩陣數據 */
    void print();
};

2.3x3矩陣的乘法實現(cpp文件)

#include "Matrix3x3.h"

/* 默認構造函數 */
Matrix3x3::Matrix3x3()
{
}
/* 3x3矩陣的乘法 */
Matrix3x3& Matrix3x3::operator*(const Matrix3x3& otherMatrix)
{
    Matrix3x3 m;

    m.m11 = this->m11*otherMatrix.m11 + this->m12*otherMatrix.m21 + this->m13*otherMatrix.m31;
    m.m12 = this->m11*otherMatrix.m12 + this->m12*otherMatrix.m22 + this->m13*otherMatrix.m32;
    m.m13 = this->m11*otherMatrix.m13 + this->m12*otherMatrix.m23 + this->m13*otherMatrix.m33;

    m.m21 = this->m21*otherMatrix.m11 + this->m22*otherMatrix.m12 + this->m23*otherMatrix.m31;
    m.m22 = this->m21*otherMatrix.m12 + this->m22*otherMatrix.m22 + this->m23*otherMatrix.m32;
    m.m23 = this->m21*otherMatrix.m13 + this->m22*otherMatrix.m23 + this->m23*otherMatrix.m33;

    m.m31 = this->m31*otherMatrix.m11 + this->m32*otherMatrix.m21 + this->m33*otherMatrix.m31;
    m.m32 = this->m31*otherMatrix.m12 + this->m32*otherMatrix.m22 + this->m33*otherMatrix.m32;
    m.m33 = this->m31*otherMatrix.m13 + this->m32*otherMatrix.m23 + this->m33*otherMatrix.m33;
    
    return m;
}
/* 打印矩陣元素 */
void Matrix3x3::print()
{
    cout << m11 << "\t" << m12 << "\t" << m13 << endl;
    cout << m21 << "\t" << m22 << "\t" << m23 << endl;
    cout << m31 << "\t" << m32 << "\t" << m33 << endl;
}

第四節:3d向量和3x3矩陣乘法的編程實現

1.頭文件(和前面3d向量的編程實現類似的則省略)

#pragma once
#include <iostream>
#include "Matrix3x3.h"

using namespace std;

class Vector3
{
        .......
    // 重載 "*" 操作符(向量和矩陣相乘)
    Vector3 operator*(const Matrix3x3& matrix3x3);
        ......
};

2.cpp文件(和前面3d向量的編程實現類似的則省略)

#include "Vector3.h"

// 其他操作......

// 重載 "*" 操作符(向量和矩陣相乘)
Vector3 Vector3::operator*(const Matrix3x3& matrix3x3)
{
    Vector3 vector3;
    vector3.x = this->x*matrix3x3.m11 + this->y*matrix3x3.m21 + this->z*matrix3x3.m31;
    vector3.y = this->x*matrix3x3.m12 + this->y*matrix3x3.m22 + this->z*matrix3x3.m32;
    vector3.z = this->x*matrix3x3.m13 + this->y*matrix3x3.m23 + this->z*matrix3x3.m33;
    return vector3;
}

// 其他操作......


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM