Line data Source code
1 : /**
2 : * @file
3 : * @brief Definition of Vec2f and Vec3f.
4 : *
5 : * Vec2fs can be added, subtracted, multiplied (dot product) and normalized.
6 : * It also has an implementation of the following operators:
7 : * "+", "+=", "-", "-=", "*" (vector-vector);
8 : * "*", "*=", "/", "/=" (vector-scalar);
9 : * "==", "!=" (equality);
10 : * "*" (scalar-vector);
11 : * "<<" (printing).
12 : * The same applies for Vec3fs.
13 : */
14 : #pragma once
15 :
16 : #include <AH/Settings/Warnings.hpp>
17 : AH_DIAGNOSTIC_WERROR() // Enable errors on warnings
18 :
19 : #include <AH/Arduino-Wrapper.h> // Print
20 : #include <AH/STL/cmath> // std::sqrt
21 :
22 : #ifndef ARDUINO
23 : #include <iosfwd> // std::ostream
24 : #endif
25 :
26 : BEGIN_AH_NAMESPACE
27 :
28 : /// @addtogroup math-types
29 : /// @{
30 :
31 : /**
32 : * @brief Type for 2D vectors of floating point numbers.
33 : *
34 : * Vec2fs can be added, subtracted, multiplied (dot product) and normalized.
35 : * It also has an implementation of the following operators:
36 : * "+", "+=", "-", "-=", "*" (vector-vector);
37 : * "*", "*=", "/", "/=" (vector-scalar);
38 : * "==", "!=" (equality);
39 : * "*" (scalar-vector);
40 : * "<<" (printing).
41 : */
42 : struct Vec2f {
43 : float x = 0.0; ///< The x component of the vector.
44 : float y = 0.0; ///< The y component of the vector.
45 :
46 : /// Create a vector that is initialized to the zero vector (0,0).
47 : Vec2f() = default;
48 : /// Create a vector with the given x and y coordinates.
49 1000046 : Vec2f(float x, float y) : x(x), y(y) {}
50 :
51 : /// Addition.
52 4 : Vec2f &operator+=(Vec2f rhs) {
53 4 : x += rhs.x;
54 4 : y += rhs.y;
55 4 : return *this;
56 : }
57 : /// Addition.
58 1 : Vec2f operator+(Vec2f rhs) const {
59 1 : Vec2f result = *this;
60 1 : result += rhs;
61 1 : return result;
62 : }
63 :
64 : /// Negation.
65 3 : Vec2f operator-() const { return {-x, -y}; }
66 : /// Subtraction.
67 2 : Vec2f &operator-=(Vec2f rhs) { return *this += -rhs; }
68 : /// Subtraction.
69 1 : Vec2f operator-(Vec2f rhs) const {
70 1 : Vec2f result = *this;
71 1 : result -= rhs;
72 1 : return result;
73 : }
74 :
75 : /// Scalar multiplication.
76 2 : Vec2f &operator*=(float rhs) {
77 2 : x *= rhs;
78 2 : y *= rhs;
79 2 : return *this;
80 : }
81 : /// Scalar multiplication.
82 1 : Vec2f operator*(float rhs) const {
83 1 : Vec2f result = *this;
84 1 : result *= rhs;
85 1 : return result;
86 : }
87 :
88 : /// Scalar division.
89 1000007 : Vec2f &operator/=(float rhs) {
90 1000007 : x /= rhs;
91 1000007 : y /= rhs;
92 1000007 : return *this;
93 : }
94 : /// Scalar division.
95 2 : Vec2f operator/(float rhs) const {
96 2 : Vec2f result = *this;
97 2 : result /= rhs;
98 2 : return result;
99 : }
100 :
101 : /// Inner product.
102 2 : float operator*(Vec2f rhs) const {
103 2 : return this->x * rhs.x + this->y * rhs.y;
104 : }
105 :
106 : /// Norm squared.
107 1 : float normSquared() const { return (*this) * (*this); }
108 : /// Norm.
109 1000006 : float norm() const {
110 : // return std::sqrt(normSquared()); // faster but less accurate
111 1000006 : return std::hypot(x, y);
112 : }
113 : /// Normalize this vector.
114 1 : Vec2f &normalize() { return *this /= norm(); }
115 : /// Normalize a copy of this vector (doesn't change the original vector).
116 1 : Vec2f normalized() const { return *this / norm(); }
117 :
118 : /// Equality check.
119 21 : bool operator==(Vec2f rhs) const {
120 21 : return this->x == rhs.x && this->y == rhs.y;
121 : }
122 : /// Inequality check.
123 2 : bool operator!=(Vec2f rhs) const { return !(*this == rhs); }
124 : };
125 :
126 : /// Scalar multiplication.
127 : /// @related Vec2f
128 1 : inline Vec2f operator*(float lhs, Vec2f rhs) {
129 1 : return {lhs * rhs.x, lhs * rhs.y};
130 : }
131 :
132 : /**
133 : * @brief Type for 3D vectors of floating point numbers.
134 : *
135 : * Vec3fs can be added, subtracted, multiplied (dot product) and normalized.
136 : * It also has an implementation of the following operators:
137 : * "+", "+=", "-", "-=", "*" (vector-vector);
138 : * "*", "*=", "/", "/=" (vector-scalar);
139 : * "==", "!=" (equality);
140 : * "*" (scalar-vector);
141 : * "<<" (printing).
142 : */
143 : struct Vec3f {
144 : float x = 0.0; ///< The x component of the vector.
145 : float y = 0.0; ///< The y component of the vector.
146 : float z = 0.0; ///< The z component of the vector.
147 :
148 : /// Create a vector that is initialized to the zero vector (0,0,0).
149 : Vec3f() = default;
150 : /// Create a vector with the given x, y and z coordinates.
151 4000066 : Vec3f(float x, float y, float z) : x(x), y(y), z(z) {}
152 7000073 : Vec3f(const Vec3f &) = default;
153 : Vec3f(const volatile Vec3f &other) : x(other.x), y(other.y), z(other.z) {}
154 : void operator=(const Vec3f &other) volatile {
155 : this->x = other.x;
156 : this->y = other.y;
157 : this->z = other.z;
158 : }
159 :
160 : /// Addition.
161 1000007 : Vec3f &operator+=(Vec3f rhs) {
162 1000007 : x += rhs.x;
163 1000007 : y += rhs.y;
164 1000007 : z += rhs.z;
165 1000007 : return *this;
166 : }
167 : /// Addition.
168 1 : Vec3f operator+(Vec3f rhs) const {
169 1 : Vec3f result = *this;
170 1 : result += rhs;
171 1 : return result;
172 : }
173 :
174 : /// Negation.
175 1000006 : Vec3f operator-() const { return {-x, -y, -z}; }
176 : /// Subtraction.
177 1000005 : Vec3f &operator-=(Vec3f rhs) { return *this += -rhs; }
178 : /// Subtraction.
179 1000004 : Vec3f operator-(Vec3f rhs) const {
180 1000004 : Vec3f result = *this;
181 1000004 : result -= rhs;
182 1000004 : return result;
183 : }
184 :
185 : /// Scalar multiplication.
186 2 : Vec3f &operator*=(float rhs) {
187 2 : x *= rhs;
188 2 : y *= rhs;
189 2 : z *= rhs;
190 2 : return *this;
191 : }
192 : /// Scalar multiplication.
193 1 : Vec3f operator*(float rhs) const {
194 1 : Vec3f result = *this;
195 1 : result *= rhs;
196 1 : return result;
197 : }
198 :
199 : /// Scalar division.
200 1000008 : Vec3f &operator/=(float rhs) {
201 1000008 : x /= rhs;
202 1000008 : y /= rhs;
203 1000008 : z /= rhs;
204 1000008 : return *this;
205 : }
206 : /// Scalar division.
207 1000005 : Vec3f operator/(float rhs) const {
208 1000005 : Vec3f result = *this;
209 1000005 : result /= rhs;
210 1000005 : return result;
211 : }
212 :
213 : /// Inner product.
214 3000017 : float operator*(Vec3f rhs) const {
215 3000017 : return this->x * rhs.x + this->y * rhs.y + this->z * rhs.z;
216 : }
217 :
218 : /// Norm squared.
219 3000016 : float normSquared() const { return (*this) * (*this); }
220 :
221 : /// Norm.
222 3000015 : float norm() const {
223 3000015 : return std::sqrt(normSquared());
224 : // return std::hypot(x, y, z); // C++17
225 : }
226 :
227 : /// Normalize this vector.
228 2 : Vec3f &normalize() { return *this /= norm(); }
229 : /// Normalize a copy of this vector (doesn't change the original vector).
230 1000004 : Vec3f normalized() const { return *this / norm(); }
231 :
232 : /// Equality check.
233 21 : bool operator==(Vec3f rhs) const {
234 21 : return this->x == rhs.x && this->y == rhs.y && this->z == rhs.z;
235 : }
236 : /// Inequality check.
237 2 : bool operator!=(Vec3f rhs) const { return !(*this == rhs); }
238 : };
239 :
240 : /// Scalar multiplication.
241 : /// @related Vec3f
242 1 : inline Vec3f operator*(float lhs, Vec3f rhs) {
243 1 : return {lhs * rhs.x, lhs * rhs.y, lhs * rhs.z};
244 : }
245 :
246 : #ifndef ARDUINO
247 :
248 : /// Printing.
249 : /// @related Vec2f
250 : std::ostream &operator<<(std::ostream &os, Vec2f v);
251 :
252 : /// Printing.
253 : /// @related Vec3f
254 : std::ostream &operator<<(std::ostream &os, Vec3f v);
255 :
256 : #endif
257 :
258 : /// Printing.
259 : /// @related Vec2f
260 : Print &operator<<(Print &os, Vec2f v);
261 :
262 : /// Printing.
263 : /// @related Vec3f
264 : Print &operator<<(Print &os, Vec3f v);
265 :
266 : /// @}
267 :
268 : END_AH_NAMESPACE
269 :
270 : AH_DIAGNOSTIC_POP()
|