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
27namespace love
28{
29
30// All math operators are component-wise.
31struct 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.
92struct 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.
141struct 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
192inline float Vector2::getLength() const
193{
194 return sqrtf(x*x + y*y);
195}
196
197inline float Vector2::getLengthSquare() const
198{
199 return x*x + y*y;
200}
201
202inline Vector2 Vector2::getNormal() const
203{
204 return Vector2(-y, x);
205}
206
207inline Vector2 Vector2::getNormal(float scale) const
208{
209 return Vector2(-y * scale, x * scale);
210}
211
212inline float Vector2::dot(const Vector2 &a, const Vector2 &b)
213{
214 return a.x * b.x + a.y * b.y;
215}
216
217inline float Vector2::cross(const Vector2 &a, const Vector2 &b)
218{
219 return a.x * b.y - a.y * b.x;
220}
221
222inline 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
233inline Vector2 Vector2::operator + (const Vector2 &v) const
234{
235 return Vector2(x + v.x, y + v.y);
236}
237
238inline Vector2 Vector2::operator - (const Vector2 &v) const
239{
240 return Vector2(x - v.x, y - v.y);
241}
242
243inline Vector2 Vector2::operator * (float s) const
244{
245 return Vector2(x*s, y*s);
246}
247
248inline Vector2 Vector2::operator / (float s) const
249{
250 float invs = 1.0f / s;
251 return Vector2(x*invs, y*invs);
252}
253
254inline Vector2 Vector2::operator - () const
255{
256 return Vector2(-x, -y);
257}
258
259inline void Vector2::operator += (const Vector2 &v)
260{
261 x += v.x;
262 y += v.y;
263}
264
265inline void Vector2::operator -= (const Vector2 &v)
266{
267 x -= v.x;
268 y -= v.y;
269}
270
271inline void Vector2::operator *= (float s)
272{
273 x *= s;
274 y *= s;
275}
276
277inline void Vector2::operator /= (float s)
278{
279 float invs = 1.0f / s;
280 x *= invs;
281 y *= invs;
282}
283
284inline bool Vector2::operator == (const Vector2 &v) const
285{
286 return x == v.x && y == v.y;
287}
288
289inline bool Vector2::operator != (const Vector2 &v) const
290{
291 return x != v.x || y != v.y;
292}
293
294
295inline float Vector3::getLength() const
296{
297 return sqrtf(x*x + y*y + z*z);
298}
299
300inline float Vector3::getLengthSquare() const
301{
302 return x*x + y*y + z*z;
303}
304
305inline 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
310inline 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
315inline 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
327inline Vector3 Vector3::operator + (const Vector3 &v) const
328{
329 return Vector3(x + v.x, y + v.y, z + v.z);
330}
331
332inline Vector3 Vector3::operator - (const Vector3 &v) const
333{
334 return Vector3(x - v.x, y - v.y, z - v.z);
335}
336
337inline Vector3 Vector3::operator * (float s) const
338{
339 return Vector3(x*s, y*s, z*s);
340}
341
342inline Vector3 Vector3::operator / (float s) const
343{
344 float invs = 1.0f / s;
345 return Vector3(x*invs, y*invs, z*invs);
346}
347
348inline Vector3 Vector3::operator - () const
349{
350 return Vector3(-x, -y, -z);
351}
352
353inline void Vector3::operator += (const Vector3 &v)
354{
355 x += v.x;
356 y += v.y;
357 z += v.z;
358}
359
360inline void Vector3::operator -= (const Vector3 &v)
361{
362 x -= v.x;
363 y -= v.y;
364 z -= v.z;
365}
366
367inline void Vector3::operator *= (float s)
368{
369 x *= s;
370 y *= s;
371 z *= s;
372}
373
374inline void Vector3::operator /= (float s)
375{
376 float invs = 1.0f / s;
377 x *= invs;
378 y *= invs;
379 z *= invs;
380}
381
382inline bool Vector3::operator == (const Vector3 &v) const
383{
384 return x == v.x && y == v.y && z == v.z;
385}
386
387inline bool Vector3::operator != (const Vector3 &v) const
388{
389 return x != v.x || y != v.y || z != v.z;
390}
391
392
393inline float Vector4::getLength() const
394{
395 return sqrtf(x*x + y*y + z*z + w*w);
396}
397
398inline float Vector4::getLengthSquare() const
399{
400 return x*x + y*y + z*z + w*w;
401}
402
403inline 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
408inline 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
421inline 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
426inline 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
431inline Vector4 Vector4::operator * (float s) const
432{
433 return Vector4(x*s, y*s, z*s, w*s);
434}
435
436inline 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
442inline Vector4 Vector4::operator - () const
443{
444 return Vector4(-x, -y, -z, -w);
445}
446
447inline 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
455inline 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
463inline void Vector4::operator *= (float s)
464{
465 x *= s;
466 y *= s;
467 z *= s;
468 w *= s;
469}
470
471inline 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
480inline bool Vector4::operator == (const Vector4 &v) const
481{
482 return x == v.x && y == v.y && z == v.z && w == v.w;
483}
484
485inline 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