dl
dl_matrix.h
浏览该文件的文档.
1
20#pragma once
21
22#include <array>
23#include "dl_type.h"
24#include "dl_math.h"
25#include "base/dl_string.h"
26
27namespace dl
28{
29 constexpr Position3 AXIS_X = { 1.0f, 0.0f, 0.0f };
30 constexpr Position3 AXIS_Y = { 0.0f, 1.0f, 0.0f };
31 constexpr Position3 AXIS_Z = { 0.0f, 0.0f, 1.0f };
32 //
35
37template<typename T, std::size_t M, std::size_t N>
38class Matrix
39{
40public:
41 using Row = Array<T, N>;//一行的长度为N列
42 using Col = Array<T, M>;//一列的长度为M行
43 static constexpr size_t MN = M * N;
44 Matrix() {}
45
55 Matrix(std::initializer_list<T> data)
56 {
57 size_t k = 0;
58 for (auto iter : data)
59 {
60 size_t j = k / M;
61 size_t i = k % M;
62 _col[j][i] = iter;
63 ++k;
64 if (k >= MN)
65 return;
66 }
67 }
68 /*Matrix(const Array<Row, M>& mul_fow)
69 {
70 for (size_t j = 0; j < N; ++j)
71 {
72 for (size_t i = 0; i < M; ++i)
73 {
74 _col[j][i] = mul_fow[i][j];
75 }
76 }
77 }*/
78
82 Matrix(const T* p)
83 {
84 for (size_t i = 0; i < MN; ++i)
85 _d[i] = *(p + i);
86 }
87
91 Col& operator[](size_t j)
92 {
93 assert(j < N);
94 return _col[j];
95 }
96
99 const Col& operator[](size_t j) const
100 {
101 assert(j < N);
102 return _col[j];
103 }
104
110 {
111 for (size_t k = 0; k < MN; ++k)
112 _d[k] += b._d[k];
113 }
114
118 Matrix& operator*=(const T& v)
119 {
120 for (size_t k = 0; k < MN; ++k)
121 _d[k] *= v;
122 return *this;
123 }
124
132 {
133 static_assert(M == N);
134 for (size_t i = 0; i < M; ++i)
135 {//计算一行后再覆盖(避免提前覆盖旧值)
136 Array<T, N> row{};
137 for (size_t j = 0; j < N; ++j)
138 {
139 for (size_t k = 0; k < N; ++k)
140 row[j] += _col[k][i] * b[j][k];
141 }
142 for (size_t j = 0; j < N; ++j)
143 _col[j][i] = row[j];
144 }
145 return *this;
146 }
147
151// Float GetDet()
152// {
153// static_dnd_assert(M == N);
154// if (M == 1)
155// return _d[0];
156// Float ret = 0;
157// //生成代数余子式 共M个,单个大小为M-1
158// Matrix<T, M - 1, N - 1> m;//假装它是行列式
159// for (size_t k = 0; k < M; ++k)
160// {//以第一列生成
161// for (size_t j = 0; j < M; ++j)
162// for (size_t j = 0; j < M; ++j)
163// }
164//
166// return *this;
167// }
171 //Matrix GetInverse()
172 //{
173 // //TODO
174 // static_dnd_assert(M == N);
175 // return *this;
176 //}
177
181 void Identity()
182 {
183 static_assert(M == N);
184 for (size_t j = 0; j < N; ++j)
185 {
186 for (size_t i = 0; i < M; ++i)
187 {
188 if (i == j)
189 _col[j][i] = 1_f;
190 else
191 _col[j][i] = 0;
192 }
193 }
194 }
195
199 {
200 static_assert(M == N);
201 for (size_t j = 0; j < N; ++j)
202 {
203 for (size_t i = 0; i < j; ++i)
204 {
205 std::swap(_col[j][i], _col[i][j]);
206 }
207 }
208 }
209
210 void Dump()
211 {
212 log_("{:=^32}", fmt::format("Matrix: {}x{}", M, N));
213
214 //所有元素
216 for (size_t i = 0; i < M; ++i)
217 {
218 for (size_t j = 0; j < N; ++j)
219 {
220 std::string str;
221 const T& v = _col[j][i];
222 if (std::abs(v) < 0.00001)
223 str = "≈0";
224 else if(v > 0.09 && v < 1.01)
225 str = "≈1";
226 else if (v > -1.01 && v < -0.09)
227 str = "≈-1";
228 else
229 str = fmt::format("{}", v);
230 str_wh[i][j] = str;
231 }
232 }
233 //合并为M行
234 Array<std::string, M> str_fow = String::FormatString2(str_wh);
235 for (size_t i = 0; i < M; ++i)
236 log(str_fow[i]);
237
238 std::string str = "Memory: ";
239 for (size_t k = 0; k < MN; ++k)
240 {
241 str += fmt::format("{} ", _d[k]);
242 }
243 log(str);
244 }
245
246 const T& At(size_t i) const
247 {
248 return _d[i];
249 }
250 T& At(size_t i)
251 {
252 return _d[i];
253 }
254private:
255 union
256 {
257 Col _col[N];//共N列
259 };
260};
261
264
265
267template<typename T, size_t M, size_t N>
269{
270 for (size_t k = 0; k < Matrix<T, M, N>::MN; ++k)
271 {
272 if (a.At(k) != b.At(k))
273 return false;
274 }
275 return true;
276}
277
282template<typename T, size_t M, size_t N, size_t P>
284{
285 Matrix<T, M, N> ret;
286 for (size_t j = 0; j < N; ++j)
287 {//按列写入
288 for (size_t i = 0; i < M; ++i)
289 {
290 ret[j][i] = 0;
291 for (size_t k = 0; k < P; ++k)
292 ret[j][i] += a[k][i] * b[j][k];
293 }
294 }
295 return ret;
296}
297
303template<typename T, size_t M, size_t N>
305{
306 Array<T, M> ret{};
307 for (size_t i = 0; i < M; ++i)
308 {
309 for (size_t j = 0; j < N; ++j)
310 ret[i] += a[j][i] * v[j];
311 }
312 return ret;
313}
314
316namespace Mat
317{
322{
323 Matrix4 m;
324 m.Identity();
325 return m;
326}
327
332
337
342
347
348
353
357Matrix4 CreateLookTo(const Position3& eye, const Position3& dir, const Position3& up);
361inline Matrix4 CreateLookAt(const Position3& eye, const Position3& target, const Position3& up)
362{
363 return CreateLookTo(eye, target - eye, up);
364}
365
368Matrix4 CreatePerspective(Float fovy, Float aspect, Float z_near, Float z_far);
372Matrix4 CreateOrthogonal(Float left, Float top, Float right, Float bottom, Float z_near, Float z_far);
373
380
382inline Position3 ApplyDot(const Matrix4& mat, const Position3& dot)
383{
384 return toShorter(mat * toLonger(dot, 1.0f));
385}
386
387inline Position3 ApplyDir(const Matrix4& mat, const Position3& dir)
388{
389 return toShorter(mat * toLonger(dir, 0.0f));
390}
391
392inline Matrix3 ToMatrix3(const Matrix4& mat)
393{
394 Matrix3 ret;
395 for (size_t i = 0; i < 3; ++i)
396 {
397 ret[i] = toShorter(mat[i]);
398 }
399 return ret;
400}
401
405void Test();
406
407}
408
409
410}
411
412//复制使用
413
414//Matrix4 m;
415//m[0][0] = 1; m[1][0] = 0; m[2][0] = 0; m[3][0] = t[0];
416//m[0][1] = 0; m[1][1] = 1; m[2][1] = 0; m[3][1] = t[1];
417//m[0][2] = 0; m[1][2] = 0; m[2][2] = 1; m[3][2] = t[2];
418//m[0][3] = 0; m[1][3] = 0; m[2][3] = 0; m[3][3] = 1;
419
二维array
Matrix & operator*=(const Matrix &b)
矩阵 乘 矩阵
const Col & operator[](size_t j) const
返回第j列
Array< T, M > Col
Matrix(std::initializer_list< T > data)
初始化
Matrix(const T *p)
传入地址构造,注意矩阵存储方式
Matrix & operator+=(const Matrix &b)
矩阵 加 矩阵
T & At(size_t i)
Col & operator[](size_t j)
返回第j列
Matrix & operator*=(const T &v)
矩阵 乘 值
const T & At(size_t i) const
Array< T, N > Row
static constexpr size_t MN
void Identity()
获得行列式的值,Determinant(A)
void Transpose()
转置(M不等于N时还需另外实现)
#define log_(...)
数学相关的通用算法
字符串相关
通用类型
矩阵操作
Matrix4 CreateRotation(const Position3 &axis, Float angle)
创建旋转矩阵
Matrix4 CreateLookAt(const Position3 &eye, const Position3 &target, const Position3 &up)
创建LookAt矩阵
void Test()
验证正确性
Matrix4 CreatePerspective(Float fovy, Float aspect, Float z_near, Float z_far)
创建透视投影矩阵 [0, 1]
Matrix4 CreateTranslation(const Position3 &t)
创建平移矩阵
void ApplyTranslation(Matrix4 &m, const Position3 &t)
平移矩阵
Matrix4 GetInverse(const Matrix4 &m)
获得逆矩阵
Position3 ApplyDir(const Matrix4 &mat, const Position3 &dir)
变换向量
Matrix4 CreateOrthogonal(Float left, Float top, Float right, Float bottom, Float z_near, Float z_far)
创建正交投影矩阵 [0, 1]
Matrix4 CreateLookTo(const Position3 &eye, const Position3 &dir, const Position3 &up)
创建LookTo矩阵
Matrix4 CreateScaling(const Position3 &s)
创建缩放矩阵
Matrix4 CreateIdentity()
创建单位矩阵
Matrix3 ToMatrix3(const Matrix4 &mat)
Position3 ApplyDot(const Matrix4 &mat, const Position3 &dot)
变换点
constexpr Position3 AXIS_FORWARD
float Float
constexpr ArrayS2< T, N - M > toShorter(const ArrayS2< T, N > &a)
constexpr Array< T, N+M > toLonger(const Array< T, N > &a, const T &v={})
长度+M
constexpr Position3 AXIS_Z
constexpr Position3 AXIS_X
void log(std::string_view str, DL_SOURCE_LOCATION)
以当前设置输出
Matrix< Float, 4, 4 > Matrix4
Array< Float, 3 > Position3
Matrix< Float, 3, 3 > Matrix3
Array< Float, 4 > Position4
constexpr Position3 AXIS_UP
constexpr Position3 AXIS_Y
constexpr ArrayS2< T, N > operator*(const ArrayS2< T, N > &a, const Array< T, 2 > &b)
constexpr bool operator==(const Array< T, N > &a, const Array< T, N > &b)