向量點(diǎn)乘
兩個(gè)向量點(diǎn)乘(x1,y1,z1).(x2,y2,z2),結(jié)果是一個(gè)數(shù)值
//向量點(diǎn)乘
inline float vec3_dot(Vec3& v1,Vec3& v2){
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
}
點(diǎn)乘的幾何意義
計(jì)算兩個(gè)向量正交性
當(dāng)結(jié)果為0,表示兩個(gè)向量垂直
當(dāng)結(jié)果>0,表示兩個(gè)向量方向相同,夾角在0~90度
當(dāng)結(jié)果<0,表示兩個(gè)向量方向相反,夾角在90~180度
- 兩個(gè)向量夾角0~90度
(0.5,0.5,0),(0.5,0,0)計(jì)算這兩個(gè)點(diǎn)的點(diǎn)乘結(jié)果
0.50.5+0.50+0*0 = 0.25

- 兩個(gè)向量垂直
(0,0.5,0),(0.5,0,0)
00.5+0.50+0*0 = 0

- 兩個(gè)向量夾角90~180度
(0.5,0.5,0),(-0.5,0,0)
0.5*-0.5+0.50+00 = -0.25

計(jì)算兩個(gè)向量的夾角
cos(θ) = (A·B) / (||A|| * ||B||)
其中:||A|| = √(A?2 + A?2 + ... + A?2),||B|| = √(B?2 + B?2 + ... + B?2)
向量叉乘
公式
兩個(gè)三維向量 ?? = [???, ???, ???] 和 ?? = [???, ???, ???]
AxB叉乘結(jié)果是一個(gè)向量,通俗的講法就是法向量,該向量垂直于 A ,B 向量構(gòu)成的平面。
兩個(gè)向量的叉乘公式如下:
<aside>
?? ?? × ?? = [?????? - ??????, ?????? - ??????, ?????? - ??????]
</aside>
inline Vec3 vec3_cross(Vec3& v1,Vec3& v2){
Vec3 v;
v.x = v1.y * v2.z - v1.z * v2.y;
v.y = v1.z * v2.x - v1.x * v2.z;
v.z = v1.x * v2.y - v1.y * v2.x;
return v;
}
叉乘的幾何意義
計(jì)算法向量
向量C = AxB
方向的判斷
根據(jù)右手法則,axb表示紅色法向量,表示大拇指的方向,四指從a指向b。
bxa或者-axb表示黃色法向量,表示大拇指的方向,四指方向從b指向a

向量 A 和向量B 構(gòu)成的平行四邊形面積
根據(jù)向量叉乘的性質(zhì),兩個(gè)向量的叉乘結(jié)果的模長(zhǎng)等于這兩個(gè)向量所在平行四邊形的面積。|?? × ??| = |??| × |??| × sin(θ),|??| 表示向量 ?? 的模長(zhǎng),|??| 表示向量 ?? 的模長(zhǎng),θ 表示向量 ?? 和 ?? 之間的夾角
面積的計(jì)算方式:
面積 = || ?? × ?? ||表示向量 ?? 叉乘向量 ?? 的模,也就是叉積的大小。


平行四邊形面積:s = a*h
|A| = |A| = √(a?2 + a?2 + ... + a?2)
計(jì)算兩個(gè)向量 A B的所形成的平行四邊形的面積

矩陣運(yùn)算
矩陣加法/減法
前提:同型矩陣。也就是兩個(gè)矩陣的行列都要一樣,結(jié)果還是一個(gè)矩陣
矩陣數(shù)乘
一個(gè)數(shù)值與矩陣相乘就叫做矩陣的數(shù)乘,結(jié)果還是一個(gè)矩陣

矩陣轉(zhuǎn)置
把矩陣 A 的行和列相互交互所產(chǎn)生的矩陣稱為 A 的轉(zhuǎn)置矩陣,結(jié)果還是一個(gè)矩陣
mxn → nxm

//交換兩個(gè)數(shù)
inline void swapf(float &a,float &b){
float tmp = a;
a = b;
b = tmp;
}
//矩陣轉(zhuǎn)置
inline Mat3x3 mat3x3_transpose(Mat3x3 &matrix){
Mat3x3 result = matrix;
swapf(result.r0.y,result.r1.x);
swapf(result.r0.z,result.r2.x);
swapf(result.r1.z,result.r2.y);
return result;
}
矩陣相乘
前提:矩陣 A 的列數(shù)等于矩陣 B 的行數(shù),A 矩陣mxn B 矩陣 nxp,因此矩陣的乘法不滿足交換律
矩陣 C = A x B = mxp
矩陣行列式
一個(gè)矩陣的行列式的結(jié)果是一個(gè)數(shù),它的幾何意義是矩陣的行列式結(jié)果不為 0,表示該矩陣是可逆的。

inline float mat3x3_determinant(Mat3x3& matrix){
return matrix.r0.x * (matrix.r1.y * matrix.r2.z -matrix.r1.z * matrix.r2.y)
-matrix.r0.y * (matrix.r1.x * matrix.r2.z -matrix.r1.z * matrix.r2.x)
+matrix.r0.z * (matrix.r1.x * matrix.r2.y -matrix.r1.y * matrix.r2.x);
}
伴隨矩陣
矩陣 A 的伴隨矩陣使用 A* 表示
inline Mat3x3 companion_mat3x3(Mat3x3& matrix){
Mat3x3 inv;
Vec3 v1 = matrix.r0;
Vec3 v2 = matrix.r1;
Vec3 v3 = matrix.r2;
float a11 = 1 * (v2.y * v3.z - v2.z * v3.y);
float a12 = -1 * (v2.x * v3.z - v3.x * v2.z);
float a13 = 1 * (v2.x * v3.y - v2.y * v3.x);
float a21 = -1 * (v1.y * v3.z - v1.z * v3.y);
float a22 = 1 * (v1.x * v3.z - v1.z * v3.x);
float a23 = -1* (v1.x * v3.y - v1.y * v3.x);
float a31 = 1 * (v1.y * v2.z - v1.z * v2.y);
float a32 = -1 * (v1.x * v2.z - v1.z * v2.x);
float a33 = 1 * (v1.x * v2.y - v1.y * v2.x);
inv.r0.x = a11;
inv.r0.y = a12;
inv.r0.z = a13;
inv.r1.x = a21;
inv.r1.y = a22;
inv.r1.z = a23;
inv.r2.x = a31;
inv.r2.y = a32;
inv.r2.z = a33;
//轉(zhuǎn)置矩陣
mat3x3_transpose(inv);
// inv.r0.x = a11;
// inv.r0.y = a21;
// inv.r0.z = a31;
// inv.r1.x = a12;
// inv.r1.y = a22;
// inv.r1.z = a32;
// inv.r2.x = a13;
// inv.r2.y = a23;
// inv.r2.z = a33;
return inv;
}
矩陣 A 的伴隨矩陣的計(jì)算過程如下所示

逆矩陣
矩陣 A 的逆矩陣 = 矩陣A的伴隨矩陣/矩陣A的行列式

|A| 矩陣A的行列式如果不為0,則表示該矩陣是可膩的。
inline void vec3_div(Vec3& vec3,float div){
vec3.x = vec3.x/div;
vec3.y = vec3.y /div;
vec3.z = vec3.z/div;
}
inline void mat3x3_div(Mat3x3& m,float div){
vec3_div(m.r0,div);
vec3_div(m.r1,div);
vec3_div(m.r2,div);
}
inline Mat3x3 mat3x3_reverse(Mat3x3& matrix){
float determinant = mat3x3_determinant(matrix);
Mat3x3 compain_matrix = companion_mat3x3(matrix);
mat3x3_div(compain_matrix,determinant);
return compain_matrix;
}
下面是通過這個(gè)公式來推導(dǎo)出矩陣 A 的逆矩陣

參考
線性代數(shù)課程
本文是筆者學(xué)習(xí)之后的總結(jié),方便日后查看學(xué)習(xí),有任何不對(duì)的地方請(qǐng)指正。
記錄于2023年11月21日