diff --git a/include/boost/astronomy/coordinate/conversion/conversion_graph.hpp b/include/boost/astronomy/coordinate/conversion/conversion_graph.hpp new file mode 100644 index 00000000..f9909e26 --- /dev/null +++ b/include/boost/astronomy/coordinate/conversion/conversion_graph.hpp @@ -0,0 +1,125 @@ +/*============================================================================= +Copyright 2020 Syed Ali Hasan + +Distributed under the Boost Software License, Version 1.0. (See accompanying +file License.txt or copy at https://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ + +#include +#include + +//Graph +#include +#include +#include +#include +#include + +//Matrix +#include +#include +#include + +//Angle +#include +#include +#include + +namespace bu = boost::units; +namespace bg = boost::geometry; +namespace bac = boost::astronomy::coordinate; + +using namespace boost::units; +using namespace boost::units::si; +using namespace boost::astronomy::coordinate; + +enum class COORDINATE_SYSTEM { + HORIZON, + EQUATORIAL_HA_DEC, + EQUATORIAL_RA_DEC, + ECLIPTIC, + GALACTIC}; + +struct CoordinateData +{ + COORDINATE_SYSTEM coordinate_system; + std::string coordinate_name; +}; + +struct EdgeData +{ + std::string edge_label; + matrix conv_matrix; +}; + +using graph_t = boost::adjacency_list; + +using vertex_t = boost::graph_traits::vertex_descriptor; + +template +< + typename CoordinateType = double, + typename Angle = bu::quantity +> +matrix convert(const COORDINATE_SYSTEM src, + const COORDINATE_SYSTEM dest, + const Angle& phi, + const Angle& st, + const Angle& obliquity, + coord_sys<2, bg::cs::spherical, CoordinateType> source_coordinate) +{ + bac::column_vector, + double> + col_vec(bg::get<0>(source_coordinate.get_point()) * radians, bg::get<1>(source_coordinate.get_point()) * radians); + + graph_t G; + + const int graph_size = 5; + + vertex_t vd0 = boost::add_vertex(CoordinateData{COORDINATE_SYSTEM::HORIZON,"Horizon"}, G); + vertex_t vd1 = boost::add_vertex(CoordinateData{COORDINATE_SYSTEM::EQUATORIAL_HA_DEC,"Equatorial_HA_Dec"}, G); + vertex_t vd2 = boost::add_vertex(CoordinateData{COORDINATE_SYSTEM::EQUATORIAL_RA_DEC,"Equatorial_RA_Dec"}, G); + vertex_t vd3 = boost::add_vertex(CoordinateData{COORDINATE_SYSTEM::ECLIPTIC,"Ecliptic"}, G); + vertex_t vd4 = boost::add_vertex(CoordinateData{COORDINATE_SYSTEM::GALACTIC,"Galactic"}, G); + + boost::add_edge(vd0, vd1, EdgeData{"Horizon to Equatorial HA Dec", bac::ha_dec_horizon, double>(phi).get()}, G); + boost::add_edge(vd1, vd0, EdgeData{"Equatorial HA Dec to Horizon", bac::ha_dec_horizon, double>(phi).get()}, G); + boost::add_edge(vd1, vd2, EdgeData{"Equatorial HA Dec to Equatorial RA Dec", bac::ha_dec_ra_dec, double>(st).get()}, G); + boost::add_edge(vd2, vd1, EdgeData{"Equatorial RA Dec to Equatorial HA Dec", bac::ha_dec_ra_dec, double>(st).get()}, G); + boost::add_edge(vd2, vd3, EdgeData{"Equatorial RA Dec to Ecliptic", bac::ra_dec_to_ecliptic, double>(obliquity).get()}, G); + boost::add_edge(vd3, vd2, EdgeData{"Ecliptic to Equatorial RA Dec", bac::ecliptic_to_ra_dec, double>(obliquity).get()}, G); + boost::add_edge(vd2, vd4, EdgeData{"Equatorial RA Dec to Galactic", bac::ra_dec_to_galactic().get()}, G); + boost::add_edge(vd4, vd2, EdgeData{"Galactic to Equatorial RA Dec", bac::galactic_to_ra_dec().get()}, G); + + //Predecessor Array + boost::array predecessors{0}; + predecessors[(int)src] = (int)src; + + boost::breadth_first_search(G, (int)src, boost::visitor( + boost::make_bfs_visitor( + boost::record_predecessors(predecessors.begin(), + boost::on_tree_edge{})))); + + //Get traversed path + std::vector store_path; + + int p = (int)dest; + while (p != (int)src) + { + store_path.push_back(p); + p = predecessors[p]; + } + store_path.push_back(p); + + matrix ans = col_vec.get(); + + //Matrix Multiplication + for(auto it = store_path.rbegin(); it + 1 != store_path.rend(); ++it) + ans = prod(G[boost::edge(*it,*(it+1),G).first].conv_matrix, ans); + + return ans; +} \ No newline at end of file diff --git a/include/boost/astronomy/coordinate/conversion/graph.png b/include/boost/astronomy/coordinate/conversion/graph.png new file mode 100644 index 00000000..2a86904d Binary files /dev/null and b/include/boost/astronomy/coordinate/conversion/graph.png differ diff --git a/include/boost/astronomy/time/time_conversions.hpp b/include/boost/astronomy/time/time_conversions.hpp index b164263d..2e19ed8c 100644 --- a/include/boost/astronomy/time/time_conversions.hpp +++ b/include/boost/astronomy/time/time_conversions.hpp @@ -66,36 +66,49 @@ decimal_hour GST(ptime t) enum class DIRECTION {WEST, EAST}; +decimal_hour compute_LST(double longitude, DIRECTION direction, double gst) +{ + //Convert longitude to hours + double long_hours = longitude / 15.0; + + switch(direction) + { + case DIRECTION::WEST: + //Multiply with direction + long_hours = -1 * long_hours; + break; + case DIRECTION::EAST: + //Multiply with direction + long_hours = 1 * long_hours; + break; + } + + long_hours = long_hours + gst; + + //Bring the result into the range 0 to 24 by adding or subtracting 24 if necessary. + //This is the local sidereal time (LST). + long_hours = long_hours - 24.0 * floor(long_hours/24.0); + + return {long_hours}; +} + //Local Sidereal Time (LST) decimal_hour LST(double longitude, DIRECTION direction, ptime t) { double gst = GST(t).get(); - if(longitude == 0) - return {gst}; - - //Convert longitude to hours - double long_hours = longitude / 15.0; + if(longitude == 0) + return {gst}; - switch(direction) - { - case DIRECTION::WEST: - //Multiply with direction - long_hours = -1 * long_hours; - break; - case DIRECTION::EAST: - //Multiply with direction - long_hours = 1 * long_hours; - break; - } - - long_hours = long_hours + gst; + return compute_LST(longitude,direction,gst); +} - //Bring the result into the range 0 to 24 by adding or subtracting 24 if necessary. - //This is the local sidereal time (LST). - long_hours = long_hours - 24.0 * floor(long_hours/24.0); +decimal_hour LST(double longitude, DIRECTION direction, double gst) +{ + if(longitude == 0) + return {gst}; - return {long_hours}; + return compute_LST(longitude,direction,gst); } #endif //BOOST_ASTRONOMY_TIME_CONVERSIONS diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index f4fe0345..e0cab8b9 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -7,3 +7,6 @@ add_subdirectory(units) add_subdirectory(time) add_subdirectory(io) + +add_subdirectory(conversion) + diff --git a/test/Jamfile b/test/Jamfile index bcd82786..17fe7fa1 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -12,3 +12,7 @@ build-project header ; build-project coordinate ; build-project units ; build-project io ; +build-project time ; +build-project conversion ; + + diff --git a/test/conversion/CMakeLists.txt b/test/conversion/CMakeLists.txt new file mode 100644 index 00000000..6d22c20d --- /dev/null +++ b/test/conversion/CMakeLists.txt @@ -0,0 +1,16 @@ +foreach(_name + conversion_graph) + set(_target test_coordinate_${_name}) + + add_executable(${_target} "") + target_sources(${_target} PRIVATE ${_name}.cpp) + target_link_libraries(${_target} + PRIVATE + astronomy_compile_options + astronomy_include_directories + astronomy_dependencies) + add_test(NAME test.astro.${_name} COMMAND ${_target}) + + unset(_name) + unset(_target) +endforeach() diff --git a/test/conversion/Jamfile b/test/conversion/Jamfile new file mode 100644 index 00000000..9b3c1a2a --- /dev/null +++ b/test/conversion/Jamfile @@ -0,0 +1,3 @@ +import testing ; + +run conversion_graph.cpp ; diff --git a/test/conversion/conversion_graph.cpp b/test/conversion/conversion_graph.cpp new file mode 100644 index 00000000..b9bb9717 --- /dev/null +++ b/test/conversion/conversion_graph.cpp @@ -0,0 +1,72 @@ +/*============================================================================= +Copyright 2020 Syed Ali Hasan + +Distributed under the Boost Software License, Version 1.0. (See accompanying +file License.txt or copy at https://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ + +#define BOOST_TEST_MODULE conversion_graph + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include + +using namespace boost::units; +using namespace boost::units::si; +using namespace boost::astronomy::coordinate; + +namespace bud = boost::units::degree; +namespace bac = boost::astronomy::coordinate; + +BOOST_AUTO_TEST_SUITE(conversion_graph) + +BOOST_AUTO_TEST_CASE(ecliptic_to_horizon) { + + ecliptic_coord, quantity> + ec(97.638119 * bud::degrees, -17.857969 * bud::degrees); + + quantity phi = 52.175 * bud::degree; + quantity st = 77.337 * bud::degree; + quantity obliquity = 23.446 * bud::degree; + + matrix ans = convert(COORDINATE_SYSTEM::ECLIPTIC,COORDINATE_SYSTEM::HORIZON,phi,st,obliquity,ec); + + auto theta = bac::extract_coordinates(ans).get_coordinates().first; + auto gama = bac::extract_coordinates(ans).get_coordinates().second; + + BOOST_CHECK_CLOSE(theta.value() * 180.0 / PI, 153.491944, 0.001); + BOOST_CHECK_CLOSE(gama.value() * 180.0 / PI, 40.399444, 0.001); +} + +BOOST_AUTO_TEST_CASE(horizon_to_ecliptic) { + + horizon_coord, quantity> + hc(153.491944 * bud::degrees, 40.399444 * bud::degrees); + + quantity phi = 52.175 * bud::degree; + quantity st = 77.337 * bud::degree; + quantity obliquity = 23.446 * bud::degree; + + matrix ans = convert(COORDINATE_SYSTEM::HORIZON,COORDINATE_SYSTEM::ECLIPTIC,phi,st,obliquity,hc); + + auto theta = bac::extract_coordinates(ans).get_coordinates().first; + auto gama = bac::extract_coordinates(ans).get_coordinates().second; + + BOOST_CHECK_CLOSE(theta.value() * 180.0 / PI, 97.638119 , 0.001); + BOOST_CHECK_CLOSE(gama.value() * 180.0 / PI, -17.857969, 0.001); +} + +BOOST_AUTO_TEST_SUITE_END() +