Brick
Loading...
Searching...
No Matches
translation2d.h
1#pragma once
2
3#include <cmath>
4#include <vector>
5
6#include "cevalm.hpp"
7#include "core/math/eigen_interface.h"
8#include "core/math/geometry/rotation2d.h"
9#include "core/math/units.h"
10
11class Rotation2d;
12
13template <typename Q>
15 units::KinematicQuantity<Q> && std::ratio_equal_v<typename Q::length, std::ratio<1>> &&
16 std::ratio_equal_v<typename Q::angle, std::ratio<0>>;
17
18/**
19 * Class representing a 2d vector. Depending on unit this could be
20 * a Translation2d, Velocity2d, Acceleration2d, Jerk2d, or other
21 *
22 * Assumes conventional cartesian coordinate system:
23 * Looking down at the coordinate plane,
24 * +X is right
25 * +Y is up
26 * +Theta is counterclockwise
27 */
28template <LinearKinematicQuantity Q>
30 private:
31 Q x_;
32 Q y_;
33
34 public:
35 /// Default Constructor for LinearVector2d valued (0, 0)
36 constexpr LinearVector2d() : x_{0}, y_{0} {}
37
38 /**
39 * Constructs a vector with the given x and y values.
40 *
41 * @param x The x component of the vector.
42 * @param y The y component of the vector.
43 */
44 constexpr LinearVector2d(Q x, Q y) : x_{x}, y_{y} {}
45
46 /**
47 * Constructs a vector given polar coordinates of the form (r, theta).
48 *
49 * @param r The magnitude of the vector.
50 * @param theta The angle of the vector.
51 */
52 constexpr LinearVector2d(Q r, Rotation2d theta) : x_{r * theta.f_cos()}, y_{r * theta.f_sin()} {}
53
54 /**
55 * Constructs a vector with the values from the given Eigen::Vector.
56 *
57 * @param vector The vector whose values will be used.
58 * @param unit The unit to use when assigning x and y (e.g. units::inches)
59 */
60 constexpr LinearVector2d(Eigen::Vector2d vector, Q unit)
61 : x_{vector[0], unit}, y_{vector[1], unit} {}
62
63 /// Gets the x component.
64 constexpr Q x() const { return x_; }
65
66 /// Gets x in the supplied unit.
67 constexpr double x(Q unit) const { return x_.to(unit); }
68
69 /// Sets the x component.
70 constexpr void set_x(Q val) { x_ = val; }
71
72 /// Gets the y component.
73 constexpr Q y() const { return y_; }
74
75 /// Gets y in the supplied unit.
76 constexpr double y(Q unit) const { return y_.to(unit); }
77
78 /// Sets the y component.
79 constexpr void set_y(Q val) { y_ = val; }
80
81 /// Gets the angle of the vector from the x axis.
82 constexpr Rotation2d theta() const { return Rotation2d(x_.internal(), y_.internal()); }
83
84 /**
85 * Returns the vector as an Eigen::Vector2d.
86 *
87 * @param unit The unit to get the x and y components as (e.g. units::inches)
88 * @returns Eigen::Vector2d with the same values as the vector.
89 */
90 constexpr Eigen::Vector2d as_vector(Q unit) const { return EVec<2>{x_.to(unit), y_.to(unit)}; }
91
92 /// Gets the norm of the vector.
93 constexpr Q norm() const { return units::hypot(x_, y_); }
94
95 /**
96 * Returns a vector of the same angle, but specific magnitude
97 * (default 1 base unit)
98 *
99 * @param magnitude magnitude of the vector (default 1 base unit).
100 * @returns The normalized vector.
101 */
102 constexpr LinearVector2d normalize(Q magnitude = Q(1.0)) const {
103 return LinearVector2d(magnitude, theta());
104 }
105
106 /// Gets the distance between two vectors.
107 constexpr Q distance(LinearVector2d other) const {
108 return units::hypot(x_ - other.x_, y_ - other.y_);
109 }
110
111 /**
112 * Interpolates along a straight line to another vector.
113 * Fractions outside [0, 1] return the nearest endpoint.
114 *
115 * @param end endpoint
116 * @param fraction percent of the way between the points
117 * @return interpolated vector
118 */
119 constexpr LinearVector2d interpolate(LinearVector2d end, double fraction) const {
120 if (fraction <= 0) {
121 return *this;
122 }
123 if (fraction >= 1) {
124 return end;
125 }
126 return *this + (end - *this) * fraction;
127 }
128
129 /**
130 * Rotates this vector around the origin by the provided rotation.
131 *
132 * Equivalent to multiplying a vector by a rotation matrix:
133 * x = [cos, -sin][x]
134 * y = [sin, cos][y]
135 *
136 * @param rotation the angle amount to rotate.
137 * @returns The new vector that has been rotated around the origin.
138 */
139 constexpr LinearVector2d rotate_by(Rotation2d rotation) const {
140 return {
141 x_ * rotation.f_cos() - y_ * rotation.f_sin(), x_ * rotation.f_sin() + y_ * rotation.f_cos()
142 };
143 }
144
145 /**
146 * Applies a rotation to this vector around another given vector.
147 *
148 * [x] = [cos, -sin][x - otherx] + [otherx]
149 * [y] = [sin, cos][y - othery] + [othery]
150 *
151 * @param other the center of rotation.
152 * @param rotation the angle amount the vector will be rotated.
153 * @returns The vector that has been rotated.
154 */
155 constexpr LinearVector2d rotate_around(LinearVector2d other, Rotation2d rotation) const {
156 LinearVector2d diff = *this - other;
157 return diff.rotate_by(rotation) + other;
158 }
159
160 /**
161 * Returns the inverse of this vector, or mirrors it across the origin.
162 * [x] = [-x]
163 * [y] = [-y]
164 *
165 * @returns The inverse of this vector.
166 */
167 constexpr LinearVector2d inverse() const { return LinearVector2d(-x_, -y_); }
168
169 /**
170 * Returns the dot product of two vectors.
171 * The result has the product of the two component units.
172 *
173 * [scalar] = [x][otherx] + [y][othery]
174 *
175 * @param other the other vector to dot with.
176 * @returns The dot product of this and other.
177 */
179 return (x_ * other.x_) + (y_ * other.y_);
180 }
181
182 /// Adds another vector to this vector component wise.
183 constexpr LinearVector2d operator+(LinearVector2d other) const {
184 return {x_ + other.x_, y_ + other.y_};
185 }
186
187 /// Adds another vector to this vector component wise.
188 constexpr LinearVector2d& operator+=(LinearVector2d other) { return *this = *this + other; }
189
190 /// Subtracts another vector from this vector component wise.
191 constexpr LinearVector2d operator-(LinearVector2d other) const {
192 return {x_ - other.x_, y_ - other.y_};
193 }
194
195 /// Subtracts another vector from this vector component wise.
196 constexpr LinearVector2d& operator-=(LinearVector2d other) { return *this = *this - other; }
197
198 /// Inverts this vector (flipped across origin).
199 constexpr LinearVector2d operator-() const { return inverse(); }
200
201 /// Multiplies this vector by a scalar.
202 constexpr LinearVector2d operator*(double scalar) const { return {x_ * scalar, y_ * scalar}; }
203
204 /// Multiplies a scalar by this vector.
205 friend constexpr LinearVector2d operator*(double scalar, LinearVector2d vector) {
206 return vector * scalar;
207 }
208
209 /**
210 * Multiplies this vector by a scalar with a unit of time.
211 * e.g. Velocity2d * Time = Translation2d
212 */
213 template <units::IsQuantity S>
216 return LinearVector2d<units::Multiplied<Q, S>>{x_ * scalar, y_ * scalar};
217 }
218
219 /**
220 * Multiplies a scalar with a unit of time by this vector.
221 * e.g. Time * Velocity2d = Translation2d
222 */
223 template <units::IsQuantity S>
225 friend constexpr auto operator*(S scalar, LinearVector2d vector) {
226 return vector * scalar;
227 }
228
229 /**
230 * Returns the dot product of two vectors.
231 * The result has the product of the two component units.
232 *
233 * [scalar] = [x][otherx] + [y][othery]
234 *
235 * @param other the other vector to dot with.
236 * @returns The dot product of this and other.
237 */
238 constexpr units::Multiplied<Q, Q> operator*(LinearVector2d other) const { return dot(other); }
239
240 /// Multiplies this vector by a scalar.
241 constexpr LinearVector2d& operator*=(double scalar) { return *this = *this * scalar; }
242
243 /// Divides this vector by a scalar.
244 constexpr LinearVector2d operator/(double scalar) const { return {x_ / scalar, y_ / scalar}; }
245
246 template <units::IsQuantity S>
248 constexpr LinearVector2d<units::Divided<Q, S>> operator/(S scalar) const {
249 return LinearVector2d<units::Divided<Q, S>>{x_ / scalar, y_ / scalar};
250 }
251
252 /// Divides this vector by a scalar.
253 constexpr LinearVector2d& operator/=(double scalar) { return *this = *this / scalar; }
254
255 /// Checks exact equality between this and another vector.
256 constexpr bool operator==(LinearVector2d other) const {
257 return cevalm::abs(x_.internal() - other.x_.internal()) < 1e-6 &&
258 cevalm::abs(y_.internal() - other.y_.internal()) < 1e-6;
259 }
260
261 /**
262 * Checks the distance between vectors against a tolerance.
263 * Defaults to 1um for translations, 1um/s for velocities, etc.
264 */
265 constexpr bool is_near(LinearVector2d other, Q tolerance = Q(1e-6)) const {
266 return distance(other) <= tolerance;
267 }
268
269 /**
270 * Calculates the mean of a list of vectors.
271 *
272 * @param list std::vector containing a list of vectors.
273 * @return the single vector mean of the list of vectors.
274 */
275 static constexpr LinearVector2d mean(const std::vector<LinearVector2d>& list) {
276 if (list.size() == 0) {
277 return LinearVector2d{};
278 }
279
280 Q sumx;
281 Q sumy;
282
283 for (LinearVector2d& vec : list) {
284 sumx += vec.x_;
285 sumy += vec.y_;
286 }
287
288 return LinearVector2d(sumx / list.size(), sumy / list.size());
289 }
290};
291
292/// Translation2d is a 2d length vector
293using Translation2d = LinearVector2d<units::Length>;
294/// Velocity2d is a 2d velocity vector
295using Velocity2d = LinearVector2d<units::Velocity>;
296/// Acceleration2d is a 2d acceleration vector
297using Acceleration2d = LinearVector2d<units::Acceleration>;
298/// Jerk2d is a 2d jerk vector
299using Jerk2d = LinearVector2d<units::Jerk>;
Definition translation2d.h:29
constexpr bool operator==(LinearVector2d other) const
Checks exact equality between this and another vector.
Definition translation2d.h:256
constexpr LinearVector2d & operator-=(LinearVector2d other)
Subtracts another vector from this vector component wise.
Definition translation2d.h:196
constexpr Rotation2d theta() const
Definition translation2d.h:82
constexpr LinearVector2d operator-() const
Inverts this vector (flipped across origin).
Definition translation2d.h:199
constexpr LinearVector2d & operator*=(double scalar)
Multiplies this vector by a scalar.
Definition translation2d.h:241
constexpr double x(Q unit) const
Gets x in the supplied unit.
Definition translation2d.h:67
constexpr LinearVector2d operator-(LinearVector2d other) const
Subtracts another vector from this vector component wise.
Definition translation2d.h:191
constexpr LinearVector2d interpolate(LinearVector2d end, double fraction) const
Definition translation2d.h:119
constexpr units::Multiplied< Q, Q > dot(LinearVector2d other) const
Definition translation2d.h:178
constexpr LinearVector2d normalize(Q magnitude=Q(1.0)) const
Definition translation2d.h:102
constexpr LinearVector2d & operator/=(double scalar)
Divides this vector by a scalar.
Definition translation2d.h:253
constexpr Q x() const
Definition translation2d.h:64
constexpr LinearVector2d operator+(LinearVector2d other) const
Adds another vector to this vector component wise.
Definition translation2d.h:183
friend constexpr auto operator*(S scalar, LinearVector2d vector)
Definition translation2d.h:225
friend constexpr LinearVector2d operator*(double scalar, LinearVector2d vector)
Multiplies a scalar by this vector.
Definition translation2d.h:205
constexpr Q distance(LinearVector2d other) const
Gets the distance between two vectors.
Definition translation2d.h:107
constexpr double y(Q unit) const
Gets y in the supplied unit.
Definition translation2d.h:76
constexpr void set_x(Q val)
Sets the x component.
Definition translation2d.h:70
constexpr units::Multiplied< Q, Q > operator*(LinearVector2d other) const
Definition translation2d.h:238
constexpr LinearVector2d operator*(double scalar) const
Multiplies this vector by a scalar.
Definition translation2d.h:202
static constexpr LinearVector2d mean(const std::vector< LinearVector2d > &list)
Definition translation2d.h:275
constexpr void set_y(Q val)
Sets the y component.
Definition translation2d.h:79
constexpr LinearVector2d rotate_around(LinearVector2d other, Rotation2d rotation) const
Definition translation2d.h:155
constexpr LinearVector2d()
Default Constructor for LinearVector2d valued (0, 0).
Definition translation2d.h:36
constexpr LinearVector2d(Q x, Q y)
Definition translation2d.h:44
constexpr LinearVector2d(Q r, Rotation2d theta)
Definition translation2d.h:52
constexpr LinearVector2d(Eigen::Vector2d vector, Q unit)
Definition translation2d.h:60
constexpr LinearVector2d< units::Multiplied< Q, S > > operator*(S scalar) const
Definition translation2d.h:215
constexpr LinearVector2d & operator+=(LinearVector2d other)
Adds another vector to this vector component wise.
Definition translation2d.h:188
constexpr bool is_near(LinearVector2d other, Q tolerance=Q(1e-6)) const
Definition translation2d.h:265
constexpr LinearVector2d rotate_by(Rotation2d rotation) const
Definition translation2d.h:139
constexpr LinearVector2d inverse() const
Definition translation2d.h:167
constexpr Eigen::Vector2d as_vector(Q unit) const
Definition translation2d.h:90
constexpr Q norm() const
Gets the norm of the vector.
Definition translation2d.h:93
constexpr Q y() const
Definition translation2d.h:73
constexpr LinearVector2d operator/(double scalar) const
Divides this vector by a scalar.
Definition translation2d.h:244
Definition rotation2d.h:16
constexpr double f_sin() const
Gets the sine of the rotation.
Definition rotation2d.h:87
constexpr Rotation2d()=default
Default Constructor for Rotation2d.
constexpr double f_cos() const
Gets the cosine of the rotation.
Definition rotation2d.h:84
Definition translation2d.h:14
Only allows nonzero length, time, angle for the next two functions.
Definition units.h:961
Quantity< std::ratio_add< typename Q1::mass, typename Q2::mass >, std::ratio_add< typename Q1::length, typename Q2::length >, std::ratio_add< typename Q1::time, typename Q2::time >, std::ratio_add< typename Q1::current, typename Q2::current >, std::ratio_add< typename Q1::angle, typename Q2::angle >, std::ratio_add< typename Q1::temperature, typename Q2::temperature >, std::ratio_add< typename Q1::luminosity, typename Q2::luminosity >, std::ratio_add< typename Q1::moles, typename Q2::moles > > Multiplied
Multiplying quantities adds their dimensions.
Definition units.h:194