1 /++ 2 Matrix management module. 3 4 Macros: 5 LREF = <a href="#$1">$1</a> 6 HREF = <a href="$1">$2</a> 7 IDENTITY_IMG = <img src="https://latex.codecogs.com/svg.image?I_{n}&space;=&space;\begin{bmatrix}&space;1&&space;0&space;&&space;0&space;&&space;0&space;\\&space;0&&space;1&space;&&space;0&space;&&space;0&space;\\&space;0&&space;0&space;&&space;1&space;&&space;0&space;\\&space;0&&space;0&space;&&space;0&space;&&space;1&space;\\\end{bmatrix}" title="I_{n} = \begin{bmatrix} 1& 0 & 0 & 0 \\ 0& 1 & 0 & 0 \\ 0& 0 & 1 & 0 \\ 0& 0 & 0 & 1 \\\end{bmatrix}" /> 8 TRANSLATE_IMG = <img src="https://latex.codecogs.com/svg.image?\begin{bmatrix}&space;1&space;&&space;0&space;&&space;0&space;&&space;x&space;\\&space;0&space;&&space;1&space;&&space;0&space;&&space;y&space;\\&space;0&space;&&space;0&space;&&space;1&space;&&space;z&space;\\&space;0&space;&&space;0&space;&&space;0&space;&&space;1&space;\\\end{bmatrix}" title="\begin{bmatrix} 1 & 0 & 0 & x \\ 0 & 1 & 0 & y \\ 0 & 0 & 1 & z \\ 0 & 0 & 0 & 1 \\\end{bmatrix}" /> 9 SCALE_IMG = <img src="https://latex.codecogs.com/svg.image?\begin{bmatrix}&space;x&space;&&space;0&space;&&space;0&space;&&space;0&space;\\&space;0&space;&&space;y&space;&&space;0&space;&&space;0&space;\\&space;0&space;&&space;0&space;&&space;z&space;&&space;0&space;\\&space;0&space;&&space;0&space;&&space;0&space;&&space;1&space;\\\end{bmatrix}" title="\begin{bmatrix} x & 0 & 0 & 0 \\ 0 & y & 0 & 0 \\ 0 & 0 & z & 0 \\ 0 & 0 & 0 & 1 \\\end{bmatrix}" /> 10 ROTATE_IMG = <img src="https://latex.codecogs.com/svg.image?xfactor&space;=&space;\begin{bmatrix}&space;1&space;&&space;0&space;&&space;0&space;&&space;0&space;\\&space;0&space;&&space;cos&space;\o&space;&&space;-sin&space;\o&space;&&space;0&space;\\&space;0&space;&&space;sin&space;\o&space;&&space;cos&space;\o&space;&&space;0&space;\\&space;0&space;&&space;0&space;&&space;0&space;&&space;1&space;\\\end{bmatrix},y-factor&space;=\begin{bmatrix}&space;cos\psi&space;&&space;0&space;&&space;sin\psi&space;&&space;0&space;\\&space;0&space;&&space;1&space;&&space;0&space;&&space;0&space;\\&space;-sin\psi&space;&&space;0&space;&&space;cos\psi&space;&space;&&space;0&space;\\&space;0&space;&&space;0&space;&&space;0&space;&&space;1&space;\\\end{bmatrix},z-factor=&space;\begin{bmatrix}&space;cos\chi&space;&space;&&space;-sin\chi&space;&&space;0&space;&&space;0&space;\\&space;sin\chi&space;&&space;cos\chi&space;&&space;0&space;&&space;0&space;\\&space;0&space;&&space;0&space;&&space;1&space;&&space;0&space;\\&space;0&space;&&space;0&space;&&space;0&space;&&space;1&space;\\\end{bmatrix}" title="xfactor = \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & cos \o & -sin \o & 0 \\ 0 & sin \o & cos \o & 0 \\ 0 & 0 & 0 & 1 \\\end{bmatrix},y-factor =\begin{bmatrix} cos\psi & 0 & sin\psi & 0 \\ 0 & 1 & 0 & 0 \\ -sin\psi & 0 & cos\psi & 0 \\ 0 & 0 & 0 & 1 \\\end{bmatrix},z-factor= \begin{bmatrix} cos\chi & -sin\chi & 0 & 0 \\ sin\chi & cos\chi & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \\\end{bmatrix}" /> 11 12 Authors: $(HREF https://github.com/TodNaz,TodNaz) 13 Copyright: Copyright (c) 2020 - 2021, TodNaz. 14 License: $(HREF https://github.com/TodNaz/Tida/blob/master/LICENSE,MIT) 15 +/ 16 module tida.matrix; 17 18 alias mat4 = float[4][4]; /// Matrix alias 19 20 /++ 21 A square matrix, the elements of the main diagonal of which are equal to one 22 of the field, and the rest are equal to zero. 23 24 $(IDENTITY_IMG) 25 +/ 26 @property float[4][4] identity() @safe nothrow pure 27 { 28 return [ 29 [1, 0, 0, 0], 30 [0, 1, 0, 0], 31 [0, 0, 1, 0], 32 [0, 0, 0, 1] 33 ]; 34 } 35 36 /++ 37 Increases the matrix by a specified factor along the specified axes. 38 39 Params: 40 x = X-axis scaling factor. 41 y = Y-axis scaling factor. 42 z = Z-axis scaling factor. 43 44 Returns: 45 Scaling matrix. 46 47 See_Also: 48 $(HREF https://en.wikipedia.org/wiki/Scaling_(geometry), Scaling (geometry) - Wikipedia.) 49 50 $(SCALE_IMG) 51 +/ 52 float[4][4] scaleMat(float x, float y, float z = 1.0f) @safe nothrow pure 53 { 54 float[] v = [x, y, z, 1.0f]; 55 float[4][4] mat = identity(); 56 57 for (int i = 0; i < 4; ++i) 58 for (int j = 0; j + 1 < 4; ++j) 59 mat[i][j] *= v[j]; 60 61 return mat; 62 } 63 64 /++ 65 Increases the matrix by a specified factor along the specified axes. 66 67 Params: 68 mat = Matrix to be scaled. 69 x = X-axis scaling factor. 70 y = Y-axis scaling factor. 71 z = Z-axis scaling factor. 72 73 Returns: 74 Scaling matrix. 75 76 See_Also: 77 $(HREF https://en.wikipedia.org/wiki/Scaling_(geometry), Scaling (geometry) - Wikipedia.) 78 79 $(SCALE_IMG) 80 +/ 81 float[4][4] scale(float[4][4] mat, float x, float y, float z = 1.0f) @safe nothrow pure 82 { 83 return mulmat(mat, scaleMat(x, y, z)); 84 } 85 86 /++ 87 Moves the matrix along the specified axes by the specified amount. 88 89 Params: 90 x = X-axis move factor. 91 y = Y-axis move factor. 92 z = Z-axis move factor. 93 94 Returns: 95 Moved matrix. 96 97 See_Also: 98 $(HREF https://en.wikipedia.org/wiki/Translation_(geometry), Translation (geometry) - Wikipedia) 99 100 $(TRANSLATE_IMG) 101 +/ 102 float[4][4] translation(float x, float y, float z) @safe nothrow pure 103 { 104 auto mat = identity(); 105 106 mat[3][0] = x; 107 mat[3][1] = y; 108 mat[3][2] = z; 109 110 return mat; 111 } 112 113 /++ 114 Moves the matrix provided in the arguments along the given axes with the 115 given values. 116 117 Params: 118 mat = The matrix to be moved. 119 x = X-axis move factor. 120 y = Y-axis move factor. 121 z = Z-axis move factor. 122 123 Returns: 124 Matrix that was previously cast in the matrix and is now moved by the function. 125 126 See_Also: 127 $(HREF https://en.wikipedia.org/wiki/Translation_(geometry), Translation (geometry) - Wikipedia) 128 129 $(TRANSLATE_IMG) 130 +/ 131 float[4][4] translate(float[4][4] mat, float x, float y, float z) @safe nothrow pure 132 { 133 return mulmat(mat, translation(x, y, z)); 134 } 135 136 /++ 137 Gives the rotation matrix. 138 139 Params: 140 angle = Angle rotation. 141 x = X-axis rotate factor. 142 y = Y-axis rotate factor. 143 z = Z-axis rotate factor. 144 145 Returns: 146 Rotation matrix. 147 148 Also_See: 149 $(HREF https://en.wikipedia.org/wiki/Rotation_matrix, Rotation matrix - Wikipedia) 150 151 $(ROTATE_IMG) 152 +/ 153 float[4][4] rotateMat(float angle, float x, float y, float z) @safe nothrow pure 154 { 155 import std.math; 156 157 float[4][4] res = identity(); 158 159 const float c = cos(angle); 160 const oneMinusC = 1 - c; 161 const float s = sin(angle); 162 163 res[0][0] = x * x * oneMinusC + c; 164 res[0][1] = x * y * oneMinusC - z * s; 165 res[0][2] = x * z * oneMinusC + y * s; 166 res[1][0] = y * x * oneMinusC + z * s; 167 res[1][1] = y * y * oneMinusC + c; 168 res[1][2] = y * z * oneMinusC - x * s; 169 res[2][0] = z * x * oneMinusC - y * s; 170 res[2][1] = z * y * oneMinusC + x * s; 171 res[2][2] = z * z * oneMinusC + c; 172 173 return res; 174 } 175 176 /++ 177 Gives the rotation matrix. 178 179 Params: 180 mat = Rotation matrix. 181 angle = Angle rotation. 182 x = X-axis rotate factor. 183 y = Y-axis rotate factor. 184 z = Z-axis rotate factor. 185 186 Returns: 187 Rotation matrix. 188 189 Also_See: 190 $(HREF https://en.wikipedia.org/wiki/Rotation_matrix, Rotation matrix - Wikipedia) 191 192 $(ROTATE_IMG) 193 +/ 194 float[4][4] rotateMat(float[4][4] mat, float angle, float x, float y, float z) @safe nothrow pure 195 { 196 return mulmat(mat, rotateMat(angle, x, y, z)); 197 } 198 199 /++ 200 Euler method rotation matrix. 201 202 Params: 203 roll = Roll-Axis. 204 pitch = Pitch-Axis. 205 yaw = Yaw-Axis. 206 207 Returns: 208 Rotated matrix. 209 210 See_Also: 211 $(HREF https://en.wikipedia.org/wiki/Rotation_matrix, Rotation matrix - Wikipedia) 212 +/ 213 float[4][4] eulerRotateMat(float roll, float pitch, float yaw) @safe nothrow pure 214 { 215 import std.math; 216 217 float[4][4] xres = identity(); 218 float[4][4] yres = identity(); 219 float[4][4] zres = identity(); 220 221 immutable ct = [cos(roll), cos(pitch), cos(yaw)]; 222 immutable st = [sin(roll), sin(pitch), sin(yaw)]; 223 224 xres[0][0] = ct[0]; 225 xres[0][1] = st[0]; 226 xres[1][0] = -st[0]; 227 xres[1][1] = ct[0]; 228 229 yres[0][0] = ct[1]; 230 yres[0][2] = -st[1]; 231 yres[2][0] = st[1]; 232 yres[2][2] = ct[1]; 233 234 zres[0][0] = ct[2]; 235 zres[0][1] = st[2]; 236 zres[1][0] = -st[2]; 237 zres[1][1] = ct[2]; 238 239 mat4 result = identity(); 240 241 result = mulmat(result, xres); 242 result = mulmat(result, yres); 243 result = mulmat(result, zres); 244 245 return result; 246 } 247 248 /++ 249 Euler method rotation matrix. 250 251 Params: 252 mat = Rotation matrix. 253 roll = Roll-Axis. 254 pitch = Pitch-Axis. 255 yaw = Yaw-Axis. 256 257 Returns: 258 Rotated matrix. 259 260 See_Also: 261 $(HREF https://en.wikipedia.org/wiki/Rotation_matrix, Rotation matrix - Wikipedia) 262 +/ 263 float[4][4] eulerRotate(float[4][4] mat, float roll, float pitch, float yaw) @safe nothrow pure 264 { 265 return mulmat(mat, eulerRotateMat(roll, pitch, yaw)); 266 } 267 268 /++ 269 Multiply two matrices. 270 271 Params: 272 a = First matrix. 273 b = Second matrix. 274 275 Returns: 276 Multiple matrix. 277 278 See_Also: 279 $(HREF https://en.wikipedia.org/wiki/Matrix_multiplication, Matix multiplication - Wikipedia) 280 +/ 281 float[4][4] mulmat(float[4][4] a, float[4][4] b) @safe nothrow pure 282 { 283 float[4][4] result = 0.0f; 284 285 for (int i = 0; i < 4; ++i) 286 { 287 for (int j = 0; j < 4; ++j) 288 { 289 float sum = 0.0f; 290 291 for (int k = 0; k < 4; ++k) 292 sum += a[i][k] * b[k][j]; 293 294 result[i][j] = sum; 295 } 296 } 297 298 return result; 299 } 300 301 /// Ortho matrix generate 302 float[4][4] ortho(float left, float right, float bottom, float top, float zNear = -1.0f, float zFar = 0.0f) 303 @safe nothrow pure 304 { 305 immutable defl = 0.0f; 306 307 immutable mRL = right - left; 308 immutable mTB = top - bottom; 309 immutable mFN = zFar - zNear; 310 311 immutable tRL = -(right + left) / mRL; 312 immutable tTB = -(top + bottom) / mTB; 313 immutable tFN = -(zFar + zNear) / mFN; 314 315 return [ 316 [2 / mRL, defl, defl, defl], 317 [defl, 2 / mTB, defl, defl], 318 [defl, defl, -2 / mFN, defl], 319 [ tRL, tTB, tFN, 1.0f] 320 ]; 321 } 322 323 import tida.vector; 324 325 /++ 326 Multiple matrix and vector. 327 +/ 328 Vector!float transform(Vector!float v, mat4 m) @safe nothrow pure 329 { 330 Vector!float result = vec!(float)(0.0f, 0.0f); 331 332 for (size_t i = 0; i < 2; ++i) 333 { 334 float sum = 0.0f; 335 336 for (size_t j = 0; j < 2; ++j) 337 { 338 sum += m[i][j] * v[j]; 339 } 340 341 result[i] = sum; 342 } 343 344 return result; 345 }