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