Physical Quantities  v1.0.0
C++ library of physical quantities, physical models, and units of measure for scientific computing. https://github.com/acodcha/phq
Loading...
Searching...
No Matches
PlanarVector.hpp
Go to the documentation of this file.
1// Copyright © 2020-2024 Alexandre Coderre-Chabot
2//
3// This file is part of Physical Quantities (PhQ), a C++ library of physical quantities, physical
4// models, and units of measure for scientific computing.
5//
6// Physical Quantities is hosted at:
7// https://github.com/acodcha/phq
8//
9// Physical Quantities is licensed under the MIT License:
10// https://mit-license.org
11//
12// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
13// associated documentation files (the "Software"), to deal in the Software without restriction,
14// including without limitation the rights to use, copy, modify, merge, publish, distribute,
15// sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
16// furnished to do so, subject to the following conditions:
17// - The above copyright notice and this permission notice shall be included in all copies or
18// substantial portions of the Software.
19// - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
20// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
22// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM
23// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
25#ifndef PHQ_PLANAR_VECTOR_HPP
26#define PHQ_PLANAR_VECTOR_HPP
27
28#include <array>
29#include <cmath>
30#include <cstddef>
31#include <functional>
32#include <ostream>
33#include <string>
34#include <type_traits>
35
36#include "Base.hpp"
37
38namespace PhQ {
39
40// Forward declarations for class PhQ::PlanarVector.
41template <typename NumericType>
42class Angle;
43
44// Forward declaration for class PhQ::PlanarVector.
45template <typename>
46class Dyad;
47
48// Forward declaration for class PhQ::PlanarVector.
49template <typename NumericType>
50class PlanarDirection;
51
52// Forward declaration for class PhQ::PlanarVector.
53template <typename NumericType>
54class Vector;
55
56/// \brief Two-dimensional Euclidean vector in the XY plane. Contains two components in Cartesian
57/// coordinates: x and y. For a three-dimensional Euclidean vector, see PhQ::Vector. For a
58/// three-dimensional Euclidean dyadic tensor, see PhQ::Dyad. For a three-dimensional symmetric
59/// Euclidean dyadic tensor, see PhQ::SymmetricDyad.
60/// \tparam NumericType Floating-point numeric type: float, double, or long double. Defaults to
61/// double if unspecified.
62template <typename NumericType = double>
64 static_assert(std::is_floating_point<NumericType>::value,
65 "The NumericType template parameter of PhQ::PlanarVector<NumericType> must be a "
66 "numeric floating-point type: float, double, or long double.");
67
68public:
69 /// \brief Default constructor. Constructs a two-dimensional planar vector with uninitialized x
70 /// and y Cartesian components.
71 PlanarVector() = default;
72
73 /// \brief Constructor. Constructs a two-dimensional planar vector from the given x and y
74 /// Cartesian components.
75 constexpr PlanarVector(const NumericType x, const NumericType y) : x_y_({x, y}) {}
76
77 /// \brief Constructor. Constructs a two-dimensional planar vector from a given array representing
78 /// its x and y Cartesian components.
79 explicit constexpr PlanarVector(const std::array<NumericType, 2>& x_y) : x_y_(x_y) {}
80
81 /// \brief Constructor. Constructs a two-dimensional planar vector from a given three-dimensional
82 /// vector. Projects the three-dimensional vector onto the XY plane.
83 explicit constexpr PlanarVector(const Vector<NumericType>& vector);
84
85 /// \brief Constructor. Constructs a two-dimensional planar vector given a magnitude and a planar
86 /// direction.
87 constexpr PlanarVector(NumericType magnitude, const PlanarDirection<NumericType>& direction);
88
89 /// \brief Destructor. Destroys this two-dimensional planar vector.
90 ~PlanarVector() noexcept = default;
91
92 /// \brief Copy constructor. Constructs a two-dimensional planar vector by copying another one.
93 constexpr PlanarVector(const PlanarVector<NumericType>& other) = default;
94
95 /// \brief Copy constructor. Constructs a two-dimensional planar vector by copying another one.
96 template <typename OtherNumericType>
97 explicit constexpr PlanarVector(const PlanarVector<OtherNumericType>& other)
98 : x_y_({static_cast<NumericType>(other.x()), static_cast<NumericType>(other.y())}) {}
99
100 /// \brief Move constructor. Constructs a two-dimensional planar vector by moving another one.
101 constexpr PlanarVector(PlanarVector<NumericType>&& other) noexcept = default;
102
103 /// \brief Copy assignment operator. Assigns this two-dimensional planar vector by copying another
104 /// one.
106
107 /// \brief Copy assignment operator. Assigns this two-dimensional planar vector by copying another
108 /// one.
109 template <typename OtherNumericType>
111 x_y_[0] = static_cast<NumericType>(other.x());
112 x_y_[1] = static_cast<NumericType>(other.y());
113 return *this;
114 }
115
116 /// \brief Move assignment operator. Assigns this two-dimensional planar vector by moving another
117 /// one.
119 PlanarVector<NumericType>&& other) noexcept = default;
120
121 /// \brief Assignment operator. Assigns this two-dimensional planar vector by copying a given
122 /// array representing its x and y Cartesian components.
123 constexpr PlanarVector<NumericType>& operator=(const std::array<NumericType, 2>& x_y) {
124 x_y_ = x_y;
125 return *this;
126 }
127
128 /// \brief Statically creates a two-dimensional planar vector with its x and y Cartesian
129 /// components initialized to zero.
130 [[nodiscard]] static constexpr PlanarVector<NumericType> Zero() {
132 std::array<NumericType, 2>{static_cast<NumericType>(0), static_cast<NumericType>(0)}
133 };
134 }
135
136 /// \brief Returns this two-dimensional planar vector's x and y Cartesian components as an array.
137 [[nodiscard]] constexpr const std::array<NumericType, 2>& x_y() const noexcept {
138 return x_y_;
139 }
140
141 /// \brief Returns this two-dimensional planar vector's x Cartesian component.
142 [[nodiscard]] constexpr NumericType x() const noexcept {
143 return x_y_[0];
144 }
145
146 /// \brief Returns this two-dimensional planar vector's y Cartesian component.
147 [[nodiscard]] constexpr NumericType y() const noexcept {
148 return x_y_[1];
149 }
150
151 /// \brief Returns this two-dimensional planar vector's x and y Cartesian components as a mutable
152 /// array.
153 [[nodiscard]] constexpr std::array<NumericType, 2>& Mutable_x_y() noexcept {
154 return x_y_;
155 }
156
157 /// \brief Returns this two-dimensional planar vector's x Cartesian component as a mutable value.
158 [[nodiscard]] constexpr NumericType& Mutable_x() noexcept {
159 return x_y_[0];
160 }
161
162 /// \brief Returns this two-dimensional planar vector's y Cartesian component as a mutable value.
163 [[nodiscard]] constexpr NumericType& Mutable_y() noexcept {
164 return x_y_[1];
165 }
166
167 /// \brief Sets this two-dimensional planar vector's x and y Cartesian components to the given
168 /// values.
169 constexpr void Set_x_y(const std::array<NumericType, 2>& x_y) noexcept {
170 x_y_ = x_y;
171 }
172
173 /// \brief Sets this two-dimensional planar vector's x and y Cartesian components to the given
174 /// values.
175 constexpr void Set_x_y(const NumericType x, const NumericType y) noexcept {
176 x_y_[0] = x;
177 x_y_[1] = y;
178 }
179
180 /// \brief Sets this two-dimensional planar vector's x Cartesian component to a given value.
181 constexpr void Set_x(const NumericType x) noexcept {
182 x_y_[0] = x;
183 }
184
185 /// \brief Sets this two-dimensional planar vector's y Cartesian component to a given value.
186 constexpr void Set_y(const NumericType y) noexcept {
187 x_y_[1] = y;
188 }
189
190 /// \brief Returns the square of the magnitude of this two-dimensional planar vector.
191 [[nodiscard]] constexpr NumericType MagnitudeSquared() const noexcept {
192 return x_y_[0] * x_y_[0] + x_y_[1] * x_y_[1];
193 }
194
195 /// \brief Returns the magnitude (also known as the L2 norm) of this two-dimensional planar
196 /// vector.
197 [[nodiscard]] NumericType Magnitude() const noexcept {
198 return std::sqrt(MagnitudeSquared());
199 }
200
201 /// \brief Returns the planar direction of this two-dimensional planar vector.
203
204 /// \brief Returns the dot product (also known as the inner product or scalar product) of this
205 /// two-dimensional planar vector and another one.
206 [[nodiscard]] constexpr NumericType Dot(const PlanarVector<NumericType>& other) const noexcept {
207 return x_y_[0] * other.x_y_[0] + x_y_[1] * other.x_y_[1];
208 }
209
210 /// \brief Returns the dot product (also known as the inner product or scalar product) of this
211 /// two-dimensional planar vector and a given planar direction.
212 [[nodiscard]] constexpr NumericType Dot(
213 const PhQ::PlanarDirection<NumericType>& planar_direction) const noexcept;
214
215 /// \brief Returns the cross product (also known as the vector product) of this two-dimensional
216 /// planar vector and another one.
217 [[nodiscard]] constexpr Vector<NumericType> Cross(const PlanarVector<NumericType>& other) const;
218
219 /// \brief Returns the cross product (also known as the vector product) of this two-dimensional
220 /// planar vector and a given planar direction.
221 [[nodiscard]] constexpr Vector<NumericType> Cross(
222 const PhQ::PlanarDirection<NumericType>& planar_direction) const;
223
224 /// \brief Returns the dyadic tensor product (also known as the outer product) of this
225 /// two-dimensional planar vector and another one.
226 [[nodiscard]] constexpr Dyad<NumericType> Dyadic(const PlanarVector<NumericType>& other) const;
227
228 /// \brief Returns the dyadic tensor product (also known as the outer product) of this
229 /// two-dimensional planar vector and a given planar direction.
230 [[nodiscard]] constexpr Dyad<NumericType> Dyadic(
231 const PhQ::PlanarDirection<NumericType>& planar_direction) const;
232
233 /// \brief Returns the angle between this two-dimensional planar vector and another one.
234 [[nodiscard]] PhQ::Angle<NumericType> Angle(const PlanarVector<NumericType>& other) const;
235
236 /// \brief Returns the angle between this two-dimensional planar vector and a given planar
237 /// direction.
238 [[nodiscard]] PhQ::Angle<NumericType> Angle(
239 const PhQ::PlanarDirection<NumericType>& planar_direction) const;
240
241 /// \brief Prints this two-dimensional planar vector as a string.
242 [[nodiscard]] std::string Print() const {
243 return "(" + PhQ::Print(x_y_[0]) + ", " + PhQ::Print(x_y_[1]) + ")";
244 }
245
246 /// \brief Serializes this two-dimensional planar vector as a JSON message.
247 [[nodiscard]] std::string JSON() const {
248 return "{\"x\":" + PhQ::Print(x_y_[0]) + ",\"y\":" + PhQ::Print(x_y_[1]) + "}";
249 }
250
251 /// \brief Serializes this two-dimensional planar vector as an XML message.
252 [[nodiscard]] std::string XML() const {
253 return "<x>" + PhQ::Print(x_y_[0]) + "</x><y>" + PhQ::Print(x_y_[1]) + "</y>";
254 }
255
256 /// \brief Serializes this two-dimensional planar vector as a YAML message.
257 [[nodiscard]] std::string YAML() const {
258 return "{x:" + PhQ::Print(x_y_[0]) + ",y:" + PhQ::Print(x_y_[1]) + "}";
259 }
260
261 /// \brief Adds another two-dimensional planar vector to this one.
262 constexpr void operator+=(const PlanarVector<NumericType>& other) noexcept {
263 x_y_[0] += other.x_y_[0];
264 x_y_[1] += other.x_y_[1];
265 }
266
267 /// \brief Subtracts another two-dimensional planar vector from this one.
268 constexpr void operator-=(const PlanarVector<NumericType>& other) noexcept {
269 x_y_[0] -= other.x_y_[0];
270 x_y_[1] -= other.x_y_[1];
271 }
272
273 /// \brief Multiplies this two-dimensional planar vector by the given number.
274 /// \tparam OtherNumericType Floating-point numeric type of the given number. Deduced
275 /// automatically.
276 template <typename OtherNumericType>
277 constexpr void operator*=(const OtherNumericType number) noexcept {
278 x_y_[0] *= static_cast<NumericType>(number);
279 x_y_[1] *= static_cast<NumericType>(number);
280 }
281
282 /// \brief Divides this two-dimensional planar vector by the given number.
283 /// \tparam OtherNumericType Floating-point numeric type of the given number. Deduced
284 /// automatically.
285 template <typename OtherNumericType>
286 constexpr void operator/=(const OtherNumericType number) noexcept {
287 x_y_[0] /= static_cast<NumericType>(number);
288 x_y_[1] /= static_cast<NumericType>(number);
289 }
290
291private:
292 /// \brief Cartesian components of this two-dimensional planar vector.
293 std::array<NumericType, 2> x_y_;
294};
295
296template <typename NumericType>
297inline constexpr bool operator==(
298 const PlanarVector<NumericType>& left, const PlanarVector<NumericType>& right) noexcept {
299 return left.x() == right.x() && left.y() == right.y();
300}
301
302template <typename NumericType>
303inline constexpr bool operator!=(
304 const PlanarVector<NumericType>& left, const PlanarVector<NumericType>& right) noexcept {
305 return left.x() != right.x() || left.y() != right.y();
306}
307
308template <typename NumericType>
309inline constexpr bool operator<(
310 const PlanarVector<NumericType>& left, const PlanarVector<NumericType>& right) noexcept {
311 if (left.x() != right.x()) {
312 return left.x() < right.x();
313 }
314 return left.y() < right.y();
315}
316
317template <typename NumericType>
318inline constexpr bool operator>(
319 const PlanarVector<NumericType>& left, const PlanarVector<NumericType>& right) noexcept {
320 if (left.x() != right.x()) {
321 return left.x() > right.x();
322 }
323 return left.y() > right.y();
324}
325
326template <typename NumericType>
327inline constexpr bool operator<=(
328 const PlanarVector<NumericType>& left, const PlanarVector<NumericType>& right) noexcept {
329 return !(left > right);
330}
331
332template <typename NumericType>
333inline constexpr bool operator>=(
334 const PlanarVector<NumericType>& left, const PlanarVector<NumericType>& right) noexcept {
335 return !(left < right);
336}
337
338template <typename NumericType>
340 const PlanarVector<NumericType>& left, const PlanarVector<NumericType>& right) {
341 return PlanarVector<NumericType>{left.x() + right.x(), left.y() + right.y()};
342}
343
344template <typename NumericType>
346 const PlanarVector<NumericType>& left, const PlanarVector<NumericType>& right) {
347 return PlanarVector<NumericType>{left.x() - right.x(), left.y() - right.y()};
348}
349
350template <typename NumericType, typename OtherNumericType>
352 const PlanarVector<NumericType>& planar_vector, const OtherNumericType number) {
353 return PlanarVector<NumericType>{planar_vector.x() * static_cast<NumericType>(number),
354 planar_vector.y() * static_cast<NumericType>(number)};
355}
356
357template <typename NumericType, typename OtherNumericType>
359 const OtherNumericType number, const PlanarVector<NumericType>& planar_vector) {
360 return PlanarVector<NumericType>{planar_vector * number};
361}
362
363template <typename NumericType, typename OtherNumericType>
365 const PlanarVector<NumericType>& planar_vector, const OtherNumericType number) {
366 return PlanarVector<NumericType>{planar_vector.x() / static_cast<NumericType>(number),
367 planar_vector.y() / static_cast<NumericType>(number)};
368}
369
370template <typename NumericType>
371inline std::ostream& operator<<(
372 std::ostream& stream, const PlanarVector<NumericType>& planar_vector) {
373 stream << planar_vector.Print();
374 return stream;
375}
376
377} // namespace PhQ
378
379namespace std {
380
381template <typename NumericType>
382struct hash<PhQ::PlanarVector<NumericType>> {
383 inline size_t operator()(const PhQ::PlanarVector<NumericType>& planar_vector) const {
384 size_t result{17};
385 result = static_cast<size_t>(31) * result + hash<NumericType>()(planar_vector.x());
386 result = static_cast<size_t>(31) * result + hash<NumericType>()(planar_vector.y());
387 return result;
388 }
389};
390
391} // namespace std
392
393#endif // PHQ_PLANAR_VECTOR_HPP
Plane angle between two lines or dihedral angle between two planes.
Definition Angle.hpp:130
Three-dimensional Euclidean dyadic tensor. Contains nine components in Cartesian coordinates: xx,...
Definition Dyad.hpp:51
two-dimensional Euclidean direction vector in the XY plane. Contains two components in Cartesian coor...
Two-dimensional Euclidean vector in the XY plane. Contains two components in Cartesian coordinates: x...
constexpr Vector< NumericType > Cross(const PlanarVector< NumericType > &other) const
Returns the cross product (also known as the vector product) of this two-dimensional planar vector an...
Definition Vector.hpp:411
constexpr PlanarVector(const NumericType x, const NumericType y)
Constructor. Constructs a two-dimensional planar vector from the given x and y Cartesian components.
std::string YAML() const
Serializes this two-dimensional planar vector as a YAML message.
constexpr NumericType x() const noexcept
Returns this two-dimensional planar vector's x Cartesian component.
constexpr void operator*=(const OtherNumericType number) noexcept
Multiplies this two-dimensional planar vector by the given number.
constexpr void operator-=(const PlanarVector< NumericType > &other) noexcept
Subtracts another two-dimensional planar vector from this one.
constexpr void Set_x_y(const NumericType x, const NumericType y) noexcept
Sets this two-dimensional planar vector's x and y Cartesian components to the given values.
constexpr void operator+=(const PlanarVector< NumericType > &other) noexcept
Adds another two-dimensional planar vector to this one.
static constexpr PlanarVector< NumericType > Zero()
Statically creates a two-dimensional planar vector with its x and y Cartesian components initialized ...
constexpr std::array< NumericType, 2 > & Mutable_x_y() noexcept
Returns this two-dimensional planar vector's x and y Cartesian components as a mutable array.
constexpr void Set_y(const NumericType y) noexcept
Sets this two-dimensional planar vector's y Cartesian component to a given value.
PlanarVector()=default
Default constructor. Constructs a two-dimensional planar vector with uninitialized x and y Cartesian ...
constexpr PlanarVector< NumericType > & operator=(const PlanarVector< OtherNumericType > &other)
Copy assignment operator. Assigns this two-dimensional planar vector by copying another one.
constexpr PlanarVector< NumericType > & operator=(const PlanarVector< NumericType > &other)=default
Copy assignment operator. Assigns this two-dimensional planar vector by copying another one.
constexpr void Set_x(const NumericType x) noexcept
Sets this two-dimensional planar vector's x Cartesian component to a given value.
PhQ::PlanarDirection< NumericType > PlanarDirection() const
Returns the planar direction of this two-dimensional planar vector.
constexpr NumericType Dot(const PlanarVector< NumericType > &other) const noexcept
Returns the dot product (also known as the inner product or scalar product) of this two-dimensional p...
NumericType Magnitude() const noexcept
Returns the magnitude (also known as the L2 norm) of this two-dimensional planar vector.
constexpr PlanarVector(PlanarVector< NumericType > &&other) noexcept=default
Move constructor. Constructs a two-dimensional planar vector by moving another one.
std::string JSON() const
Serializes this two-dimensional planar vector as a JSON message.
std::string XML() const
Serializes this two-dimensional planar vector as an XML message.
std::array< NumericType, 2 > x_y_
Cartesian components of this two-dimensional planar vector.
constexpr PlanarVector(const std::array< NumericType, 2 > &x_y)
Constructor. Constructs a two-dimensional planar vector from a given array representing its x and y C...
constexpr void Set_x_y(const std::array< NumericType, 2 > &x_y) noexcept
Sets this two-dimensional planar vector's x and y Cartesian components to the given values.
constexpr void operator/=(const OtherNumericType number) noexcept
Divides this two-dimensional planar vector by the given number.
constexpr const std::array< NumericType, 2 > & x_y() const noexcept
Returns this two-dimensional planar vector's x and y Cartesian components as an array.
constexpr NumericType & Mutable_y() noexcept
Returns this two-dimensional planar vector's y Cartesian component as a mutable value.
constexpr Dyad< NumericType > Dyadic(const PlanarVector< NumericType > &other) const
Returns the dyadic tensor product (also known as the outer product) of this two-dimensional planar ve...
Definition Dyad.hpp:722
constexpr NumericType & Mutable_x() noexcept
Returns this two-dimensional planar vector's x Cartesian component as a mutable value.
std::string Print() const
Prints this two-dimensional planar vector as a string.
constexpr NumericType y() const noexcept
Returns this two-dimensional planar vector's y Cartesian component.
constexpr PlanarVector< NumericType > & operator=(PlanarVector< NumericType > &&other) noexcept=default
Move assignment operator. Assigns this two-dimensional planar vector by moving another one.
constexpr NumericType MagnitudeSquared() const noexcept
Returns the square of the magnitude of this two-dimensional planar vector.
constexpr PlanarVector< NumericType > & operator=(const std::array< NumericType, 2 > &x_y)
Assignment operator. Assigns this two-dimensional planar vector by copying a given array representing...
~PlanarVector() noexcept=default
Destructor. Destroys this two-dimensional planar vector.
Three-dimensional Euclidean vector. Contains three components in Cartesian coordinates: x,...
Definition Vector.hpp:60
Angle
Angle units.
Definition Angle.hpp:53
Namespace that encompasses all of the Physical Quantities library's content.
std::ostream & operator<<(std::ostream &stream, const Acceleration< NumericType > &acceleration)
constexpr Dyad< NumericType > operator+(const Dyad< NumericType > &left, const Dyad< NumericType > &right)
Definition Dyad.hpp:568
constexpr bool operator<(const Acceleration< NumericType > &left, const Acceleration< NumericType > &right) noexcept
constexpr bool operator<=(const Acceleration< NumericType > &left, const Acceleration< NumericType > &right) noexcept
constexpr Dyad< NumericType > operator/(const Dyad< NumericType > &dyad, const OtherNumericType number)
Definition Dyad.hpp:696
constexpr Dyad< NumericType > operator-(const Dyad< NumericType > &left, const Dyad< NumericType > &right)
Definition Dyad.hpp:576
constexpr bool operator>(const Acceleration< NumericType > &left, const Acceleration< NumericType > &right) noexcept
constexpr Acceleration< NumericType > operator*(const NumericType number, const Acceleration< NumericType > &acceleration)
constexpr bool operator==(const Acceleration< NumericType > &left, const Acceleration< NumericType > &right) noexcept
constexpr bool operator>=(const Acceleration< NumericType > &left, const Acceleration< NumericType > &right) noexcept
constexpr bool operator!=(const Acceleration< NumericType > &left, const Acceleration< NumericType > &right) noexcept
std::string Print(const NumericType value)
Prints a given floating-point number as a string. Prints enough digits to represent the number exactl...
Definition Base.hpp:170