Antkeeper  0.0.1
frame.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2023 Christopher J. Howard
3  *
4  * This file is part of Antkeeper source code.
5  *
6  * Antkeeper source code is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Antkeeper source code is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef ANTKEEPER_PHYSICS_ORBIT_FRAME_HPP
21 #define ANTKEEPER_PHYSICS_ORBIT_FRAME_HPP
22 
23 #include <engine/math/se3.hpp>
24 #include <cmath>
25 
26 namespace physics {
27 namespace orbit {
28 
30 namespace frame {
31 
33 namespace pqw {
34 
41  template <class T>
43  {
44  const T xx_yy = v.x() * v.x() + v.y() * v.y();
45 
46  return math::vec3<T>
47  {
48  std::sqrt(xx_yy + v.z() * v.z()),
49  std::atan2(v.z(), std::sqrt(xx_yy)),
50  std::atan2(v.y(), v.x())
51  };
52  }
53 
63  template <class T>
64  math::vec3<T> spherical(T ec, T a, T ea, T b)
65  {
66  const T x = a * (std::cos(ea) - ec);
67  const T y = b * std::sin(ea);
68  const T d = std::sqrt(x * x + y * y);
69  const T ta = std::atan2(y, x);
70 
71  return math::vec3<T>{d, T(0), ta};
72  }
73 
82  template <class T>
83  math::vec3<T> spherical(T ec, T a, T ea)
84  {
85  const T b = a * std::sqrt(T(1) - ec * ec);
86  return spherical<T>(ec, a, ea, b);
87  }
88 
95  template <class T>
97  {
98  const T x = v[0] * std::cos(v[1]);
99 
100  return math::vec3<T>
101  {
102  x * std::cos(v[2]),
103  x * std::sin(v[2]),
104  v[0] * std::sin(v[1]),
105  };
106  }
107 
117  template <class T>
118  math::vec3<T> cartesian(T ec, T a, T ea, T b)
119  {
120  return cartesian<T>(spherical<T>(ec, a, ea, b));
121  }
122 
131  template <class T>
132  math::vec3<T> cartesian(T ec, T a, T ea)
133  {
134  return cartesian<T>(spherical<T>(ec, a, ea));
135  }
136 
145  template <typename T>
146  math::se3<T> to_bci(T om, T in, T w)
147  {
149  (
153  );
154 
155  return math::se3<T>{{T(0), T(0), T(0)}, r};
156  }
157 
158 } // namespace pqw
159 
161 namespace bci {
162 
169  template <class T>
171  {
172  const T x = v[0] * std::cos(v[1]);
173 
174  return math::vec3<T>
175  {
176  x * std::cos(v[2]),
177  x * std::sin(v[2]),
178  v[0] * std::sin(v[1]),
179  };
180  }
181 
188  template <class T>
190  {
191  const T xx_yy = v.x() * v.x() + v.y() * v.y();
192 
193  return math::vec3<T>
194  {
195  std::sqrt(xx_yy + v.z() * v.z()),
196  std::atan2(v.z(), std::sqrt(xx_yy)),
197  std::atan2(v.y(), v.x())
198  };
199  }
200 
212  template <typename T>
213  math::se3<T> to_bcbf(T ra, T dec, T w)
214  {
216  (
217  math::quaternion<T>::rotate_z(-math::half_pi<T> - ra) *
218  math::quaternion<T>::rotate_x(dec - math::half_pi<T>) *
220  );
221 
222  return math::se3<T>{{T(0), T(0), T(0)}, r};
223  }
224 
233  template <typename T>
234  math::se3<T> to_pqw(T om, T in, T w)
235  {
237  (
241  );
242 
243  return math::se3<T>{{T(0), T(0), T(0)}, r};
244  }
245 
246 } // namespace bci
247 
249 namespace bcbf {
250 
257  template <class T>
259  {
260  const T x = v[0] * std::cos(v[1]);
261 
262  return math::vec3<T>
263  {
264  x * std::cos(v[2]),
265  x * std::sin(v[2]),
266  v[0] * std::sin(v[1]),
267  };
268  }
269 
276  template <class T>
278  {
279  const T xx_yy = v.x() * v.x() + v.y() * v.y();
280 
281  return math::vec3<T>
282  {
283  std::sqrt(xx_yy + v.z() * v.z()),
284  std::atan2(v.z(), std::sqrt(xx_yy)),
285  std::atan2(v.y(), v.x())
286  };
287  }
288 
300  template <typename T>
301  math::se3<T> to_bci(T ra, T dec, T w)
302  {
304  (
306  math::quaternion<T>::rotate_x(math::half_pi<T> - dec) *
307  math::quaternion<T>::rotate_z(ra + math::half_pi<T>)
308 
309  );
310 
311  return math::se3<T>{{T(0), T(0), T(0)}, r};
312  }
313 
322  template <typename T>
323  math::se3<T> to_enu(T distance, T latitude, T longitude)
324  {
325  const math::vec3<T> t = {T(0), T(0), -distance};
327  (
328  math::quaternion<T>::rotate_x(-math::half_pi<T> + latitude) *
329  math::quaternion<T>::rotate_z(-longitude - math::half_pi<T>)
330  );
331 
332  return math::se3<T>{t, r};
333  }
334 
335 } // namespace bcbf
336 
338 namespace enu {
339 
346  template <class T>
348  {
349  const T x = v[0] * std::cos(v[1]);
350  const T y = math::half_pi<T> - v[2];
351 
352  return math::vec3<T>
353  {
354  x * std::cos(y),
355  x * std::sin(y),
356  v[0] * std::sin(v[1]),
357  };
358  }
359 
366  template <class T>
368  {
369  const T xx_yy = v.x() * v.x() + v.y() * v.y();
370 
371  return math::vec3<T>
372  {
373  std::sqrt(xx_yy + v.z() * v.z()),
374  std::atan2(v.z(), std::sqrt(xx_yy)),
375  math::half_pi<T> - std::atan2(v.y(), v.x())
376  };
377  }
378 
387  template <typename T>
388  math::se3<T> to_bcbf(T distance, T latitude, T longitude)
389  {
390  const math::vec3<T> t = {T(0), T(0), distance};
392  (
393  math::quaternion<T>::rotate_z(longitude + math::half_pi<T>) *
394  math::quaternion<T>::rotate_x(math::half_pi<T> - latitude)
395  );
396 
397  return math::se3<T>{r * t, r};
398  }
399 
400 } // namespace enu
401 
402 } // namespace frame
403 } // namespace orbit
404 } // namespace physics
405 
406 #endif // ANTKEEPER_PHYSICS_ORBIT_FRAME_HPP
quaternion< T > normalize(const quaternion< T > &q)
Normalizes a quaternion.
Definition: quaternion.hpp:679
T distance(const vector< T, N > &p0, const vector< T, N > &p1)
Calculates the distance between two points.
Definition: vector.hpp:1106
vector< T, N > sqrt(const vector< T, N > &x)
Takes the square root of each element.
math::se3< T > to_bci(T ra, T dec, T w)
Constructs an SE(3) transformation from a BCBF frame to a BCI frame.
Definition: frame.hpp:301
math::vec3< T > cartesian(const math::vec3< T > &v)
Converts BCBF coordinates from spherical to Cartesian.
Definition: frame.hpp:258
math::vec3< T > spherical(const math::vec3< T > &v)
Converts BCBF coordinates from Cartesian to spherical.
Definition: frame.hpp:277
math::se3< T > to_enu(T distance, T latitude, T longitude)
Constructs an SE(3) transformation from a BCBF frame to an ENU frame.
Definition: frame.hpp:323
math::se3< T > to_pqw(T om, T in, T w)
Constructs an SE(3) transformation from a BCI frame to a PQW frame.
Definition: frame.hpp:234
math::se3< T > to_bcbf(T ra, T dec, T w)
Constructs an SE(3) transformation from a BCI frame to a BCBF frame.
Definition: frame.hpp:213
math::vec3< T > cartesian(const math::vec3< T > &v)
Converts BCI coordinates from spherical to Cartesian.
Definition: frame.hpp:170
math::vec3< T > spherical(const math::vec3< T > &v)
Converts BCI coordinates from Cartesian to spherical.
Definition: frame.hpp:189
math::vec3< T > spherical(const math::vec3< T > &v)
Converts ENU coordinates from Cartesian to spherical.
Definition: frame.hpp:367
math::se3< T > to_bcbf(T distance, T latitude, T longitude)
Constructs an SE(3) transformation from an ENU frame to a BCBF frame.
Definition: frame.hpp:388
math::vec3< T > cartesian(const math::vec3< T > &v)
Converts ENU coordinates from spherical to Cartesian.
Definition: frame.hpp:347
math::vec3< T > spherical(const math::vec3< T > &v)
Converts PQW coordinates from Cartesian to spherical.
Definition: frame.hpp:42
math::vec3< T > cartesian(const math::vec3< T > &v)
Converts PQW coordinates from spherical to Cartesian.
Definition: frame.hpp:96
math::se3< T > to_bci(T om, T in, T w)
Constructs an SE(3) transformation from a PQW frame to a BCI frame.
Definition: frame.hpp:146
Physics.
Definition: constants.hpp:23
Quaternion composed of a real scalar part and imaginary vector part.
Definition: quaternion.hpp:39
SE(3) proper rigid transformation (rototranslation).
Definition: se3.hpp:35
n-dimensional vector.
Definition: vector.hpp:44