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