NumCpp  2.10.1
A Templatized Header Only C++ Implementation of the Python NumPy Library
Coordinate.hpp
Go to the documentation of this file.
1 #pragma once
29 
30 #include <cmath>
31 #include <iostream>
32 #include <string>
33 
37 #include "NumCpp/Core/Types.hpp"
39 #include "NumCpp/Functions/dot.hpp"
41 #include "NumCpp/NdArray.hpp"
42 #include "NumCpp/Utils/sqr.hpp"
43 
44 namespace nc::coordinates
45 {
46  //================================================================================
48  class Coordinate
49  {
50  public:
51  //============================================================================
54  Coordinate() = default;
55 
56  //============================================================================
62  Coordinate(double inRaDegrees, double inDecDegrees) :
63  ra_(inRaDegrees),
64  dec_(inDecDegrees)
65  {
66  polarToCartesian();
67  }
68 
69  //============================================================================
80  Coordinate(uint8 inRaHours,
81  uint8 inRaMinutes,
82  double inRaSeconds,
83  Sign inSign,
84  uint8 inDecDegreesWhole,
85  uint8 inDecMinutes,
86  double inDecSeconds) :
87  ra_(inRaHours, inRaMinutes, inRaSeconds),
88  dec_(inSign, inDecDegreesWhole, inDecMinutes, inDecSeconds)
89  {
90  polarToCartesian();
91  }
92 
93  //============================================================================
99  Coordinate(const RA& inRA, const Dec& inDec) noexcept :
100  ra_(inRA),
101  dec_(inDec)
102  {
103  polarToCartesian();
104  }
105 
106  //============================================================================
113  Coordinate(double inX, double inY, double inZ) :
114  x_(inX),
115  y_(inY),
116  z_(inZ)
117  {
118  cartesianToPolar();
119  }
120 
121  //============================================================================
126  Coordinate(const NdArray<double>& inCartesianVector)
127  {
128  if (inCartesianVector.size() != 3)
129  {
130  THROW_INVALID_ARGUMENT_ERROR("NdArray input must be of length 3.");
131  }
132 
133  x_ = inCartesianVector[0];
134  y_ = inCartesianVector[1];
135  z_ = inCartesianVector[2];
136 
137  cartesianToPolar();
138  }
139 
140  //============================================================================
145  [[nodiscard]] const Dec& dec() const noexcept
146  {
147  return dec_;
148  }
149 
150  //============================================================================
155  [[nodiscard]] const RA& ra() const noexcept
156  {
157  return ra_;
158  }
159 
160  //============================================================================
165  [[nodiscard]] double x() const noexcept
166  {
167  return x_;
168  }
169 
170  //============================================================================
175  [[nodiscard]] double y() const noexcept
176  {
177  return y_;
178  }
179 
180  //============================================================================
185  [[nodiscard]] double z() const noexcept
186  {
187  return z_;
188  }
189 
190  //============================================================================
195  [[nodiscard]] NdArray<double> xyz() const
196  {
197  NdArray<double> out = { x_, y_, z_ };
198  return out;
199  }
200 
201  //============================================================================
208  [[nodiscard]] double degreeSeperation(const Coordinate& inOtherCoordinate) const
209  {
210  return rad2deg(radianSeperation(inOtherCoordinate));
211  }
212 
213  //============================================================================
221  [[nodiscard]] double degreeSeperation(const NdArray<double>& inVector) const
222  {
223  return rad2deg(radianSeperation(inVector));
224  }
225 
226  //============================================================================
233  [[nodiscard]] double radianSeperation(const Coordinate& inOtherCoordinate) const
234  {
235  return std::acos(dot(xyz(), inOtherCoordinate.xyz()).item());
236  }
237 
238  //============================================================================
246  [[nodiscard]] double radianSeperation(const NdArray<double>& inVector) const
247  {
248  if (inVector.size() != 3)
249  {
250  THROW_INVALID_ARGUMENT_ERROR("input vector must be of length 3.");
251  }
252 
253  return std::acos(dot(xyz(), inVector.flatten()).item());
254  }
255 
256  //============================================================================
261  [[nodiscard]] std::string str() const
262  {
263  std::string returnStr;
264  returnStr = ra_.str();
265  returnStr += dec_.str();
266  returnStr += "Cartesian = " + xyz().str();
267  return returnStr;
268  }
269 
270  //============================================================================
273  void print() const
274  {
275  std::cout << *this;
276  }
277 
278  //============================================================================
285  bool operator==(const Coordinate& inRhs) const noexcept
286  {
287  return ra_ == inRhs.ra_ && dec_ == inRhs.dec_;
288  }
289 
290  //============================================================================
297  bool operator!=(const Coordinate& inRhs) const noexcept
298  {
299  return !(*this == inRhs);
300  }
301 
302  //============================================================================
310  friend std::ostream& operator<<(std::ostream& inStream, const Coordinate& inCoord)
311  {
312  inStream << inCoord.str();
313  return inStream;
314  }
315 
316  private:
317  //====================================Attributes==============================
318  RA ra_{};
319  Dec dec_{};
320  double x_{ 1. };
321  double y_{ 0. };
322  double z_{ 0. };
323 
324  //============================================================================
327  void cartesianToPolar()
328  {
329  double degreesRa = rad2deg(std::atan2(y_, x_));
330  if (degreesRa < 0)
331  {
332  degreesRa += 360;
333  }
334  ra_ = RA(degreesRa);
335 
336  const double r = std::sqrt(utils::sqr(x_) + utils::sqr(y_) + utils::sqr(z_));
337  const double degreesDec = rad2deg(std::asin(z_ / r));
338  dec_ = Dec(degreesDec);
339  }
340 
341  //============================================================================
344  void polarToCartesian() noexcept
345  {
346  const double raRadians = deg2rad(ra_.degrees());
347  const double decRadians = deg2rad(dec_.degrees());
348 
349  x_ = std::cos(raRadians) * std::cos(decRadians);
350  y_ = std::sin(raRadians) * std::cos(decRadians);
351  z_ = std::sin(decRadians);
352  }
353  };
354 } // namespace nc::coordinates
#define THROW_INVALID_ARGUMENT_ERROR(msg)
Definition: Error.hpp:37
size_type size() const noexcept
Definition: NdArrayCore.hpp:4415
self_type flatten() const
Definition: NdArrayCore.hpp:2770
std::string str() const
Definition: NdArrayCore.hpp:4473
Holds a full coordinate object.
Definition: Coordinate.hpp:49
NdArray< double > xyz() const
Definition: Coordinate.hpp:195
std::string str() const
Definition: Coordinate.hpp:261
double radianSeperation(const Coordinate &inOtherCoordinate) const
Definition: Coordinate.hpp:233
double z() const noexcept
Definition: Coordinate.hpp:185
double degreeSeperation(const NdArray< double > &inVector) const
Definition: Coordinate.hpp:221
Coordinate(const NdArray< double > &inCartesianVector)
Definition: Coordinate.hpp:126
double y() const noexcept
Definition: Coordinate.hpp:175
Coordinate(uint8 inRaHours, uint8 inRaMinutes, double inRaSeconds, Sign inSign, uint8 inDecDegreesWhole, uint8 inDecMinutes, double inDecSeconds)
Definition: Coordinate.hpp:80
Coordinate(const RA &inRA, const Dec &inDec) noexcept
Definition: Coordinate.hpp:99
bool operator!=(const Coordinate &inRhs) const noexcept
Definition: Coordinate.hpp:297
bool operator==(const Coordinate &inRhs) const noexcept
Definition: Coordinate.hpp:285
Coordinate(double inRaDegrees, double inDecDegrees)
Definition: Coordinate.hpp:62
double degreeSeperation(const Coordinate &inOtherCoordinate) const
Definition: Coordinate.hpp:208
Coordinate(double inX, double inY, double inZ)
Definition: Coordinate.hpp:113
friend std::ostream & operator<<(std::ostream &inStream, const Coordinate &inCoord)
Definition: Coordinate.hpp:310
const Dec & dec() const noexcept
Definition: Coordinate.hpp:145
const RA & ra() const noexcept
Definition: Coordinate.hpp:155
double x() const noexcept
Definition: Coordinate.hpp:165
double radianSeperation(const NdArray< double > &inVector) const
Definition: Coordinate.hpp:246
void print() const
Definition: Coordinate.hpp:273
Holds a Declination object.
Definition: Dec.hpp:53
std::string str() const
Definition: Dec.hpp:168
double degrees() const noexcept
Definition: Dec.hpp:118
Holds a right ascension object.
Definition: RA.hpp:45
std::string str() const
Definition: RA.hpp:144
double degrees() const noexcept
Definition: RA.hpp:104
Definition: Coordinate.hpp:45
Sign
Struct Enum for positive or negative Dec angle.
Definition: Dec.hpp:45
constexpr dtype sqr(dtype inValue) noexcept
Definition: sqr.hpp:42
NdArray< dtype > dot(const NdArray< dtype > &inArray1, const NdArray< dtype > &inArray2)
Definition: dot.hpp:47
constexpr auto deg2rad(dtype inValue) noexcept
Definition: deg2rad.hpp:47
auto sin(dtype inValue) noexcept
Definition: sin.hpp:49
auto cos(dtype inValue) noexcept
Definition: cos.hpp:49
constexpr auto rad2deg(dtype inValue) noexcept
Definition: rad2deg.hpp:48
auto sqrt(dtype inValue) noexcept
Definition: sqrt.hpp:48
std::uint8_t uint8
Definition: Types.hpp:42