diff --git a/include/boost/astronomy/coordinate/arithmetic.hpp b/include/boost/astronomy/coordinate/arithmetic.hpp index 10e7bc78..5c0f5f31 100644 --- a/include/boost/astronomy/coordinate/arithmetic.hpp +++ b/include/boost/astronomy/coordinate/arithmetic.hpp @@ -252,6 +252,25 @@ auto unit_vector(Coordinate const& vector) return tempVector; } +//! Returns unit vector directing from representation2 to representation1 +template +Representation1 unit_vector +( + Representation1 const& representation1, + Representation2 const& representation2 +) +{ + /*!first difference of both representation gets calaculated + then unit_vector of difference vector and further unit_vector + is returned into requested type*/ + + auto diff = difference(representation1,representation2); + + //calculating unit_vector towards vector diff + + auto result = unit_vector(diff); + return Representation1(result); +} //! Returns sum of representation1 and representation2 template @@ -310,6 +329,62 @@ Representation1 sum return Representation1(result); } +//! Returns difference of representation1 and representation2 (difference vector towards representation1) +template +Representation1 difference +( + Representation1 const& representation1, + Representation2 const& representation2 +) +{ + /*!both the coordinates/vector are first converted into + cartesian coordinate system then difference of cartesian + vectors is converted into the type of first argument and returned*/ + + /*checking types if it is not subclass of + base_representaion then compile time erorr is generated*/ + //BOOST_STATIC_ASSERT_MSG((boost::astronomy::detail::is_base_template_of + // < + // boost::astronomy::coordinate::base_representation, + // Representation1 + // >::value), + // "First argument type is expected to be a representation class"); + //BOOST_STATIC_ASSERT_MSG((boost::astronomy::detail::is_base_template_of + // < + // boost::astronomy::coordinate::base_representation, + // Representation2 + // >::value), + // "Second argument type is expected to be a representation class"); + + /*converting both coordinates/vector into cartesian system*/ + bg::model::point + < + typename std::conditional + < + sizeof(typename Representation2::type) >= + sizeof(typename Representation1::type), + typename Representation2::type, + typename Representation1::type + >::type, + 3, + bg::cs::cartesian + > result; + + auto cartesian1 = make_cartesian_representation(representation1); + auto cartesian2 = make_cartesian_representation(representation2); + + typedef decltype(cartesian1) cartesian1_type; + + //performing calculation to find the sum + bg::set<0>(result, (cartesian1.get_x().value() - + static_cast(cartesian2.get_x()).value())); + bg::set<1>(result, (cartesian1.get_y().value() - + static_cast(cartesian2.get_y()).value())); + bg::set<2>(result, (cartesian1.get_z().value() - + static_cast(cartesian2.get_z()).value())); + + return Representation1(result); +} //! Returns mean of representation1 and representation2 template diff --git a/test/coordinate/cartesian_representation.cpp b/test/coordinate/cartesian_representation.cpp index ebee416a..627fe4c9 100644 --- a/test/coordinate/cartesian_representation.cpp +++ b/test/coordinate/cartesian_representation.cpp @@ -254,6 +254,23 @@ BOOST_AUTO_TEST_CASE(cartesian_representation_unit_vector) BOOST_TEST((std::is_same>::value)); } +BOOST_AUTO_TEST_CASE(cartesian_representation_two_point_unit_vector) +{ + auto point1 = make_cartesian_representation(25.0*meter, 36.0*meter, 90.0*meter); + auto point2 = make_cartesian_representation(24.0*meter,35.0*meter,89.0*meter); + + auto result = boost::astronomy::coordinate::unit_vector(point1,point2); + + BOOST_CHECK_CLOSE(result.get_x().value(), 0.5773502691896258, 0.001); + BOOST_CHECK_CLOSE(result.get_y().value(), 0.5773502691896258, 0.001); + BOOST_CHECK_CLOSE(result.get_z().value(), 0.5773502691896258, 0.001); + + //checking whether quantity stored is as expected or not + BOOST_TEST((std::is_same>::value)); + BOOST_TEST((std::is_same>::value)); + BOOST_TEST((std::is_same>::value)); +} + BOOST_AUTO_TEST_CASE(cartesian_representation_magnitude) { auto point1 = make_cartesian_representation @@ -287,6 +304,25 @@ BOOST_AUTO_TEST_CASE(cartesian_representation_sum) BOOST_TEST((std::is_same>::value)); } +BOOST_AUTO_TEST_CASE(cartesian_representation_difference) +{ + auto point1 = make_cartesian_representation + (10.0 * meter, 20.0 * si::kilo * meters, 30.0 * meter); + auto point2 = make_cartesian_representation + (50.0 * si::centi * meter, 60.0 * meter, 30.0 * meter); + + auto result = boost::astronomy::coordinate::difference(point1, point2); + + BOOST_CHECK_CLOSE(result.get_x().value(), 9.5, 0.001); + BOOST_CHECK_CLOSE(result.get_y().value(), 19.94, 0.001); + BOOST_CHECK_CLOSE(result.get_z().value(), 0, 0.001); + + //checking whether quantity stored is as expected or not + BOOST_TEST((std::is_same>::value)); + BOOST_TEST((std::is_same>::value)); + BOOST_TEST((std::is_same>::value)); +} + BOOST_AUTO_TEST_CASE(cartesian_representation_mean) { auto point1 = make_cartesian_representation diff --git a/test/coordinate/spherical_equatorial_representation.cpp b/test/coordinate/spherical_equatorial_representation.cpp index 3e5bb5ca..06710e46 100644 --- a/test/coordinate/spherical_equatorial_representation.cpp +++ b/test/coordinate/spherical_equatorial_representation.cpp @@ -246,6 +246,22 @@ BOOST_AUTO_TEST_CASE(spherical_equatorial_representation_unit_vector) BOOST_TEST((std::is_same>::value)); } +BOOST_AUTO_TEST_CASE(spherical_equatorial_representation_two_point_unit_vector) +{ + auto point1 = make_spherical_equatorial_representation(25.0 * bud::degrees, 30.0 * bud::degrees, 90.0*meter); + auto point2 = make_spherical_equatorial_representation(30.0 * bud::degrees, 35.0 * bud::degrees, 90.0*meter); + auto result = boost::astronomy::coordinate::unit_vector(point1,point2); + + BOOST_CHECK_CLOSE(result.get_lat().value(), -30.0, 0.001); + BOOST_CHECK_CLOSE(result.get_lon().value(), -40.1709, 0.001); + BOOST_CHECK_CLOSE(result.get_dist().value(), 1, 0.001); + + //checking whether quantity stored is as expected or not + BOOST_TEST((std::is_same>::value)); + BOOST_TEST((std::is_same>::value)); + BOOST_TEST((std::is_same>::value)); +} + BOOST_AUTO_TEST_CASE(spherical_equatorial_representation_magnitude) { auto point1 = make_spherical_equatorial_representation(25.0 * bud::degrees, 36.0 * bud::degrees, 9.0 * meters); @@ -276,6 +292,23 @@ BOOST_AUTO_TEST_CASE(spherical_equatorial_representation_sum) BOOST_TEST((std::is_same>::value)); } +BOOST_AUTO_TEST_CASE(spherical_equatorial_representation_difference) +{ + auto point1 = make_spherical_equatorial_representation(15.0 * bud::degrees, 30.0 * bud::degrees, 10.0 * meters); + auto point2 = make_spherical_equatorial_representation(30.0 * bud::degrees, 45.0 * bud::degrees, 20.0 * meters); + + auto result = boost::astronomy::coordinate::difference(point2, point1); + + BOOST_CHECK_CLOSE(result.get_lat().value(), 51.206, 0.001); + BOOST_CHECK_CLOSE(result.get_lon().value(), 55.8705, 0.001); + BOOST_CHECK_CLOSE(result.get_dist().value(), 11.0443, 0.001); + + //checking whether quantity stored is as expected or not + BOOST_TEST((std::is_same>::value)); + BOOST_TEST((std::is_same>::value)); + BOOST_TEST((std::is_same>::value)); +} + BOOST_AUTO_TEST_CASE(spherical_equatorial_representation_mean) { auto point1 = make_spherical_equatorial_representation(15.0 * bud::degrees, 30.0 * bud::degrees, 10.0 * meter); diff --git a/test/coordinate/spherical_representation.cpp b/test/coordinate/spherical_representation.cpp index e3b050cb..72b5b60e 100644 --- a/test/coordinate/spherical_representation.cpp +++ b/test/coordinate/spherical_representation.cpp @@ -246,6 +246,23 @@ BOOST_AUTO_TEST_CASE(spherical_representation_unit_vector) BOOST_TEST((std::is_same>::value)); } +BOOST_AUTO_TEST_CASE(spherical_representation_two_point_unit_vector) +{ + auto point1 = make_spherical_representation(25.0 * bud::degrees, 30.0 * bud::degrees, 90.0*meter); + auto point2 = make_spherical_representation(30.0 * bud::degrees, 35.0 * bud::degrees, 90.0*meter); + + auto result = boost::astronomy::coordinate::unit_vector(point1,point2); + + BOOST_CHECK_CLOSE(result.get_lat().value(), -120, 0.001); + BOOST_CHECK_CLOSE(result.get_lon().value(), 61.7281, 0.001); + BOOST_CHECK_CLOSE(result.get_dist().value(), 1, 0.001); + + //checking whether quantity stored is as expected or not + BOOST_TEST((std::is_same>::value)); + BOOST_TEST((std::is_same>::value)); + BOOST_TEST((std::is_same>::value)); +} + BOOST_AUTO_TEST_CASE(spherical_representation_magnitude) { auto point1 = make_spherical_representation(25.0 * bud::degrees, 36.0 * bud::degrees, 9.0 * meters); @@ -276,6 +293,24 @@ BOOST_AUTO_TEST_CASE(spherical_representation_sum) BOOST_TEST((std::is_same>::value)); } +BOOST_AUTO_TEST_CASE(spherical_representation_difference) +{ + auto point1 = make_spherical_representation(15.0 * bud::degrees, 30.0 * bud::degrees, 10.0 * meters); + auto point2 = make_spherical_representation(30.0 * bud::degrees, 45.0 * bud::degrees, 20.0 * meters); + + auto result = boost::astronomy::coordinate::difference(point1, point2); + + BOOST_CHECK_CLOSE(result.get_lat().value(), -142.089, 0.001); + BOOST_CHECK_CLOSE(result.get_lon().value(), 120.245, 0.001); + BOOST_CHECK_CLOSE(result.get_dist().value(), 10.8834, 0.001); + + //checking whether quantity stored is as expected or not + BOOST_TEST((std::is_same>::value)); + BOOST_TEST((std::is_same>::value)); + BOOST_TEST((std::is_same>::value)); +} + + BOOST_AUTO_TEST_CASE(spherical_representation_mean) { auto point1 = make_spherical_representation(15.0 * bud::degrees, 30.0 * bud::degrees, 10.0 * meter);