/*
* Copyright (C) 2021 Christopher J. Howard
*
* This file is part of Antkeeper source code.
*
* Antkeeper source code is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Antkeeper source code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Antkeeper source code. If not, see .
*/
#ifndef ANTKEEPER_PHYSICS_ORBIT_FRAMES_HPP
#define ANTKEEPER_PHYSICS_ORBIT_FRAMES_HPP
#include "physics/frame.hpp"
namespace physics {
namespace orbit {
/// Inertial right-handed coordinate system
namespace inertial {
/**
* Constucts a reference frame which transforms coordinates from inertial space into perifocal space.
*
* @param focus Cartesian coordinates of the focus of the orbit, in the parent space.
* @param raan Right ascension of the ascending node (OMEGA), in radians.
* @param i Orbital inclination (i), in radians.
* @param w Argument of periapsis (omega), in radians.
* @return Perifocal frame.
*/
template
physics::frame to_perifocal(const math::vector3& focus, T raan, T i, T w)
{
const math::quaternion rotation = math::normalize
(
math::quaternion::rotate_z(raan) *
math::quaternion::rotate_x(i) *
math::quaternion::rotate_z(w)
);
return physics::frame{focus, rotation}.inverse();
}
/**
* Constructs a reference frame which transforms coordinates from inertial space to body-centered inertial space.
*
* @param r Cartesian position vector (r) of the center of the body, in inertial space.
* @param i Orbital inclination (i), in radians.
* @param axial_tilt Angle between the body's rotational axis and its orbital axis, in radians.
* @return Body-centered inertial frame.
*/
template
physics::frame to_bci(const math::vector3& r, T i, T axial_tilt)
{
return physics::frame{r, math::quaternion::rotate_x(-axial_tilt - i)}.inverse();
}
/**
* Constructs a reference frame which transforms coordinates from inertial space to body-centered, body-fixed space.
*
* @param r Cartesian position vector (r) of the center of the body, in inertial space.
* @param i Orbital inclination (i), in radians.
* @param axial_tilt Angle between the orbiting body's rotational axis and its orbital axis, in radians.
* @param axial_rotation Angle of rotation about the orbiting body's rotational axis, in radians.
*/
template
frame to_bcbf(const math::vector3& r, T i, T axial_tilt, T axial_rotation)
{
const math::quaternion rotation = math::normalize
(
math::quaternion::rotate_x(-axial_tilt - i) *
math::quaternion::rotate_z(axial_rotation)
);
return physics::frame{r, rotation}.inverse();
}
} // namespace inertial
/// Perifocal right-handed coordinate system in which the x-axis points toward the periapsis of the orbit, the y-axis has a true anomaly of 90 degrees past the periapsis, and the z-axis is the angular momentum vector, which is orthogonal to the orbital plane.
namespace perifocal {
} // namespace perifocal
/// Non-inertial body-centered, body-fixed right-handed coordinate system. The x-axis is orthogonal to the intersection of the prime meridian and the equator. The z-axis points toward the positive pole. The y-axis is right-hand orthogonal to the xz-plane.
namespace bcbf {
/**
* Constructs a reference frame which transforms coordinates from BCBF space to topocentric space.
*
* @param distance Radial distance of the observer from the center of the body.
* @param latitude Latitude of the observer, in radians.
* @param longitude Longitude of the obserer, in radians.
* @return Topocentric frame.
*/
template
physics::frame to_topocentric(T distance, T latitude, T longitude)
{
const math::vector3 translation = {T(0), T(0), distance};
const math::quaternion rotation = math::normalize
(
math::quaternion::rotate_z(longitude) *
math::quaternion::rotate_y(math::half_pi - latitude)
);
return physics::frame{rotation * translation, rotation}.inverse();
}
} // namespace bcbf
/// Non-inertial topocentric right-handed coordinate system. Topocentric frames are constructed as south-east-zenith (SEZ) frames; the x-axis points south, the y-axis points east, and the z-axis points toward the zenith (orthogonal to reference spheroid).
namespace topocentric {
} // namespace topocentric
} // namespace orbit
} // namespace physics
#endif // ANTKEEPER_PHYSICS_ORBIT_FRAMES_HPP