1 module aurorafw.math.matrix; 2 3 /**************************************************************************** 4 ** ┌─┐┬ ┬┬─┐┌─┐┬─┐┌─┐ ┌─┐┬─┐┌─┐┌┬┐┌─┐┬ ┬┌─┐┬─┐┬┌─ 5 ** ├─┤│ │├┬┘│ │├┬┘├─┤ ├┤ ├┬┘├─┤│││├┤ ││││ │├┬┘├┴┐ 6 ** ┴ ┴└─┘┴└─└─┘┴└─┴ ┴ └ ┴└─┴ ┴┴ ┴└─┘└┴┘└─┘┴└─┴ ┴ 7 ** A Powerful General Purpose Framework 8 ** More information in: https://aurora-fw.github.io/ 9 ** 10 ** Copyright (C) 2018 Aurora Framework, All rights reserved. 11 ** 12 ** This file is part of the Aurora Framework. This framework is free 13 ** software; you can redistribute it and/or modify it under the terms of 14 ** the GNU Lesser General Public License version 3 as published by the 15 ** Free Software Foundation and appearing in the file LICENSE included in 16 ** the packaging of this file. Please review the following information to 17 ** ensure the GNU Lesser General Public License version 3 requirements 18 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. 19 ****************************************************************************/ 20 21 /** @file aurorafw/math/matrix.d 22 * Variable Matrix file. This contains a variable matrix struct that 23 * represents a grid with size of M * N. 24 * @author Luís Ferreira <contact@lsferreira.net> 25 * @since snapshot20180509 26 */ 27 28 /** A struct that represents a variable matrix. A struct that store's 29 * N*M array, allows to manipulate it. 30 * @since snapshot20190930 31 */ 32 @nogc pure @safe struct mat(T, size_t M, size_t N) { 33 this(T num) 34 in { 35 static assert(M == N, "invalid diagonal matrix"); 36 } 37 body { 38 foreach(size_t i; 0..M) 39 matrix[i * M + i] = num; 40 } 41 42 this(immutable ref mat!(T, M, N) mat) 43 { 44 this = mat; 45 } 46 47 this(T[M*N] arr) 48 { 49 matrix[] = arr; 50 } 51 52 this(T[] arr) 53 in { 54 assert(arr.length == M * N, "array doesn't have the same size"); 55 } 56 body { 57 matrix = arr; 58 } 59 60 pragma(inline) static mat!(T, M, N) zero() 61 { 62 mat!(T, M, N) ret; 63 ret.matrix[0..N*M] = 0; 64 return ret; 65 } 66 67 pragma(inline) static mat!(T, M, N) identity() 68 { 69 mat!(T, M, N) ret; 70 ret.setIdentity(); 71 return ret; 72 } 73 74 void setIdentity() @property 75 { 76 foreach(size_t x; 0 .. M) 77 foreach(size_t y; 0 .. N) 78 if (y == x) 79 matrix[x * M + y] = 1; 80 else 81 matrix[x * M + y] = 0; 82 } 83 84 bool opEquals(mat!(T, M, N) mat) const 85 { 86 return matrix == mat.matrix; 87 } 88 89 T opIndex(in size_t m, in size_t n) const 90 in 91 { 92 assert (n < N && m < M, "index out of bounds"); 93 } 94 body 95 { 96 return matrix[m * M + n]; 97 } 98 99 T opIndex(in size_t i) const 100 in 101 { 102 assert (i < N * M, "index out of bounds"); 103 } 104 body 105 { 106 return matrix[i]; 107 } 108 109 T opIndexAssign(in T val, in size_t m, in size_t n) 110 in 111 { 112 assert (n < N && m < M, "index out of bounds"); 113 } 114 body 115 { 116 return (matrix[m * M + n] = val); 117 } 118 119 T[] opSliceAssign(in T val, in size_t i1, in size_t i2) 120 in 121 { 122 assert (i1 < N * M && i2 < N * M, "index out of bounds"); 123 } 124 body 125 { 126 return (matrix[i1..i2] = val); 127 } 128 129 T[] opSliceAssign(in T val) 130 { 131 return (matrix[] = val); 132 } 133 134 T[M*N] matrix; 135 } 136 137 alias mat!(float, 2, 2) Matrix2x2f, Matrix2f; 138 alias mat!(float, 3, 3) Matrix3x3f, Matrix3f; 139 alias mat!(float, 4, 4) Matrix4x4f, Matrix4f; 140 alias mat!(double, 2, 2) Matrix2x2d, Matrix2d; 141 alias mat!(double, 3, 3) Matrix3x3d, Matrix3d; 142 alias mat!(double, 4, 4) Matrix4x4d, Matrix4d; 143 144 alias Matrix2x2f mat2; 145 alias Matrix3x3f mat3; 146 alias Matrix4x4f mat4;