Physical Quantities  v1.0.0
C++ library of physical quantities, physical models, and units of measure for scientific computing. https://github.com/acodcha/phq
Displacement.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_DISPLACEMENT_HPP
26 #define PHQ_DISPLACEMENT_HPP
27 
28 #include <array>
29 #include <cstddef>
30 #include <functional>
31 #include <ostream>
32 
33 #include "Angle.hpp"
34 #include "DimensionalVector.hpp"
35 #include "Direction.hpp"
36 #include "Length.hpp"
37 #include "PlanarDisplacement.hpp"
38 #include "Unit/Length.hpp"
39 #include "Vector.hpp"
40 
41 namespace PhQ {
42 
43 // Forward declaration for class PhQ::Displacement.
44 template <typename NumericType>
45 class Frequency;
46 
47 // Forward declaration for class PhQ::Displacement.
48 template <typename NumericType>
49 class Position;
50 
51 // Forward declaration for class PhQ::Displacement.
52 template <typename NumericType>
53 class Time;
54 
55 // Forward declaration for class PhQ::Displacement.
56 template <typename NumericType>
57 class Velocity;
58 
59 /// \brief Three-dimensional Euclidean displacement vector. Contains three components in Cartesian
60 /// coordinates: x, y, and z. Displacement is not to be confused with position; for a
61 /// three-dimensional Euclidean position vector, see PhQ::Position. For a two-dimensional Euclidean
62 /// displacement vector in the XY plane, see PhQ::PlanarDisplacement. For scalar displacement
63 /// components or for the magnitude of a displacement vector, see PhQ::Length.
64 template <typename NumericType = double>
65 class Displacement : public DimensionalVector<Unit::Length, NumericType> {
66 public:
67  /// \brief Default constructor. Constructs a displacement vector with an uninitialized value.
68  Displacement() = default;
69 
70  /// \brief Constructor. Constructs a displacement vector with a given value expressed in a given
71  /// length unit.
73  : DimensionalVector<Unit::Length, NumericType>(value, unit) {}
74 
75  /// \brief Constructor. Constructs a displacement vector from a given set of length components.
78  : Displacement<NumericType>({x.Value(), y.Value(), z.Value()}) {}
79 
80  /// \brief Constructor. Constructs a displacement vector from a given length and direction.
81  constexpr Displacement(const Length<NumericType>& length, const Direction<NumericType>& direction)
82  : Displacement<NumericType>(length.Value() * direction.Value()) {}
83 
84  /// \brief Constructor. Constructs an displacement vector from a given planar displacement vector
85  /// in the XY plane. This displacement vector's z-component is initialized to zero.
86  explicit constexpr Displacement(const PlanarDisplacement<NumericType>& planar_displacement)
87  : Displacement<NumericType>(Vector<NumericType>{planar_displacement.Value()}) {}
88 
89  /// \brief Constructor. Constructs a displacement vector from a given velocity vector and time
90  /// using the definition of velocity.
91  constexpr Displacement(const Velocity<NumericType>& velocity, const Time<NumericType>& time);
92 
93  /// \brief Constructor. Constructs a displacement vector from a given velocity vector and
94  /// frequency using the definition of velocity.
95  constexpr Displacement(
96  const Velocity<NumericType>& velocity, const Frequency<NumericType>& frequency);
97 
98  /// \brief Constructor. Constructs a displacement vector between a given position vector and the
99  /// origin.
100  explicit constexpr Displacement(const Position<NumericType>& position);
101 
102  /// \brief Destructor. Destroys this displacement vector.
103  ~Displacement() noexcept = default;
104 
105  /// \brief Copy constructor. Constructs a displacement vector by copying another one.
106  constexpr Displacement(const Displacement<NumericType>& other) = default;
107 
108  /// \brief Copy constructor. Constructs a displacement by copying another one.
109  template <typename OtherNumericType>
110  explicit constexpr Displacement(const Displacement<OtherNumericType>& other)
111  : Displacement(static_cast<Vector<NumericType>>(other.Value())) {}
112 
113  /// \brief Move constructor. Constructs a displacement vector by moving another one.
114  constexpr Displacement(Displacement<NumericType>&& other) noexcept = default;
115 
116  /// \brief Copy assignment operator. Assigns this displacement vector by copying another one.
118 
119  /// \brief Copy assignment operator. Assigns this displacement by copying another one.
120  template <typename OtherNumericType>
122  this->value = static_cast<Vector<NumericType>>(other.Value());
123  return *this;
124  }
125 
126  /// \brief Move assignment operator. Assigns this displacement vector by moving another one.
128  Displacement<NumericType>&& other) noexcept = default;
129 
130  /// \brief Statically creates a displacement vector of zero.
131  [[nodiscard]] static constexpr Displacement<NumericType> Zero() {
133  }
134 
135  /// \brief Statically creates a displacement vector from the given x, y, and z Cartesian
136  /// components expressed in a given length unit.
137  template <Unit::Length Unit>
138  [[nodiscard]] static constexpr Displacement<NumericType> Create(
139  const NumericType x, const NumericType y, const NumericType z) {
140  return Displacement<NumericType>{ConvertStatically<Unit::Length, Unit, Standard<Unit::Length>>(
141  Vector<NumericType>{x, y, z})};
142  }
143 
144  /// \brief Statically creates a displacement vector from the given x, y, and z Cartesian
145  /// components expressed in a given length unit.
146  template <Unit::Length Unit>
147  [[nodiscard]] static constexpr Displacement<NumericType> Create(
148  const std::array<NumericType, 3>& x_y_z) {
150  ConvertStatically<Unit::Length, Unit, Standard<Unit::Length>>(Vector<NumericType>{x_y_z})};
151  }
152 
153  /// \brief Statically creates a displacement vector with a given value expressed in a given length
154  /// unit.
155  template <Unit::Length Unit>
156  [[nodiscard]] static constexpr Displacement<NumericType> Create(
157  const Vector<NumericType>& value) {
159  ConvertStatically<Unit::Length, Unit, Standard<Unit::Length>>(value)};
160  }
161 
162  /// \brief Returns the x Cartesian component of this displacement vector.
163  [[nodiscard]] constexpr Length<NumericType> x() const noexcept {
164  return Length<NumericType>{this->value.x()};
165  }
166 
167  /// \brief Returns the y Cartesian component of this displacement vector.
168  [[nodiscard]] constexpr Length<NumericType> y() const noexcept {
169  return Length<NumericType>{this->value.y()};
170  }
171 
172  /// \brief Returns the z Cartesian component of this displacement vector.
173  [[nodiscard]] constexpr Length<NumericType> z() const noexcept {
174  return Length<NumericType>{this->value.z()};
175  }
176 
177  /// \brief Returns the magnitude of this displacement vector.
178  [[nodiscard]] Length<NumericType> Magnitude() const {
179  return Length<NumericType>{this->value.Magnitude()};
180  }
181 
182  /// \brief Returns the direction of this displacement vector.
183  [[nodiscard]] PhQ::Direction<NumericType> Direction() const {
184  return this->value.Direction();
185  }
186 
187  /// \brief Returns the angle between this displacement vector and another one.
188  [[nodiscard]] PhQ::Angle<NumericType> Angle(const Displacement<NumericType>& displacement) const {
189  return PhQ::Angle<NumericType>{*this, displacement};
190  }
191 
192  constexpr Position<NumericType> operator+(const Position<NumericType>& position) const;
193 
195  const Displacement<NumericType>& displacement) const {
196  return Displacement<NumericType>{this->value + displacement.value};
197  }
198 
199  constexpr Position<NumericType> operator-(const Position<NumericType>& position) const;
200 
202  const Displacement<NumericType>& displacement) const {
203  return Displacement<NumericType>{this->value - displacement.value};
204  }
205 
206  constexpr Displacement<NumericType> operator*(const NumericType number) const {
207  return Displacement<NumericType>{this->value * number};
208  }
209 
210  constexpr Velocity<NumericType> operator*(const Frequency<NumericType>& frequency) const;
211 
212  constexpr Displacement<NumericType> operator/(const NumericType number) const {
213  return Displacement<NumericType>{this->value / number};
214  }
215 
216  constexpr Velocity<NumericType> operator/(const Time<NumericType>& time) const;
217 
218  constexpr void operator+=(const Displacement<NumericType>& displacement) noexcept {
219  this->value += displacement.value;
220  }
221 
222  constexpr void operator-=(const Displacement<NumericType>& displacement) noexcept {
223  this->value -= displacement.value;
224  }
225 
226  constexpr void operator*=(const NumericType number) noexcept {
227  this->value *= number;
228  }
229 
230  constexpr void operator/=(const NumericType number) noexcept {
231  this->value /= number;
232  }
233 
234 private:
235  /// \brief Constructor. Constructs a displacement vector with a given value expressed in the
236  /// standard length unit.
237  explicit constexpr Displacement(const Vector<NumericType>& value)
238  : DimensionalVector<Unit::Length, NumericType>(value) {}
239 
240  template <typename OtherNumericType>
241  friend class Position;
242 };
243 
244 template <typename NumericType>
245 inline constexpr bool operator==(
246  const Displacement<NumericType>& left, const Displacement<NumericType>& right) noexcept {
247  return left.Value() == right.Value();
248 }
249 
250 template <typename NumericType>
251 inline constexpr bool operator!=(
252  const Displacement<NumericType>& left, const Displacement<NumericType>& right) noexcept {
253  return left.Value() != right.Value();
254 }
255 
256 template <typename NumericType>
257 inline constexpr bool operator<(
258  const Displacement<NumericType>& left, const Displacement<NumericType>& right) noexcept {
259  return left.Value() < right.Value();
260 }
261 
262 template <typename NumericType>
263 inline constexpr bool operator>(
264  const Displacement<NumericType>& left, const Displacement<NumericType>& right) noexcept {
265  return left.Value() > right.Value();
266 }
267 
268 template <typename NumericType>
269 inline constexpr bool operator<=(
270  const Displacement<NumericType>& left, const Displacement<NumericType>& right) noexcept {
271  return left.Value() <= right.Value();
272 }
273 
274 template <typename NumericType>
275 inline constexpr bool operator>=(
276  const Displacement<NumericType>& left, const Displacement<NumericType>& right) noexcept {
277  return left.Value() >= right.Value();
278 }
279 
280 template <typename NumericType>
281 inline std::ostream& operator<<(
282  std::ostream& stream, const Displacement<NumericType>& displacement) {
283  stream << displacement.Print();
284  return stream;
285 }
286 
287 template <typename NumericType>
289  const NumericType number, const Displacement<NumericType>& displacement) {
290  return displacement * number;
291 }
292 
293 template <typename NumericType>
295  : Direction<NumericType>(displacement.Value()) {}
296 
297 template <typename NumericType>
299  const Displacement<NumericType>& displacement1, const Displacement<NumericType>& displacement2)
300  : Angle<NumericType>(displacement1.Value(), displacement2.Value()) {}
301 
302 template <typename NumericType>
304  const Displacement<NumericType>& displacement)
305  : PlanarDisplacement(PlanarVector<NumericType>{displacement.Value()}) {}
306 
307 } // namespace PhQ
308 
309 namespace std {
310 
311 template <typename NumericType>
312 struct hash<PhQ::Displacement<NumericType>> {
313  inline size_t operator()(const PhQ::Displacement<NumericType>& displacement) const {
314  return hash<PhQ::Vector<NumericType>>()(displacement.Value());
315  }
316 };
317 
318 } // namespace std
319 
320 #endif // PHQ_DISPLACEMENT_HPP
Plane angle between two lines or dihedral angle between two planes.
Definition: Angle.hpp:130
Angle()=default
Default constructor. Constructs an angle with an uninitialized value.
constexpr const PhQ::PlanarVector< NumericType > & Value() const noexcept
Value of this physical quantity expressed in its standard unit of measure.
Abstract base class that represents any dimensional vector physical quantity. Such a physical quantit...
std::string Print() const
Prints this physical quantity as a string. This physical quantity's value is expressed in its standar...
static constexpr Unit::Length Unit()
Standard unit of measure for this physical quantity. This physical quantity's value is stored interna...
PhQ::Vector< double > value
Value of this physical quantity expressed in its standard unit of measure.
constexpr const PhQ::Vector< double > & Value() const noexcept
Value of this physical quantity expressed in its standard unit of measure.
Three-dimensional Euclidean direction vector. Contains three components in Cartesian coordinates: x,...
Definition: Direction.hpp:115
constexpr Direction()
Default constructor. Initializes a direction to the zero vector.
Definition: Direction.hpp:118
Three-dimensional Euclidean displacement vector. Contains three components in Cartesian coordinates: ...
constexpr Displacement< NumericType > operator*(const NumericType number) const
constexpr void operator/=(const NumericType number) noexcept
Displacement(const Vector< NumericType > &value, const Unit::Length unit)
Constructor. Constructs a displacement vector with a given value expressed in a given length unit.
constexpr Displacement< NumericType > operator/(const NumericType number) const
constexpr Displacement< NumericType > operator+(const Displacement< NumericType > &displacement) const
constexpr Displacement< NumericType > & operator=(Displacement< NumericType > &&other) noexcept=default
Move assignment operator. Assigns this displacement vector by moving another one.
constexpr Displacement(Displacement< NumericType > &&other) noexcept=default
Move constructor. Constructs a displacement vector by moving another one.
constexpr Displacement< NumericType > operator-(const Displacement< NumericType > &displacement) const
constexpr Position< NumericType > operator-(const Position< NumericType > &position) const
Definition: Position.hpp:292
constexpr Length< NumericType > x() const noexcept
Returns the x Cartesian component of this displacement vector.
Length< NumericType > Magnitude() const
Returns the magnitude of this displacement vector.
constexpr Displacement< NumericType > & operator=(const Displacement< NumericType > &other)=default
Copy assignment operator. Assigns this displacement vector by copying another one.
constexpr Length< NumericType > z() const noexcept
Returns the z Cartesian component of this displacement vector.
constexpr void operator+=(const Displacement< NumericType > &displacement) noexcept
constexpr Length< NumericType > y() const noexcept
Returns the y Cartesian component of this displacement vector.
PhQ::Direction< NumericType > Direction() const
Returns the direction of this displacement vector.
Displacement(const Length< NumericType > &x, const Length< NumericType > &y, const Length< NumericType > &z)
Constructor. Constructs a displacement vector from a given set of length components.
constexpr Displacement< NumericType > & operator=(const Displacement< OtherNumericType > &other)
Copy assignment operator. Assigns this displacement by copying another one.
constexpr void operator-=(const Displacement< NumericType > &displacement) noexcept
PhQ::Angle< NumericType > Angle(const Displacement< NumericType > &displacement) const
Returns the angle between this displacement vector and another one.
static constexpr Displacement< NumericType > Zero()
Statically creates a displacement vector of zero.
constexpr Displacement(const Vector< NumericType > &value)
Constructor. Constructs a displacement vector with a given value expressed in the standard length uni...
constexpr Displacement(const PlanarDisplacement< NumericType > &planar_displacement)
Constructor. Constructs an displacement vector from a given planar displacement vector in the XY plan...
static constexpr Displacement< NumericType > Create(const std::array< NumericType, 3 > &x_y_z)
Statically creates a displacement vector from the given x, y, and z Cartesian components expressed in...
constexpr Position< NumericType > operator+(const Position< NumericType > &position) const
Definition: Position.hpp:286
static constexpr Displacement< NumericType > Create(const NumericType x, const NumericType y, const NumericType z)
Statically creates a displacement vector from the given x, y, and z Cartesian components expressed in...
constexpr void operator*=(const NumericType number) noexcept
~Displacement() noexcept=default
Destructor. Destroys this displacement vector.
Displacement()=default
Default constructor. Constructs a displacement vector with an uninitialized value.
constexpr Displacement(const Length< NumericType > &length, const Direction< NumericType > &direction)
Constructor. Constructs a displacement vector from a given length and direction.
static constexpr Displacement< NumericType > Create(const Vector< NumericType > &value)
Statically creates a displacement vector with a given value expressed in a given length unit.
Frequency. Inverse of a time duration. See also PhQ::Time.
Definition: Frequency.hpp:40
Length, distance, or physical size. Can also represent a scalar component or magnitude of a position ...
Definition: Length.hpp:111
Two-dimensional Euclidean displacement vector in the XY plane. Contains two components in Cartesian c...
PlanarDisplacement()=default
Default constructor. Constructs a planar displacement vector with an uninitialized value.
Two-dimensional Euclidean vector in the XY plane. Contains two components in Cartesian coordinates: x...
Three-dimensional Euclidean position vector. Contains three components in Cartesian coordinates: x,...
Definition: Position.hpp:50
Time. Can represent either a point in time, a time duration, or a period. For the inverse of time,...
Definition: Time.hpp:172
Three-dimensional Euclidean vector. Contains three components in Cartesian coordinates: x,...
Definition: Vector.hpp:60
NumericType Magnitude() const noexcept
Returns the magnitude (also known as the L2 norm) of this three-dimensional vector.
Definition: Vector.hpp:209
static constexpr Vector< NumericType > Zero()
Statically creates a three-dimensional vector with its x, y, and z Cartesian components initialized t...
Definition: Vector.hpp:126
constexpr NumericType x() const noexcept
Returns this three-dimensional vector's x Cartesian component.
Definition: Vector.hpp:139
PhQ::Direction< NumericType > Direction() const
Returns the direction of this three-dimensional vector.
Definition: Direction.hpp:377
constexpr NumericType y() const noexcept
Returns this three-dimensional vector's y Cartesian component.
Definition: Vector.hpp:144
constexpr NumericType z() const noexcept
Returns this three-dimensional vector's z Cartesian component.
Definition: Vector.hpp:149
Three-dimensional Euclidean velocity vector. Contains three components in Cartesian coordinates: x,...
Definition: Velocity.hpp:55
Length
Length units.
Definition: Length.hpp:53
Frequency
Frequency units.
Definition: Frequency.hpp:53
Time
Time units.
Definition: Time.hpp:53
Namespace that encompasses all of the Physical Quantities library's content.
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 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
constexpr bool operator!=(const Acceleration< NumericType > &left, const Acceleration< NumericType > &right) noexcept
std::ostream & operator<<(std::ostream &stream, const Acceleration< NumericType > &acceleration)