1 module prova.math.vector4; 2 3 import prova.math; 4 import std.math; 5 6 /// 7 struct Vector4 8 { 9 /// 10 float x = 0; 11 /// 12 float y = 0; 13 /// 14 float z = 0; 15 /// 16 float w = 0; 17 18 /// 19 this(float x, float y, float z, float w) 20 { 21 set(x, y, z, w); 22 } 23 24 /// 25 this(Vector3 vector) 26 { 27 set(vector.x, vector.y, vector.z, 0); 28 } 29 30 /// 31 this(Vector2 vector) 32 { 33 set(vector.x, vector.y, 0, 0); 34 } 35 36 /// Sets the values of x, y, z, and w in a single statement 37 void set(float x, float y, float z, float w) 38 { 39 this.x = x; 40 this.y = y; 41 this.z = z; 42 this.w = w; 43 } 44 45 /// Creates a normalized vector with a random direction 46 static Vector4 random() 47 { 48 Vector4 vector = Vector4( 49 randomF(-1, 1), 50 randomF(-1, 1), 51 randomF(-1, 1), 52 randomF(-1, 1) 53 ); 54 55 vector.normalize(); 56 57 return vector; 58 } 59 60 /// 61 @property Vector2 xy() const 62 { 63 return Vector2(x, y); 64 } 65 66 /// 67 @property Vector3 xyz() const 68 { 69 return Vector3(x, y, z); 70 } 71 72 /// Returns a normalized copy of this vector 73 Vector4 getNormalized() const 74 { 75 const float magnitude = getMagnitude(); 76 77 Vector4 result; 78 79 if(magnitude != 0) { 80 result.x = x / magnitude; 81 result.y = y / magnitude; 82 result.z = z / magnitude; 83 result.w = w / magnitude; 84 } 85 86 return result; 87 } 88 89 /// Normalizes the vector 90 void normalize() 91 { 92 const float magnitude = getMagnitude(); 93 94 if(magnitude == 0) 95 return; 96 97 x = x / magnitude; 98 y = y / magnitude; 99 z = z / magnitude; 100 w = w / magnitude; 101 } 102 103 /// Returns the magnitude of the vector 104 float getMagnitude() const 105 { 106 return sqrt(x * x + y * y + z * z + w * w); 107 } 108 109 /** 110 * Sets the magnitude of this vector 111 * 112 * If the previous magnitude is zero, the x value 113 * of the vector will be set to the magnitude 114 */ 115 void setMagnitude(float magnitude) 116 { 117 if(getMagnitude() == 0) { 118 x = magnitude; 119 return; 120 } 121 122 normalize(); 123 124 x *= magnitude; 125 y *= magnitude; 126 z *= magnitude; 127 w *= magnitude; 128 } 129 130 /// Returns the distance between the vectors 131 float distanceTo(Vector4 vector) const 132 { 133 const float a = vector.x - x; 134 const float b = vector.y - y; 135 const float c = vector.z - z; 136 const float d = vector.w - w; 137 138 return sqrt(a * a + b * b + c * c + d * d); 139 } 140 141 /// Returns the squared distance between the vectors 142 float distanceToSquared(Vector4 vector) const 143 { 144 const float a = vector.x - x; 145 const float b = vector.y - y; 146 const float c = vector.z - z; 147 const float d = vector.w - w; 148 149 return a * a + b * b + c * c + d * d; 150 } 151 152 /// Returns the dot product of the two vectors 153 float dot(Vector4 vector) const 154 { 155 return x * vector.x + y * vector.y + z * vector.z + w * vector.w; 156 } 157 158 159 // assignment overloading 160 /// 161 Vector4 opAddAssign(Vector4 vector) 162 { 163 x += vector.x; 164 y += vector.y; 165 z += vector.z; 166 w += vector.w; 167 168 return this; 169 } 170 171 /// 172 Vector4 opSubAssign(Vector4 vector) 173 { 174 x -= vector.x; 175 y -= vector.y; 176 z -= vector.z; 177 w -= vector.w; 178 179 return this; 180 } 181 182 /// 183 Vector4 opMulAssign(Vector4 vector) 184 { 185 x *= vector.x; 186 y *= vector.y; 187 z *= vector.z; 188 w *= vector.w; 189 190 return this; 191 } 192 193 /// 194 Vector4 opMulAssign(float a) 195 { 196 x *= a; 197 y *= a; 198 z *= a; 199 w *= a; 200 201 return this; 202 } 203 204 /// 205 Vector3 opDiv(Vector3 vector) 206 { 207 Vector3 result; 208 result.x = x * vector.x; 209 result.y = y * vector.y; 210 result.z = z * vector.z; 211 212 return result; 213 } 214 215 /// 216 Vector4 opDivAssign(Vector4 vector) 217 { 218 x /= vector.x; 219 y /= vector.y; 220 z /= vector.z; 221 w /= vector.w; 222 223 return this; 224 } 225 226 /// 227 Vector4 opDivAssign(float a) 228 { 229 x /= a; 230 y /= a; 231 z /= a; 232 w /= a; 233 234 return this; 235 } 236 237 238 // arithmetic overloading 239 /// 240 Vector4 opAdd(Vector4 vector) const 241 { 242 Vector4 result; 243 result.x = x + vector.x; 244 result.y = y + vector.y; 245 result.z = z + vector.z; 246 result.w = w + vector.w; 247 248 return result; 249 } 250 251 /// 252 Vector4 opSub(Vector4 vector) const 253 { 254 Vector4 result; 255 result.x = x - vector.x; 256 result.y = y - vector.y; 257 result.z = z - vector.z; 258 result.w = w - vector.w; 259 260 return result; 261 } 262 263 /// 264 Vector4 opUnary(string s)() const if (s == "-") 265 { 266 Vector4 result; 267 result.x = -x; 268 result.y = -y; 269 result.z = -z; 270 result.w = -w; 271 272 return result; 273 } 274 275 /// 276 Vector4 opMul(Vector4 vector) const 277 { 278 Vector4 result; 279 result.x = x * vector.x; 280 result.y = y * vector.y; 281 result.z = z * vector.z; 282 result.w = w * vector.w; 283 284 return result; 285 } 286 287 /// 288 Vector4 opMul(float a) const 289 { 290 Vector4 result; 291 result.x = x * a; 292 result.y = y * a; 293 result.z = z * a; 294 result.w = w * a; 295 296 return result; 297 } 298 299 /// 300 Vector4 opDiv(Vector4 vector) 301 { 302 Vector4 result; 303 result.x = x / vector.x; 304 result.y = y / vector.y; 305 result.z = z / vector.z; 306 result.w = w / vector.w; 307 308 return result; 309 } 310 311 /// 312 Vector4 opDiv(float a) const 313 { 314 Vector4 result; 315 result.x = x / a; 316 result.y = y / a; 317 result.z = z / a; 318 result.w = w / a; 319 320 return result; 321 } 322 323 /// 324 void opAssign(Vector2 vector) 325 { 326 x = vector.x; 327 y = vector.y; 328 z = 0; 329 w = 0; 330 } 331 332 /// 333 void opAssign(Vector3 vector) 334 { 335 x = vector.x; 336 y = vector.y; 337 z = vector.z; 338 w = 0; 339 } 340 }