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