NumCpp  2.5.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 
33 #include "NumCpp/Core/Types.hpp"
35 #include "NumCpp/Functions/dot.hpp"
37 #include "NumCpp/NdArray.hpp"
38 #include "NumCpp/Utils/sqr.hpp"
39 
40 #include <cmath>
41 #include <iostream>
42 #include <string>
43 
44 namespace nc
45 {
46  namespace coordinates
47  {
48  //================================================================================
50  class Coordinate
51  {
52  public:
53  //============================================================================
56  Coordinate() = default;
57 
58  //============================================================================
64  Coordinate(double inRaDegrees, double inDecDegrees) :
65  ra_(inRaDegrees),
66  dec_(inDecDegrees)
67  {
68  polarToCartesian();
69  }
70 
71  //============================================================================
82  Coordinate(uint8 inRaHours, uint8 inRaMinutes, double inRaSeconds, Sign inSign,
83  uint8 inDecDegreesWhole, uint8 inDecMinutes, double inDecSeconds) :
84  ra_(inRaHours, inRaMinutes, inRaSeconds),
85  dec_(inSign, inDecDegreesWhole, inDecMinutes, inDecSeconds)
86  {
87  polarToCartesian();
88  }
89 
90  //============================================================================
96  Coordinate(const RA& inRA, const Dec& inDec) noexcept :
97  ra_(inRA),
98  dec_(inDec)
99  {
100  polarToCartesian();
101  }
102 
103  //============================================================================
110  Coordinate(double inX, double inY, double inZ) noexcept :
111  x_(inX),
112  y_(inY),
113  z_(inZ)
114  {
115  cartesianToPolar();
116  }
117 
118  //============================================================================
123  Coordinate(const NdArray<double>& inCartesianVector)
124  {
125  if (inCartesianVector.size() != 3)
126  {
127  THROW_INVALID_ARGUMENT_ERROR("NdArray input must be of length 3.");
128  }
129 
130  x_ = inCartesianVector[0];
131  y_ = inCartesianVector[1];
132  z_ = inCartesianVector[2];
133 
134  cartesianToPolar();
135  }
136 
137  //============================================================================
142  const Dec& dec() const noexcept
143  {
144  return dec_;
145  }
146 
147  //============================================================================
152  const RA& ra() const noexcept
153  {
154  return ra_;
155  }
156 
157  //============================================================================
162  double x() const noexcept
163  {
164  return x_;
165  }
166 
167  //============================================================================
172  double y() const noexcept
173  {
174  return y_;
175  }
176 
177  //============================================================================
182  double z() const noexcept
183  {
184  return z_;
185  }
186 
187  //============================================================================
193  {
194  NdArray<double> out = { x_, y_, z_ };
195  return out;
196  }
197 
198  //============================================================================
205  double degreeSeperation(const Coordinate& inOtherCoordinate) const
206  {
207  return rad2deg(radianSeperation(inOtherCoordinate));
208  }
209 
210  //============================================================================
218  double degreeSeperation(const NdArray<double>& inVector) const
219  {
220  return rad2deg(radianSeperation(inVector));
221  }
222 
223  //============================================================================
230  double radianSeperation(const Coordinate& inOtherCoordinate) const
231  {
232  return std::acos(dot(xyz(), inOtherCoordinate.xyz()).item());
233  }
234 
235  //============================================================================
243  double radianSeperation(const NdArray<double>& inVector) const
244  {
245  if (inVector.size() != 3)
246  {
247  THROW_INVALID_ARGUMENT_ERROR("input vector must be of length 3.");
248  }
249 
250  return std::acos(dot(xyz(), inVector.flatten()).item());
251  }
252 
253  //============================================================================
258  std::string str() const
259  {
260  std::string returnStr;
261  returnStr = ra_.str();
262  returnStr += dec_.str();
263  returnStr += "Cartesian = " + xyz().str();
264  return returnStr;
265  }
266 
267  //============================================================================
270  void print() const
271  {
272  std::cout << *this;
273  }
274 
275  //============================================================================
282  bool operator==(const Coordinate& inRhs) const noexcept
283  {
284  return ra_ == inRhs.ra_ && dec_ == inRhs.dec_;
285  }
286 
287  //============================================================================
294  bool operator!=(const Coordinate& inRhs) const noexcept
295  {
296  return !(*this == inRhs);
297  }
298 
299  //============================================================================
307  friend std::ostream& operator<<(std::ostream& inStream, const Coordinate& inCoord)
308  {
309  inStream << inCoord.str();
310  return inStream;
311  }
312 
313  private:
314  //====================================Attributes==============================
315  RA ra_{};
316  Dec dec_{};
317  double x_{ 1.0 };
318  double y_{ 0.0 };
319  double z_{ 0.0 };
320 
321  //============================================================================
324  void cartesianToPolar() noexcept
325  {
326  double degreesRa = rad2deg(std::atan2(y_, x_));
327  if (degreesRa < 0)
328  {
329  degreesRa += 360;
330  }
331  ra_ = RA(degreesRa);
332 
333  const double r = std::sqrt(utils::sqr(x_) + utils::sqr(y_) + utils::sqr(z_));
334  const double degreesDec = rad2deg(std::asin(z_ / r));
335  dec_ = Dec(degreesDec);
336  }
337 
338  //============================================================================
341  void polarToCartesian() noexcept
342  {
343  const double raRadians = deg2rad(ra_.degrees());
344  const double decRadians = deg2rad(dec_.degrees());
345 
346  x_ = std::cos(raRadians) * std::cos(decRadians);
347  y_ = std::sin(raRadians) * std::cos(decRadians);
348  z_ = std::sin(decRadians);
349  }
350  };
351  } // namespace coordinates
352 } // namespace nc
#define THROW_INVALID_ARGUMENT_ERROR(msg)
Definition: Error.hpp:36
size_type size() const noexcept
Definition: NdArrayCore.hpp:4497
NdArray< dtype > flatten() const
Definition: NdArrayCore.hpp:2919
std::string str() const
Definition: NdArrayCore.hpp:4560
Holds a full coordinate object.
Definition: Coordinate.hpp:51
NdArray< double > xyz() const
Definition: Coordinate.hpp:192
std::string str() const
Definition: Coordinate.hpp:258
double radianSeperation(const Coordinate &inOtherCoordinate) const
Definition: Coordinate.hpp:230
double z() const noexcept
Definition: Coordinate.hpp:182
double degreeSeperation(const NdArray< double > &inVector) const
Definition: Coordinate.hpp:218
Coordinate(const NdArray< double > &inCartesianVector)
Definition: Coordinate.hpp:123
double y() const noexcept
Definition: Coordinate.hpp:172
Coordinate(uint8 inRaHours, uint8 inRaMinutes, double inRaSeconds, Sign inSign, uint8 inDecDegreesWhole, uint8 inDecMinutes, double inDecSeconds)
Definition: Coordinate.hpp:82
Coordinate(const RA &inRA, const Dec &inDec) noexcept
Definition: Coordinate.hpp:96
bool operator!=(const Coordinate &inRhs) const noexcept
Definition: Coordinate.hpp:294
bool operator==(const Coordinate &inRhs) const noexcept
Definition: Coordinate.hpp:282
Coordinate(double inRaDegrees, double inDecDegrees)
Definition: Coordinate.hpp:64
double degreeSeperation(const Coordinate &inOtherCoordinate) const
Definition: Coordinate.hpp:205
Coordinate(double inX, double inY, double inZ) noexcept
Definition: Coordinate.hpp:110
friend std::ostream & operator<<(std::ostream &inStream, const Coordinate &inCoord)
Definition: Coordinate.hpp:307
const Dec & dec() const noexcept
Definition: Coordinate.hpp:142
const RA & ra() const noexcept
Definition: Coordinate.hpp:152
double x() const noexcept
Definition: Coordinate.hpp:162
double radianSeperation(const NdArray< double > &inVector) const
Definition: Coordinate.hpp:243
void print() const
Definition: Coordinate.hpp:270
Holds a Declination object.
Definition: Dec.hpp:51
std::string str() const
Definition: Dec.hpp:166
double degrees() const noexcept
Definition: Dec.hpp:116
Holds a right ascension object.
Definition: RA.hpp:47
std::string str() const
Definition: RA.hpp:145
double degrees() const noexcept
Definition: RA.hpp:105
Sign
Struct Enum for positive or negative Dec angle.
Definition: Dec.hpp:46
constexpr dtype sqr(dtype inValue) noexcept
Definition: sqr.hpp:44
Definition: Coordinate.hpp:45
NdArray< dtype > dot(const NdArray< dtype > &inArray1, const NdArray< dtype > &inArray2)
Definition: dot.hpp:47
constexpr auto deg2rad(dtype inValue) noexcept
Definition: deg2rad.hpp:49
auto sin(dtype inValue) noexcept
Definition: sin.hpp:51
auto cos(dtype inValue) noexcept
Definition: cos.hpp:51
constexpr auto rad2deg(dtype inValue) noexcept
Definition: rad2deg.hpp:50
auto sqrt(dtype inValue) noexcept
Definition: sqrt.hpp:50
std::uint8_t uint8
Definition: Types.hpp:42