1 module prova.math.vector2; 2 3 import prova.math, 4 std.math; 5 6 /// 7 struct Vector2 8 { 9 /// 10 float x = 0; 11 /// 12 float y = 0; 13 14 /// 15 this(float x, float y) 16 { 17 set(x, y); 18 } 19 20 /// Sets the values of x and y in a single statement 21 void set(float x, float y) 22 { 23 this.x = x; 24 this.y = y; 25 } 26 27 /// Creates a normalized vector with a random direction 28 static Vector2 random() 29 { 30 Vector2 vector = Vector2( 31 randomF(1), 32 randomF(1) 33 ); 34 35 vector.normalize(); 36 37 return vector; 38 } 39 40 /// Returns a normalized copy of this vector 41 Vector2 getNormalized() const 42 { 43 const float magnitude = getMagnitude(); 44 45 Vector2 result; 46 47 if(magnitude != 0) { 48 result.x = x / magnitude; 49 result.y = y / magnitude; 50 } 51 52 return result; 53 } 54 55 /// Normalizes the vector 56 void normalize() 57 { 58 const float magnitude = getMagnitude(); 59 60 if(magnitude == 0) 61 return; 62 63 x = x / magnitude; 64 y = y / magnitude; 65 } 66 67 /// Returns the magnitude of the vector 68 float getMagnitude() const 69 { 70 return sqrt(x * x + y * y); 71 } 72 73 /** 74 * Sets the magnitude of this vector 75 * 76 * If the previous magnitude is zero, the x value 77 * of the vector will be set to the magnitude 78 */ 79 void setMagnitude(float magnitude) 80 { 81 if(getMagnitude() == 0) { 82 x = magnitude; 83 return; 84 } 85 86 normalize(); 87 88 x *= magnitude; 89 y *= magnitude; 90 } 91 92 /// Returns the direction of the vector in degrees 93 float getDirection() const 94 { 95 return atan2(y, x) / PI * 180; 96 } 97 98 /** 99 * Sets the direction of the vector using degrees 100 * 101 * Make sure the magnitude is not zero or this will not work 102 */ 103 void setDirection(float angle) 104 { 105 const float magnitude = this.getMagnitude(); 106 angle *= PI / 180; 107 108 y = sin(angle) * magnitude; 109 x = cos(angle) * magnitude; 110 } 111 112 /// Returns the angle to the vector in degrees 113 float angleTo(Vector2 vector) const 114 { 115 return atan2(vector.y - y, vector.x - x) / PI * 180; 116 } 117 118 /// Returns the distance between the vectors 119 float distanceTo(Vector2 vector) const 120 { 121 const float a = vector.x - x; 122 const float b = vector.y - y; 123 124 return sqrt(a * a + b * b); 125 } 126 127 /// Returns the squared distance between the vectors 128 float distanceToSquared(Vector2 vector) const 129 { 130 const float a = vector.x - x; 131 const float b = vector.y - y; 132 133 return a * a + b * b; 134 } 135 136 /// Returns the dot product of the two vectors 137 float dot(Vector2 vector) 138 { 139 return x * vector.x + y * vector.y; 140 } 141 142 143 // assignment overloading 144 Vector2 opAddAssign(Vector2 vector) 145 { 146 x += vector.x; 147 y += vector.y; 148 149 return this; 150 } 151 152 Vector2 opSubAssign(Vector2 vector) 153 { 154 x -= vector.x; 155 y -= vector.y; 156 157 return this; 158 } 159 160 Vector2 opMulAssign(Vector2 vector) 161 { 162 x *= vector.x; 163 y *= vector.y; 164 165 return this; 166 } 167 168 Vector2 opMulAssign(float a) 169 { 170 x *= a; 171 y *= a; 172 173 return this; 174 } 175 176 Vector2 opDivAssign(float a) 177 { 178 x /= a; 179 y /= a; 180 181 return this; 182 } 183 184 185 // arithmetic overloading 186 Vector2 opAdd(Vector2 vector) const 187 { 188 Vector2 result; 189 result.x = x + vector.x; 190 result.y = y + vector.y; 191 192 return result; 193 } 194 195 Vector3 opAdd(Vector3 vector) const 196 { 197 Vector3 result; 198 result.x = x + vector.x; 199 result.y = y + vector.y; 200 result.z = vector.z; 201 202 return vector; 203 } 204 205 Vector2 opSub(Vector2 vector) const 206 { 207 Vector2 result; 208 result.x = x - vector.x; 209 result.y = y - vector.y; 210 211 return result; 212 } 213 214 Vector3 opSub(Vector3 vector) const 215 { 216 Vector3 result; 217 result.x = x - vector.x; 218 result.y = y - vector.y; 219 result.z = vector.z; 220 221 return result; 222 } 223 224 Vector2 opUnary(string s)() const if (s == "-") 225 { 226 Vector2 result; 227 result.x = -x; 228 result.y = -y; 229 230 return result; 231 } 232 233 Vector2 opMul(Vector2 vector) const 234 { 235 Vector2 result; 236 result.x = x * vector.x; 237 result.y = y * vector.y; 238 239 return result; 240 } 241 242 Vector2 opMul(float a) const 243 { 244 Vector2 result; 245 result.x = x * a; 246 result.y = y * a; 247 248 return result; 249 } 250 251 Vector2 opDiv(float a) const 252 { 253 Vector2 result; 254 result.x = x / a; 255 result.y = y / a; 256 257 return result; 258 } 259 }