1.矩阵及其运算

矩阵的运算:①加②减③标量乘法

④矩阵乘法:

矩阵乘法要有意义的条件是矩阵A的列数和矩阵B的行数必须相同,所以一般不满足交换律

⑤转置矩阵:

⑥矩阵行列式:det A

学习行列式的主要目的是:利用它推导出求逆矩阵的公式

方阵A是可逆的,当且仅当det A ≠ 0

余子阵:去除第i行和第j行得到的(n-1)*(n-1)矩阵0

矩阵的行列式是一种递归定义,detA的A当是二维方阵时,行列式的值就是

元素Aij的代数余子阵:

   如果为矩阵A中每个元素分别计算出Cij,并将其置于矩阵中第i行、第j列的相应位置,那么将获得矩阵A的代数余子式矩阵

伴随矩阵

  代数余子阵的转置

⑦逆矩阵:

可逆矩阵的逆矩阵是唯一的 

矩阵不存在除法的概念,但提供逆矩阵可以求解某些方程:比如

 求解p

2.用DirectXMath库处理矩阵:

XMMATRIX : 由4个XMVECTOR组成,借此使用SIMD技术 --  4x4的矩阵

// XMMATRIX类表示4×4矩阵

// 内部用r来存储4个行向量
XMVECTOR r[4]; 

// 构造方法:
// 4个行向量
XMVECTOR(FXMVECTOR R0,FXMVECTOR R1,FXMVECTOR R2,CXMVECTOR R3); 

// 16个浮点数
XMMATRIX(float m00,float m01,...); 

// 16个浮点数元素数组
explicit XMMATRIX(_in_reads_(16) const float *pArray); 

// 拷贝构造函数
XMMATRIX& operator=(const XMMATRIX& M);

XMMATRIX运算:

1.两个XMMATRIX矩阵:

+ - += -=

* *=

2.XMMATRIX和浮点数:

/ * /= *=

XMMATRIX创建实例的其他方法:

XMMATRIX XM_CALLCONV XMMatrixSet(
    float m00, float m01, float m02, float m03,
    float m10, float m11, float m12, float m13,
    float m20, float m21, float m22, float m23,
    float m30, float m31, float m32, float m33,    
);

DirectXMath文档也建议我们用XMFLOAT4X4来存储类中的矩阵类型数据成员:

struct XMFLOAT4X4{
	union{
		struct{
			float _11,_12,_13,_14;
			float _21,_22,_23,_24;
			float _31,_32,_33,_34;
			float _41,_42,_43,_44;
		};
	};
	float m[4][4];
    // 初始化方式和XMMATRIX类似 -- 1.16个浮点数2.浮点数数组
    // 还可以指定(行数,列数),或=从另一个实例复制
    float operator() (size_t Row, size_t Column)const{return m[Row][Column];}
};

①加载方法:

inline XMMATRIX XM_CALLCONV XMLoadFloat4x4(const XMFLOAT4X4* pSource);

②存储方法:

inline void XM_CALLCONV XMStoreFloat4x4(XMFLOAT4X4* pDestination, FXMMATRIX M);

矩阵函数:直接用于创建特定矩阵

// 返回单位矩阵I
XMMatrixIdentity() 

// bool 判断是否为单位矩阵
XMMatrixIsIdentity(FXMMATRIX M); 

// 返回乘积AB
XMMatrixMultiply(FXMMATRIX A,CXMMATRIX B); 

// 返回转置矩阵
XMMatrixTranspose(FXMMATRIX M); 

// 返回(det M,det M,det M,det M) -- XMVECTOR类型
XMMatrixDeterminant(FXMMATRIX M); 

// 输入:pDeterminant是(det M,det M,det M,det M) 返回M的逆矩阵
XMMatrixInverse(XMVECTOR* pDeterminant, FXMMATRIX M);

假设传入函数的XMVECTOR参数不超过两个,则第一个XMMATRIX参数应当为FXMMATRIX类型,其余的XMMATRIX参数均应当为CXMMATRIX类型

在32位Windows操作系统上的__fastcall调用约定中,XMMATRIX类型的参数是不能传至SSE/SSE2寄存器的,因为这些寄存器只支持3个XMVECTOR参数传入(XMMATRIX视为4个XMVECTOR),所以只能通过堆栈来加以引用 

// 32位typedef const XMMATRIX& FXMMATRIX; typedef const XMMATRIX& CXMMATRIX; // 64位 typedef const XMMATRIX FXMMATRIX; typedef const XMMATRIX& CXMMATRIX;

代码示例:

#include <windows.h> // XMVerifyCPUSupport()函数
#include <DirectXMath.h>
#include <DirectXPackedVector.h>
#include <iostream>
using namespace DirectX;
using namespace DirectX::PackedVector;
using namespace std;

ostream& XM_CALLCONV operator<<(ostream& os, FXMMATRIX m)
{
	XMFLOAT4X4 dest;
	XMStoreFloat4x4(&dest, m);

	for (int i = 0; i < 4; i++) {
		for (int j = 0; j < 4; j++) {
			os << dest.m[i][j] << " ";
		}
		os << "\n";
	}
	return os;
	// 也可以通过cout遍历打印FXMMATRIX的XMVECTOR数组成员r
}

int main()
{
	cout.setf(ios_base::boolalpha);

	// 检查是否支持SSE2指令集
	if (!XMVerifyCPUSupport())
	{
		cout << "direct math not supported" << endl;
		return 0;
	}

	XMMATRIX m1 = XMMatrixIdentity();
	cout << m1 << endl;

	XMMATRIX m2 = XMMatrixSet(
		1.f, 0.f, 0.f, 0.f,
		0.f, 2.f, 0.f, 0.f,
		0.f, 0.f, 4.f, 0.f,
		1.f, 2.f, 3.f, 1.f
	);
	cout << m2 << endl;

	XMMATRIX m3 = XMMatrixTranspose(m2);
	cout << m3 << endl;

	cout << m2 * m3 << endl;
	cout << 2 * m1 << endl;
	cout << m3 - m2 << endl;

	XMVECTOR v = XMMatrixDeterminant(m2);
	XMMATRIX m4 = XMMatrixInverse(&v, m2);
	cout << m4 << endl;
	
}