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(float a) 161 { 162 x *= a; 163 y *= a; 164 165 return this; 166 } 167 168 Vector2 opDivAssign(float a) 169 { 170 x /= a; 171 y /= a; 172 173 return this; 174 } 175 176 177 // arithmetic overloading 178 Vector2 opAdd(Vector2 vector) const 179 { 180 Vector2 result; 181 result.x = x + vector.x; 182 result.y = y + vector.y; 183 184 return result; 185 } 186 187 Vector3 opAdd(Vector3 vector) const 188 { 189 Vector3 result; 190 result.x = x + vector.x; 191 result.y = y + vector.y; 192 result.z = vector.z; 193 194 return vector; 195 } 196 197 Vector2 opSub(Vector2 vector) const 198 { 199 Vector2 result; 200 result.x = x - vector.x; 201 result.y = y - vector.y; 202 203 return result; 204 } 205 206 Vector3 opSub(Vector3 vector) const 207 { 208 Vector3 result; 209 result.x = x - vector.x; 210 result.y = y - vector.y; 211 result.z = vector.z; 212 213 return result; 214 } 215 216 Vector2 opUnary(string s)() const if (s == "-") 217 { 218 Vector2 result; 219 result.x = -x; 220 result.y = -y; 221 222 return result; 223 } 224 225 Vector2 opMul(float a) const 226 { 227 Vector2 result; 228 result.x = x * a; 229 result.y = y * a; 230 231 return result; 232 } 233 234 Vector2 opDiv(float a) const 235 { 236 Vector2 result; 237 result.x = x / a; 238 result.y = y / a; 239 240 return result; 241 } 242 }