1 | /** |
2 | * Copyright (c) 2006-2023 LOVE Development Team |
3 | * |
4 | * This software is provided 'as-is', without any express or implied |
5 | * warranty. In no event will the authors be held liable for any damages |
6 | * arising from the use of this software. |
7 | * |
8 | * Permission is granted to anyone to use this software for any purpose, |
9 | * including commercial applications, and to alter it and redistribute it |
10 | * freely, subject to the following restrictions: |
11 | * |
12 | * 1. The origin of this software must not be misrepresented; you must not |
13 | * claim that you wrote the original software. If you use this software |
14 | * in a product, an acknowledgment in the product documentation would be |
15 | * appreciated but is not required. |
16 | * 2. Altered source versions must be plainly marked as such, and must not be |
17 | * misrepresented as being the original software. |
18 | * 3. This notice may not be removed or altered from any source distribution. |
19 | **/ |
20 | |
21 | #ifndef LOVE_VECTOR_H |
22 | #define LOVE_VECTOR_H |
23 | |
24 | // STD |
25 | #include <cmath> |
26 | |
27 | namespace love |
28 | { |
29 | |
30 | // All math operators are component-wise. |
31 | struct Vector2 |
32 | { |
33 | float x, y; |
34 | |
35 | Vector2() |
36 | : x(0.0f), y(0.0f) |
37 | {} |
38 | |
39 | Vector2(float x, float y) |
40 | : x(x), y(y) |
41 | {} |
42 | |
43 | Vector2(const Vector2 &v) |
44 | : x(v.x), y(v.y) |
45 | {} |
46 | |
47 | float getLength() const; |
48 | float getLengthSquare() const; |
49 | |
50 | /** |
51 | * Normalizes the Vector. |
52 | * @param length Desired length of the vector. |
53 | **/ |
54 | void normalize(float length = 1.0f); |
55 | |
56 | /** |
57 | * Gets a vector perpendicular to the Vector. |
58 | * To get the true (normalized) normal, use v.getNormal(1.0f / v.getLength()) |
59 | **/ |
60 | Vector2 getNormal() const; |
61 | |
62 | /** |
63 | * Gets a vector perpendicular to the Vector. |
64 | * To get the true (normalized) normal, use v.getNormal(1.0f / v.getLength()) |
65 | **/ |
66 | Vector2 getNormal(float scale) const; |
67 | |
68 | static inline float dot(const Vector2 &a, const Vector2 &b); |
69 | static inline float cross(const Vector2 &a, const Vector2 &b); |
70 | |
71 | Vector2 operator + (const Vector2 &v) const; |
72 | Vector2 operator - (const Vector2 &v) const; |
73 | |
74 | Vector2 operator * (float s) const; |
75 | Vector2 operator / (float s) const; |
76 | |
77 | Vector2 operator - () const; |
78 | |
79 | void operator += (const Vector2 &v); |
80 | void operator -= (const Vector2 &v); |
81 | |
82 | void operator *= (float s); |
83 | void operator /= (float s); |
84 | |
85 | bool operator == (const Vector2 &v) const; |
86 | bool operator != (const Vector2 &v) const; |
87 | |
88 | }; // Vector2 |
89 | |
90 | |
91 | // All math operators are component-wise. |
92 | struct Vector3 |
93 | { |
94 | float x, y, z; |
95 | |
96 | Vector3() |
97 | : x(0.0f), y(0.0f), z(0.0f) |
98 | {} |
99 | |
100 | Vector3(float x, float y, float z) |
101 | : x(x), y(y), z(z) |
102 | {} |
103 | |
104 | Vector3(const Vector2 &v, float z = 0.0f) |
105 | : x(v.x), y(v.y), z(z) |
106 | {} |
107 | |
108 | float getLength() const; |
109 | float getLengthSquare() const; |
110 | |
111 | /** |
112 | * Normalizes the Vector. |
113 | * @param length Desired length of the vector. |
114 | **/ |
115 | void normalize(float length = 1.0); |
116 | |
117 | static inline float dot(const Vector3 &a, const Vector3 &b); |
118 | static inline Vector3 cross(const Vector3 &a, const Vector3 &b); |
119 | |
120 | Vector3 operator + (const Vector3 &v) const; |
121 | Vector3 operator - (const Vector3 &v) const; |
122 | |
123 | Vector3 operator * (float s) const; |
124 | Vector3 operator / (float s) const; |
125 | |
126 | Vector3 operator - () const; |
127 | |
128 | void operator += (const Vector3 &v); |
129 | void operator -= (const Vector3 &v); |
130 | |
131 | void operator *= (float s); |
132 | void operator /= (float s); |
133 | |
134 | bool operator == (const Vector3 &v) const; |
135 | bool operator != (const Vector3 &v) const; |
136 | |
137 | }; // Vector3 |
138 | |
139 | |
140 | // All math operators are component-wise. |
141 | struct Vector4 |
142 | { |
143 | float x, y, z, w; |
144 | |
145 | Vector4() |
146 | : x(0.0f), y(0.0f), z(0.0f), w(0.0f) |
147 | {} |
148 | |
149 | Vector4(float x, float y, float z, float w) |
150 | : x(x), y(y), z(z), w(w) |
151 | {} |
152 | |
153 | Vector4(const Vector2 &v, float z = 0.0f, float w = 0.0f) |
154 | : x(v.x), y(v.y), z(z), w(w) |
155 | {} |
156 | |
157 | Vector4(const Vector3 &v, float w = 0.0f) |
158 | : x(v.x), y(v.y), z(v.z), w(w) |
159 | {} |
160 | |
161 | float getLength() const; |
162 | float getLengthSquare() const; |
163 | |
164 | /** |
165 | * Normalizes the Vector. |
166 | * @param length Desired length of the vector. |
167 | **/ |
168 | void normalize(float length = 1.0); |
169 | |
170 | static inline float dot(const Vector4 &a, const Vector4 &b); |
171 | |
172 | Vector4 operator + (const Vector4 &v) const; |
173 | Vector4 operator - (const Vector4 &v) const; |
174 | |
175 | Vector4 operator * (float s) const; |
176 | Vector4 operator / (float s) const; |
177 | |
178 | Vector4 operator - () const; |
179 | |
180 | void operator += (const Vector4 &v); |
181 | void operator -= (const Vector4 &v); |
182 | |
183 | void operator *= (float s); |
184 | void operator /= (float s); |
185 | |
186 | bool operator == (const Vector4 &v) const; |
187 | bool operator != (const Vector4 &v) const; |
188 | |
189 | }; // Vector4 |
190 | |
191 | |
192 | inline float Vector2::getLength() const |
193 | { |
194 | return sqrtf(x*x + y*y); |
195 | } |
196 | |
197 | inline float Vector2::getLengthSquare() const |
198 | { |
199 | return x*x + y*y; |
200 | } |
201 | |
202 | inline Vector2 Vector2::getNormal() const |
203 | { |
204 | return Vector2(-y, x); |
205 | } |
206 | |
207 | inline Vector2 Vector2::getNormal(float scale) const |
208 | { |
209 | return Vector2(-y * scale, x * scale); |
210 | } |
211 | |
212 | inline float Vector2::dot(const Vector2 &a, const Vector2 &b) |
213 | { |
214 | return a.x * b.x + a.y * b.y; |
215 | } |
216 | |
217 | inline float Vector2::cross(const Vector2 &a, const Vector2 &b) |
218 | { |
219 | return a.x * b.y - a.y * b.x; |
220 | } |
221 | |
222 | inline void Vector2::normalize(float length) |
223 | { |
224 | float length_current = getLength(); |
225 | if (length_current > 0) |
226 | { |
227 | float m = length / length_current; |
228 | x *= m; |
229 | y *= m; |
230 | } |
231 | } |
232 | |
233 | inline Vector2 Vector2::operator + (const Vector2 &v) const |
234 | { |
235 | return Vector2(x + v.x, y + v.y); |
236 | } |
237 | |
238 | inline Vector2 Vector2::operator - (const Vector2 &v) const |
239 | { |
240 | return Vector2(x - v.x, y - v.y); |
241 | } |
242 | |
243 | inline Vector2 Vector2::operator * (float s) const |
244 | { |
245 | return Vector2(x*s, y*s); |
246 | } |
247 | |
248 | inline Vector2 Vector2::operator / (float s) const |
249 | { |
250 | float invs = 1.0f / s; |
251 | return Vector2(x*invs, y*invs); |
252 | } |
253 | |
254 | inline Vector2 Vector2::operator - () const |
255 | { |
256 | return Vector2(-x, -y); |
257 | } |
258 | |
259 | inline void Vector2::operator += (const Vector2 &v) |
260 | { |
261 | x += v.x; |
262 | y += v.y; |
263 | } |
264 | |
265 | inline void Vector2::operator -= (const Vector2 &v) |
266 | { |
267 | x -= v.x; |
268 | y -= v.y; |
269 | } |
270 | |
271 | inline void Vector2::operator *= (float s) |
272 | { |
273 | x *= s; |
274 | y *= s; |
275 | } |
276 | |
277 | inline void Vector2::operator /= (float s) |
278 | { |
279 | float invs = 1.0f / s; |
280 | x *= invs; |
281 | y *= invs; |
282 | } |
283 | |
284 | inline bool Vector2::operator == (const Vector2 &v) const |
285 | { |
286 | return x == v.x && y == v.y; |
287 | } |
288 | |
289 | inline bool Vector2::operator != (const Vector2 &v) const |
290 | { |
291 | return x != v.x || y != v.y; |
292 | } |
293 | |
294 | |
295 | inline float Vector3::getLength() const |
296 | { |
297 | return sqrtf(x*x + y*y + z*z); |
298 | } |
299 | |
300 | inline float Vector3::getLengthSquare() const |
301 | { |
302 | return x*x + y*y + z*z; |
303 | } |
304 | |
305 | inline float Vector3::dot(const Vector3 &a, const Vector3 &b) |
306 | { |
307 | return a.x * b.x + a.y * b.y + a.z * b.z; |
308 | } |
309 | |
310 | inline Vector3 Vector3::cross(const Vector3 &a, const Vector3 &b) |
311 | { |
312 | return Vector3(a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x); |
313 | } |
314 | |
315 | inline void Vector3::normalize(float length) |
316 | { |
317 | float length_current = getLength(); |
318 | if (length_current > 0) |
319 | { |
320 | float m = length / length_current; |
321 | x *= m; |
322 | y *= m; |
323 | z *= m; |
324 | } |
325 | } |
326 | |
327 | inline Vector3 Vector3::operator + (const Vector3 &v) const |
328 | { |
329 | return Vector3(x + v.x, y + v.y, z + v.z); |
330 | } |
331 | |
332 | inline Vector3 Vector3::operator - (const Vector3 &v) const |
333 | { |
334 | return Vector3(x - v.x, y - v.y, z - v.z); |
335 | } |
336 | |
337 | inline Vector3 Vector3::operator * (float s) const |
338 | { |
339 | return Vector3(x*s, y*s, z*s); |
340 | } |
341 | |
342 | inline Vector3 Vector3::operator / (float s) const |
343 | { |
344 | float invs = 1.0f / s; |
345 | return Vector3(x*invs, y*invs, z*invs); |
346 | } |
347 | |
348 | inline Vector3 Vector3::operator - () const |
349 | { |
350 | return Vector3(-x, -y, -z); |
351 | } |
352 | |
353 | inline void Vector3::operator += (const Vector3 &v) |
354 | { |
355 | x += v.x; |
356 | y += v.y; |
357 | z += v.z; |
358 | } |
359 | |
360 | inline void Vector3::operator -= (const Vector3 &v) |
361 | { |
362 | x -= v.x; |
363 | y -= v.y; |
364 | z -= v.z; |
365 | } |
366 | |
367 | inline void Vector3::operator *= (float s) |
368 | { |
369 | x *= s; |
370 | y *= s; |
371 | z *= s; |
372 | } |
373 | |
374 | inline void Vector3::operator /= (float s) |
375 | { |
376 | float invs = 1.0f / s; |
377 | x *= invs; |
378 | y *= invs; |
379 | z *= invs; |
380 | } |
381 | |
382 | inline bool Vector3::operator == (const Vector3 &v) const |
383 | { |
384 | return x == v.x && y == v.y && z == v.z; |
385 | } |
386 | |
387 | inline bool Vector3::operator != (const Vector3 &v) const |
388 | { |
389 | return x != v.x || y != v.y || z != v.z; |
390 | } |
391 | |
392 | |
393 | inline float Vector4::getLength() const |
394 | { |
395 | return sqrtf(x*x + y*y + z*z + w*w); |
396 | } |
397 | |
398 | inline float Vector4::getLengthSquare() const |
399 | { |
400 | return x*x + y*y + z*z + w*w; |
401 | } |
402 | |
403 | inline float Vector4::dot(const Vector4 &a, const Vector4 &b) |
404 | { |
405 | return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; |
406 | } |
407 | |
408 | inline void Vector4::normalize(float length) |
409 | { |
410 | float length_current = getLength(); |
411 | if (length_current > 0) |
412 | { |
413 | float m = length / length_current; |
414 | x *= m; |
415 | y *= m; |
416 | z *= m; |
417 | w *= m; |
418 | } |
419 | } |
420 | |
421 | inline Vector4 Vector4::operator + (const Vector4 &v) const |
422 | { |
423 | return Vector4(x + v.x, y + v.y, z + v.z, w + v.w); |
424 | } |
425 | |
426 | inline Vector4 Vector4::operator - (const Vector4 &v) const |
427 | { |
428 | return Vector4(x - v.x, y - v.y, z - v.z, w - v.w); |
429 | } |
430 | |
431 | inline Vector4 Vector4::operator * (float s) const |
432 | { |
433 | return Vector4(x*s, y*s, z*s, w*s); |
434 | } |
435 | |
436 | inline Vector4 Vector4::operator / (float s) const |
437 | { |
438 | float invs = 1.0f / s; |
439 | return Vector4(x*invs, y*invs, z*invs, w*invs); |
440 | } |
441 | |
442 | inline Vector4 Vector4::operator - () const |
443 | { |
444 | return Vector4(-x, -y, -z, -w); |
445 | } |
446 | |
447 | inline void Vector4::operator += (const Vector4 &v) |
448 | { |
449 | x += v.x; |
450 | y += v.y; |
451 | z += v.z; |
452 | w += v.w; |
453 | } |
454 | |
455 | inline void Vector4::operator -= (const Vector4 &v) |
456 | { |
457 | x -= v.x; |
458 | y -= v.y; |
459 | z -= v.z; |
460 | w -= v.w; |
461 | } |
462 | |
463 | inline void Vector4::operator *= (float s) |
464 | { |
465 | x *= s; |
466 | y *= s; |
467 | z *= s; |
468 | w *= s; |
469 | } |
470 | |
471 | inline void Vector4::operator /= (float s) |
472 | { |
473 | float invs = 1.0f / s; |
474 | x *= invs; |
475 | y *= invs; |
476 | z *= invs; |
477 | w *= invs; |
478 | } |
479 | |
480 | inline bool Vector4::operator == (const Vector4 &v) const |
481 | { |
482 | return x == v.x && y == v.y && z == v.z && w == v.w; |
483 | } |
484 | |
485 | inline bool Vector4::operator != (const Vector4 &v) const |
486 | { |
487 | return x != v.x || y != v.y || z != v.z || w != v.w; |
488 | } |
489 | |
490 | } //love |
491 | |
492 | #endif// LOVE_VECTOR_H |
493 | |