1 module viva.math.vector; 2 3 // Based on https://github.com/CosmoMyst/CosmoMyst.Math/blob/master/source/cosmomyst/math/vector.d 4 // thanks code :) 5 6 alias Vector1 = Vector!1; 7 alias Vector2 = Vector!2; 8 alias Vector3 = Vector!3; 9 alias Vector4 = Vector!4; 10 11 /++ 12 + 13 +/ 14 struct Vector(ulong n) 15 if (n >= 1) 16 { 17 union 18 { 19 /// 20 float[n] v; 21 22 struct 23 { 24 static if (n >= 1) 25 { 26 /// 27 float x; 28 } 29 30 static if (n >= 2) 31 { 32 /// 33 float y; 34 } 35 36 static if (n >= 3) 37 { 38 /// 39 float z; 40 } 41 42 static if (n >= 4) 43 { 44 /// 45 float w; 46 } 47 } 48 } 49 50 /++ 51 + 52 +/ 53 this(T...)(T values) pure nothrow @nogc 54 { 55 import viva.types.number : isNumber; 56 57 static foreach (value; values) 58 { 59 static assert(isNumber!(typeof(value)), "all values must be numeric"); 60 } 61 62 static assert(values.length > 0, "no values provided"); 63 static assert(values.length == 1 || values.length == n, "number of values must be either 1 or number of components"); 64 65 static if (values.length == 1) 66 { 67 static foreach (i; 0..n) 68 { 69 v[i] = values[0]; 70 } 71 } 72 else 73 { 74 static foreach (i, value; values) 75 { 76 v[i] = value; 77 } 78 } 79 } 80 81 /++ 82 + 83 +/ 84 auto ptr() pure const nothrow @nogc 85 { 86 return v.ptr; 87 } 88 89 /++ 90 + 91 +/ 92 float length() pure const nothrow @nogc 93 { 94 import std.math : sqrt; 95 96 float sum = 0; 97 for (int i = 0; i < n; i++) 98 { 99 sum += v[i] * v[i]; 100 } 101 102 return sqrt(sum); 103 } 104 105 /++ 106 + 107 +/ 108 void normalize() pure nothrow @nogc 109 { 110 this = normalized(); 111 } 112 113 /++ 114 + 115 +/ 116 Vector!n normalized() pure const nothrow @nogc 117 { 118 if (length() == 0) 119 { 120 return Vector!n(0f); 121 } 122 123 return this / length(); 124 } 125 126 /++ 127 + 128 +/ 129 Vector!n opBinary(string op)(in float scalar) @nogc 130 const if (op == "/") 131 { 132 Vector!n res; 133 134 for (int i = 0; i < n; i++) 135 { 136 res.v[i] = v[i] / scalar; 137 } 138 139 return res; 140 } 141 142 /++ 143 + 144 +/ 145 void opOpAssign(string op)(in float scalar) @nogc 146 const if (s == "/") 147 { 148 auto res = this / scalar; 149 this.v = res.v; 150 } 151 }