Angular separation, cartesian validation, and typed coordinate safety.
#include <cmath>
#include <iomanip>
#include <iostream>
using namespace qtty::literals;
int main() {
std::cout << std::fixed;
std::cout << "=== Siderust Coordinate Operations Example ===" << std::endl << std::endl;
std::cout << "1. ANGULAR SEPARATION (SPHERICAL DIRECTIONS)" << std::endl;
std::cout << "---------------------------------------------" << std::endl;
89.2641_deg
);
-16.7161_deg
);
std::cout << std::setprecision(4);
std::cout << "Polaris " << polaris << '\n';
std::cout << "Sirius " << sirius << '\n';
std::cout << " Angular separation = " << sep << "\n\n";
std::cout << "Nearby pair (0.5\u00b0 apart in both RA and Dec):" << std::endl;
std::cout << " Angular separation = " << close_sep << std::endl << std::endl;
std::cout << std::setprecision(6);
std::cout << "Self-separation of Polaris = " << self_sep << " (must be 0)" << std::endl
<< std::endl;
std::cout << "2. CROSS-VALIDATION: SPHERICAL vs. CARTESIAN" << std::endl;
std::cout << "---------------------------------------------" << std::endl;
double angle_rad = polaris_cart.angle_to(sirius_cart);
double angle_deg = angle_rad * 180.0 / constants::pi;
std::cout << std::setprecision(4);
std::cout << "Polaris cartesian: (" << polaris_cart.x << ", " << polaris_cart.y << ", "
<< polaris_cart.z << ")" << std::endl;
std::cout << "Sirius cartesian: (" << sirius_cart.x << ", " << sirius_cart.y << ", "
<< sirius_cart.z << ")" << std::endl;
std::cout << std::setprecision(6);
std::cout << " angle_to (Cartesian) = " << angle_rad
<< " rad = " << std::setprecision(4) << angle_deg << "\u00b0" << std::endl;
std::cout << " angular_separation (Vincenty) = " << sep << std::endl;
std::cout << std::scientific << std::setprecision(2);
std::cout << " Difference = " << std::abs(angle_deg - sep.value())
<< "\u00b0 (near machine epsilon)" << std::endl
<< std::endl;
std::cout << std::fixed;
std::cout << "3. DOT PRODUCT" << std::endl;
std::cout << "--------------" << std::endl;
std::cout << std::setprecision(6);
std::cout << "dot(North Pole, Equatorial point) = " << north_pole_c.dot(equatorial_c)
<< " (must be 0)" << std::endl;
qtty::Degree(-polaris.
dec().value()));
std::cout << "dot(Polaris, anti-Polaris) = " << polaris_cart.dot(anti_polaris_c)
<< " (must be -1)" << std::endl
<< std::endl;
std::cout << "4. EUCLIDEAN DISTANCE BETWEEN SPHERICAL POSITIONS" << std::endl;
std::cout << "--------------------------------------------------" << std::endl;
100.0_deg,
0.0_deg,
qtty::AstronomicalUnit(1.0)
);
200.0_deg,
2.0_deg,
qtty::AstronomicalUnit(1.524)
);
auto eu_dist = earth.distance_to(mars);
auto ang_sep_pos = earth.angular_separation(mars);
std::cout << std::setprecision(4);
std::cout << "Earth (lon=100\u00b0, lat=0\u00b0, r=1.000 AU)" << std::endl;
std::cout << "Mars (lon=200\u00b0, lat=2\u00b0, r=1.524 AU)" << std::endl;
std::cout << " Euclidean 3D distance = " << eu_dist << std::endl;
std::cout << " Angular separation = " << ang_sep_pos << std::endl << std::endl;
std::cout << "5. CARTESIAN POSITION OPERATIONS" << std::endl;
std::cout << "---------------------------------" << std::endl;
auto earth_cart = earth.to_cartesian();
auto mars_cart = mars.to_cartesian();
auto eu_dist_cart = earth_cart.distance_to(mars_cart);
std::cout << "Earth cartesian (AU): " << earth_cart << '\n';
std::cout << "Mars cartesian (AU): " << mars_cart << '\n';
std::cout << " Euclidean distance = " << eu_dist_cart << " (matches spherical)\n";
auto diff = mars_cart - earth_cart;
std::cout << " Mars \u2212 Earth vector: " << diff << '\n';
std::cout << " |Mars \u2212 Earth| = " << diff.magnitude() << "\n\n";
std::cout << "6. ECLIPTIC AND EQUATORIAL DIRECTIONS" << std::endl;
std::cout << "--------------------------------------" << std::endl;
std::cout << "Vernal Equinox \u2192 Summer Solstice ang. sep = "
<< std::endl;
std::cout << "Ecliptic North Pole \u2192 Vernal Equinox ang. sep = "
<< std::endl
<< std::endl;
std::cout << " Type safety note: spherical::direction::EclipticMeanJ2000 and" << std::endl;
std::cout << " spherical::direction::EquatorialMeanJ2000 are distinct types." << std::endl;
std::cout << " angular_separation only compiles within the same frame." << std::endl
<< std::endl;
std::cout << "=== Example Complete ===" << std::endl;
return 0;
}
Umbrella header for the siderust C++ wrapper library.
A direction on the celestial sphere, compile-time tagged by frame.
cartesian::Direction< F > to_cartesian() const
Convert this spherical direction to a Cartesian unit vector.
qtty::Degree angular_separation(const Direction &other) const
Angular separation between this direction and another.
A spherical position (direction + distance), compile-time tagged.