diff --git a/.gitignore b/.gitignore index f27c9e4a..f4058ea1 100644 --- a/.gitignore +++ b/.gitignore @@ -48,6 +48,7 @@ /astronomy.vcxproj.filters /astronomy.vcxproj /astronomy.sln +*.project *.user /ClassDiagram.cd diff --git a/include/boost/astronomy/coordinate/arithmetic.hpp b/include/boost/astronomy/coordinate/arithmetic.hpp index 10e7bc78..23e7e666 100644 --- a/include/boost/astronomy/coordinate/arithmetic.hpp +++ b/include/boost/astronomy/coordinate/arithmetic.hpp @@ -13,6 +13,8 @@ #include #include +#include +#include namespace boost { namespace astronomy { namespace coordinate { @@ -21,25 +23,24 @@ namespace bg = boost::geometry; namespace bu = boost::units; -//!Returns the cross product of representation1 and representation2 +//!Returns the cross product of cartesian_representation(representation1) and representation2 template < - template class Representation1, template class Representation2, typename ...Args1, typename ...Args2 > auto cross ( - Representation1 const& representation1, + cartesian_representation const& representation1, Representation2 const& representation2 ) { /*!both the coordinates/vector are first converted into cartesian coordinate system then cross product of both cartesian - vectors is converted into requested type and returned*/ + vectors is converted into cartesian system type and returned*/ - /*checking types if it is not subclass of + /*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 // < @@ -56,7 +57,7 @@ auto cross /*converting both coordinates/vector into cartesian system*/ - typedef Representation1 representation1_type; + typedef cartesian_representation representation1_type; typedef Representation2 representation2_type; bg::model::point @@ -72,54 +73,270 @@ auto cross bg::cs::cartesian > tempPoint1, tempPoint2, result; + auto cartesian1 = make_cartesian_representation(representation1); + auto cartesian2 = make_cartesian_representation(representation2); + + typedef decltype(cartesian1) cartesian1_type; + typedef decltype(cartesian2) cartesian2_type; + + bg::transform(representation1.get_point(), tempPoint1); bg::transform(representation2.get_point(), tempPoint2); + bg::set<0>(result, (bg::get<1>(tempPoint1)*bg::get<2>(tempPoint2)) - ((bg::get<2>(tempPoint1)* - bu::conversion_factor(typename representation1_type::quantity3::unit_type(), - typename representation1_type::quantity2::unit_type()))* + bu::conversion_factor(typename cartesian1_type::quantity3::unit_type(), + typename cartesian1_type::quantity2::unit_type()))* (bg::get<1>(tempPoint2)* - bu::conversion_factor(typename representation2_type::quantity2::unit_type(), - typename representation2_type::quantity3::unit_type())))); + bu::conversion_factor(typename cartesian2_type::quantity2::unit_type(), + typename cartesian2_type::quantity3::unit_type())))); bg::set<1>(result, (bg::get<2>(tempPoint1)*bg::get<0>(tempPoint2)) - ((bg::get<0>(tempPoint1)* - bu::conversion_factor(typename representation1_type::quantity1::unit_type(), - typename representation1_type::quantity3::unit_type()))* + bu::conversion_factor(typename cartesian1_type::quantity1::unit_type(), + typename cartesian1_type::quantity3::unit_type()))* (bg::get<2>(tempPoint2)* - bu::conversion_factor(typename representation2_type::quantity3::unit_type(), - typename representation2_type::quantity1::unit_type())))); + bu::conversion_factor(typename cartesian2_type::quantity3::unit_type(), + typename cartesian2_type::quantity1::unit_type())))); bg::set<2>(result, (bg::get<0>(tempPoint1)*bg::get<1>(tempPoint2)) - ((bg::get<1>(tempPoint1)* - bu::conversion_factor(typename representation1_type::quantity2::unit_type(), - typename representation1_type::quantity1::unit_type()))* + bu::conversion_factor(typename cartesian1_type::quantity2::unit_type(), + typename cartesian1_type::quantity1::unit_type()))* (bg::get<0>(tempPoint2)* - bu::conversion_factor(typename representation2_type::quantity1::unit_type(), - typename representation2_type::quantity2::unit_type())))); + bu::conversion_factor(typename cartesian2_type::quantity1::unit_type(), + typename cartesian2_type::quantity2::unit_type())))); - return Representation1 + + return + cartesian_representation < - typename representation1_type::type, + typename cartesian1_type::type, bu::quantity::type + typename cartesian1_type::quantity2::unit_type, + typename cartesian2_type::quantity3::unit_type>::type >, bu::quantity::type + typename cartesian1_type::quantity3::unit_type, + typename cartesian2_type::quantity1::unit_type>::type >, bu::quantity::type + typename cartesian1_type::quantity1::unit_type, + typename cartesian2_type::quantity2::unit_type>::type > >(result); } +//!Returns the cross product of representation1(cartesian differential) and representation2 +template +< + template class Representation2, + typename ...Args1, + typename ...Args2 +> +auto cross +( + cartesian_differential const& representation1, + Representation2 const& representation2 +) +{ + /*!both the coordinates/vector are first converted into + cartesian coordinate system then cross product of both cartesian + vectors is converted into cartesian system type 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*/ + + typedef cartesian_differential representation1_type; + typedef Representation2 representation2_type; + + bg::model::point + < + typename std::conditional + < + sizeof(typename representation2_type::type) >= + sizeof(typename representation1_type::type), + typename representation2_type::type, + typename representation1_type::type + >::type, + 3, + bg::cs::cartesian + > tempPoint1, tempPoint2, result; + + auto cartesian1 = make_cartesian_differential(representation1); + auto cartesian2 = make_cartesian_differential(representation2); + + typedef decltype(cartesian1) cartesian1_type; + typedef decltype(cartesian2) cartesian2_type; + + + bg::transform(representation1.get_point(), tempPoint1); + bg::transform(representation2.get_point(), tempPoint2); + + + bg::set<0>(result, (bg::get<1>(tempPoint1)*bg::get<2>(tempPoint2)) - + ((bg::get<2>(tempPoint1)* + bu::conversion_factor(typename cartesian1_type::quantity3::unit_type(), + typename cartesian1_type::quantity2::unit_type()))* + (bg::get<1>(tempPoint2)* + bu::conversion_factor(typename cartesian2_type::quantity2::unit_type(), + typename cartesian2_type::quantity3::unit_type())))); + + bg::set<1>(result, (bg::get<2>(tempPoint1)*bg::get<0>(tempPoint2)) - + ((bg::get<0>(tempPoint1)* + bu::conversion_factor(typename cartesian1_type::quantity1::unit_type(), + typename cartesian1_type::quantity3::unit_type()))* + (bg::get<2>(tempPoint2)* + bu::conversion_factor(typename cartesian2_type::quantity3::unit_type(), + typename cartesian2_type::quantity1::unit_type())))); + + bg::set<2>(result, (bg::get<0>(tempPoint1)*bg::get<1>(tempPoint2)) - + ((bg::get<1>(tempPoint1)* + bu::conversion_factor(typename cartesian1_type::quantity2::unit_type(), + typename cartesian1_type::quantity1::unit_type()))* + (bg::get<0>(tempPoint2)* + bu::conversion_factor(typename cartesian2_type::quantity1::unit_type(), + typename cartesian2_type::quantity2::unit_type())))); + + + return + cartesian_differential + < + typename cartesian1_type::type, + bu::quantity::type + >, + bu::quantity::type + >, + bu::quantity::type + > + >(result); +} + +//!Returns the cross product of representation1(other than cartesian form) and representation2 +template +< + template class Representation1, + template class Representation2, + typename ...Args1, + typename ...Args2 +> +auto cross +( + Representation1 const& representation1, + Representation2 const& representation2 +) +{ + /*!both the coordinates/vector are first converted into + cartesian coordinate system then cross product of both cartesian + vectors is converted into requested system type 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*/ + + typedef Representation1 representation1_type; + typedef Representation2 representation2_type; + + bg::model::point + < + typename std::conditional + < + sizeof(typename representation2_type::type) >= + sizeof(typename representation1_type::type), + typename representation2_type::type, + typename representation1_type::type + >::type, + 3, + bg::cs::cartesian + > tempPoint1, tempPoint2, result; + + auto cartesian1 = make_cartesian_representation(representation1); + auto cartesian2 = make_cartesian_representation(representation2); + + typedef decltype(cartesian1) cartesian1_type; + typedef decltype(cartesian2) cartesian2_type; + + + bg::transform(cartesian1.get_point(), tempPoint1); + bg::transform(cartesian2.get_point(), tempPoint2); + + + bg::set<0>( + tempPoint2, + bg::get<0>(tempPoint2)* + bu::conversion_factor(typename cartesian2_type::quantity1::unit_type(), + typename cartesian2_type::quantity1::unit_type()) + ); + bg::set<1>( + tempPoint2, + bg::get<1>(tempPoint2)* + bu::conversion_factor(typename cartesian2_type::quantity2::unit_type(), + typename cartesian2_type::quantity1::unit_type()) + ); + bg::set<2>( + tempPoint2, + bg::get<2>(tempPoint2)* + bu::conversion_factor(typename cartesian2_type::quantity3::unit_type(), + typename cartesian2_type::quantity1::unit_type()) + ); + + result = bg::cross_product(tempPoint1,tempPoint2); + + return Representation1 + < + typename representation1_type::type, + typename representation1_type::quantity1, + typename representation1_type::quantity2, + bu::quantity::type + > + >(result); + +} + + //! Returns dot product of representation1 and representation2 template @@ -206,6 +423,45 @@ auto magnitude } +//! Returns magnitude of the cartesian differential vector +template +< + typename CoordinateType, + typename XQuantity, + typename YQuantity, + typename ZQuantity +> +auto magnitude +( + cartesian_differential + < + CoordinateType, + XQuantity, + YQuantity, + ZQuantity + > const& vector +) +{ + CoordinateType result = 0; + bg::model::point + < + CoordinateType, + 3, + bg::cs::cartesian + > tempPoint; + + bg::set<0>(tempPoint, vector.get_dx().value()); + bg::set<1>(tempPoint, static_cast(vector.get_dy()).value()); + bg::set<2>(tempPoint, static_cast(vector.get_dz()).value()); + + result += std::pow(bg::get<0>(tempPoint), 2) + + std::pow(bg::get<1>(tempPoint), 2) + + std::pow(bg::get<2>(tempPoint), 2); + + return std::sqrt(result) * typename XQuantity::unit_type(); +} + + //! Returns magnitude of the vector other than cartesian template auto magnitude(Coordinate const& vector) @@ -239,17 +495,62 @@ unit_vector(cartesian_representation const& vector) return cartesian_representation(tempPoint); } + +//! Returns the unit vector of vector given +template +cartesian_differential +unit_vector(cartesian_differential const& vector) +{ + bg::model::point + < + typename cartesian_differential::type, + 3, + bg::cs::cartesian + > tempPoint; + auto mag = magnitude(vector); //magnitude of vector + + //performing calculations to find unit vector + bg::set<0>(tempPoint, vector.get_dx().value() / mag.value()); + bg::set<1>(tempPoint, + vector.get_dy().value() / + static_cast::quantity2>(mag).value()); + bg::set<2>(tempPoint, + vector.get_dz().value() / + static_cast::quantity3>(mag).value()); + + return cartesian_differential(tempPoint); +} + + + //! Returns unit vector of given vector other than Cartesian template auto unit_vector(Coordinate const& vector) { - Coordinate tempVector; + auto tempPoint = vector.get_point(); + bg::set<2>(tempPoint,1.0); + return Coordinate(tempPoint); +} - tempVector.set_lat(vector.get_lat()); - tempVector.set_lon(vector.get_lon()); - tempVector.set_dist(1.0 * typename Coordinate::quantity3::unit_type()); - 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); } @@ -310,6 +611,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/include/boost/astronomy/coordinate/base_differential.hpp b/include/boost/astronomy/coordinate/base_differential.hpp index 0e8a35fc..3b390783 100644 --- a/include/boost/astronomy/coordinate/base_differential.hpp +++ b/include/boost/astronomy/coordinate/base_differential.hpp @@ -39,58 +39,6 @@ struct base_differential typedef CoordinateSystem system; typedef CoordinateType type; - //! returns the unit vector of current differential - template - ReturnType unit_vector() const - { - /*!given coordinates/vectors are converted into cartesian and - unit vector of it is returned by converting it into requested type*/ - - /*checking return type if they both are not subclass of - base_representaion then compile time erorr is generated*/ - BOOST_STATIC_ASSERT_MSG((boost::astronomy::detail::is_base_template_of - ::value), - "return type is expected to be a differential class"); - - bg::model::point tempPoint; - double mag = this->magnitude(); //magnitude of vector stored in current object - - //converting coordinate/vector into cartesian - bg::transform(this->diff, tempPoint); - - //performing calculations to find unit vector - bg::set<0>(tempPoint, (bg::get<0>(tempPoint) / mag)); - bg::set<1>(tempPoint, (bg::get<1>(tempPoint) / mag)); - bg::set<2>(tempPoint, (bg::get<2>(tempPoint) / mag)); - - return ReturnType(tempPoint); - } - - //! magnitude of the current class is returned - double magnitude() const - { - double result = 0.0; - bg::model::point tempPoint; - bg::transform(this->diff, tempPoint); - - switch (DimensionCount) - { - case 2: - result += std::pow(bg::get<0>(tempPoint), 2); - result += std::pow(bg::get<1>(tempPoint), 2); - break; - case 3: - result += std::pow(bg::get<0>(tempPoint), 2); - result += std::pow(bg::get<1>(tempPoint), 2); - result += std::pow(bg::get<2>(tempPoint), 2); - break; - default: - return -1; - } - - return std::sqrt(result); - } - //! converts current representation into specified representation template ReturnType to_differential() const @@ -115,6 +63,17 @@ struct base_differential { return this->diff; } + //! returns the differential of calling object + bg::model::point + < + CoordinateType, + DimensionCount, + CoordinateSystem + > + get_point() const + { + return this->diff; + } template < diff --git a/include/boost/astronomy/coordinate/io.hpp b/include/boost/astronomy/coordinate/io.hpp index 06c5dd6a..731d03c9 100644 --- a/include/boost/astronomy/coordinate/io.hpp +++ b/include/boost/astronomy/coordinate/io.hpp @@ -11,6 +11,7 @@ #include #include #include +#include namespace boost { namespace astronomy { namespace coordinate { @@ -70,6 +71,81 @@ std::ostream& operator<< (std::ostream &out, spherical_representation return out; } +//!"<<" operator overload to print details of a Cartesian differential point +template +< + typename CoordinateType, + class XQuantity, + class YQuantity, + class ZQuantity +> +std::ostream& operator<< (std::ostream &out, cartesian_differential + const& point) +{ + out << "Cartesian differential ( " + << point.get_dx() << " , " + << point.get_dy() << " , " + << point.get_dz() << " )"; + + return out; +} + +//!"<<" operator overload to print details of a Spherical Equatorial differential Point +template +< + typename CoordinateType, + class LatQuantity, + class LonQuantity, + class DistQuantity +> +std::ostream& operator<< (std::ostream &out, spherical_equatorial_differential + const& point) +{ + out << "Spherical Equatorial differential ( " + << point.get_dlat() << " , " + << point.get_dlon() << " , " + << point.get_ddist() << " )"; + + return out; +} + +//!"<<" operator overload to print details of a Spherical differential point +template +< + typename CoordinateType, + class LatQuantity, + class LonQuantity, + class DistQuantity +> +std::ostream& operator<< (std::ostream &out, spherical_differential + const& point) +{ + out << "Spherical differential ( " + << point.get_dlat() << " , " + << point.get_dlon() << " , " + << point.get_ddist() << " )"; + + return out; +} + +//!"<<" operator overload to print details of a spherical_coslat_differential +template +< + typename CoordinateType, + class LatQuantity, + class LonQuantity, + class DistQuantity +> +std::ostream& operator<< (std::ostream &out, spherical_coslat_differential + const& point) +{ + out << "Spherical Coslat Differential ( " + << point.get_dlat() << " , " + << point.get_dlon_coslat() << " , " + << point.get_ddist() << " )"; + + return out; +} }}} //namespace boost::astronomy::coordinate #endif // !BOOST_ASTRONOMY_COORDINATE_IO_HPP \ No newline at end of file diff --git a/test/coordinate/CMakeLists.txt b/test/coordinate/CMakeLists.txt index 012a56a5..23132704 100644 --- a/test/coordinate/CMakeLists.txt +++ b/test/coordinate/CMakeLists.txt @@ -4,7 +4,8 @@ foreach(_name spherical_representation spherical_differential spherical_equatorial_representation - spherical_equatorial_differential) + spherical_equatorial_differential + spherical_coslat_differential) set(_target test_coordinate_${_name}) add_executable(${_target} "") diff --git a/test/coordinate/Jamfile b/test/coordinate/Jamfile index fd25b737..334d596d 100644 --- a/test/coordinate/Jamfile +++ b/test/coordinate/Jamfile @@ -6,3 +6,4 @@ run spherical_representation.cpp ; run spherical_differential.cpp ; run spherical_equatorial_representation.cpp ; run spherical_equatorial_differential.cpp ; +run spherical_coslat_differential.cpp ; diff --git a/test/coordinate/cartesian_representation.cpp b/test/coordinate/cartesian_representation.cpp index ebee416a..190eee52 100644 --- a/test/coordinate/cartesian_representation.cpp +++ b/test/coordinate/cartesian_representation.cpp @@ -9,6 +9,7 @@ #include #include + using namespace std; using namespace boost::astronomy::coordinate; using namespace boost::units::si; @@ -208,16 +209,15 @@ BOOST_AUTO_TEST_CASE(cartesian_representation_cross_product) auto result = cross(point1, point2); - BOOST_CHECK_CLOSE(result.get_x().value(), -180.0, 0.001); + BOOST_CHECK_CLOSE(result.get_x().value(), -180, 0.001); BOOST_CHECK_CLOSE(result.get_y().value(), 11.988, 0.001); - BOOST_CHECK_CLOSE(result.get_z().value(), -1485.0, 0.001); + BOOST_CHECK_CLOSE(result.get_z().value(), -1485, 0.001); //checking whether quantity stored is as expected or not BOOST_TEST((std::is_same::type>>::value)); BOOST_TEST((std::is_same::type>>::value)); + ::type>>::value)); BOOST_TEST((std::is_same::type>>::value)); } @@ -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_coslat_differential.cpp b/test/coordinate/spherical_coslat_differential.cpp new file mode 100644 index 00000000..25d1fe88 --- /dev/null +++ b/test/coordinate/spherical_coslat_differential.cpp @@ -0,0 +1,236 @@ +#define BOOST_TEST_MODULE spherical_coslat_differential_test + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace boost::astronomy::coordinate; +using namespace boost::units::si; +using namespace boost::geometry; +using namespace boost::units; +namespace bud = boost::units::degree; + +BOOST_AUTO_TEST_SUITE(spherical_coslat_differential_constructors) + +BOOST_AUTO_TEST_CASE(spherical_coslat_differential_default_constructor) +{ + //using set functions + spherical_coslat_differential, quantity, + quantity> motion1; + motion1.set_dlat_dlon_coslat_ddist(45.0 * bud::degrees, 18.0 * bud::degrees, 3.5 * meters/seconds); + BOOST_CHECK_CLOSE(motion1.get_dlat().value(), 45.0, 0.001); + BOOST_CHECK_CLOSE(motion1.get_dlon_coslat().value(), 18.0, 0.001); + BOOST_CHECK_CLOSE(motion1.get_ddist().value(), 3.5, 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_coslat_differential_quantities_constructor) +{ + //checking construction from value + auto motion1 = make_spherical_coslat_differential + (15.0 * bud::degrees, 39.0 * bud::degrees, 3.0*si::centi*meter/seconds); + BOOST_CHECK_CLOSE(motion1.get_dlat().value(), 15.0, 0.001); + BOOST_CHECK_CLOSE(motion1.get_dlon_coslat().value(), 39.0, 0.001); + BOOST_CHECK_CLOSE(motion1.get_ddist().value(), 3.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::type>>::value)); + + spherical_coslat_differential, quantity, + quantity> motion2(1.5 * bud::degrees, 9.0 * bud::degrees, 3.0 * meter/seconds); + BOOST_CHECK_CLOSE(motion2.get_dlat().value(), 1.5, 0.001); + BOOST_CHECK_CLOSE(motion2.get_dlon_coslat().value(), 9.0, 0.001); + BOOST_CHECK_CLOSE(motion2.get_ddist().value(), 3, 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_coslat_differential_copy_constructor) +{ + //checking construction from value + auto motion1 = make_spherical_coslat_differential + (15.0 * bud::degrees, 30.0 * bud::degrees, 3.0*si::centi*meter/seconds); + BOOST_CHECK_CLOSE(motion1.get_dlat().value(), 15.0, 0.001); + BOOST_CHECK_CLOSE(motion1.get_dlon_coslat().value(), 30.0, 0.001); + BOOST_CHECK_CLOSE(motion1.get_ddist().value(), 3, 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::type>>::value)); + + //copy constructor + auto motion2 = make_spherical_coslat_differential(motion1); + BOOST_CHECK_CLOSE(motion1.get_dlat().value(), motion2.get_dlat().value(), 0.001); + BOOST_CHECK_CLOSE(motion1.get_dlon_coslat().value(), motion2.get_dlon_coslat().value(), 0.001); + BOOST_CHECK_CLOSE(motion1.get_ddist().value(), motion2.get_ddist().value(), 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::type>>::value)); +} + +BOOST_AUTO_TEST_CASE(spherical_coslat_differential_copy_constructor_with_different_units) +{ + //checking construction from value + auto motion1 = make_spherical_coslat_differential + (15.0 * bud::degrees, 10.0 * bud::degrees, 3.0*si::centi*meter/seconds); + BOOST_CHECK_CLOSE(motion1.get_dlat().value(), 15.0, 0.001); + BOOST_CHECK_CLOSE(motion1.get_dlon_coslat().value(), 10.0, 0.001); + BOOST_CHECK_CLOSE(motion1.get_ddist().value(), 3, 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::type>>::value)); + + //Conversion from one unit type to other + auto motion2 = make_spherical_coslat_differential + , quantity, quantity>(motion1); + BOOST_CHECK_CLOSE(motion2.get_dlat().value(), 15.0, 0.001); + BOOST_CHECK_CLOSE(motion2.get_dlon_coslat().value(), 10.0, 0.001); + BOOST_CHECK_CLOSE(motion2.get_ddist().value(), 0.03, 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_coslat_differential_geometry_point_constructor) +{ + //constructing from boost::geometry::model::motion + model::point model_point(30, 60, 10); + auto motion1 = make_spherical_coslat_differential + ,quantity,quantity>(model_point); + BOOST_CHECK_CLOSE(motion1.get_dlat().value(), 63.434948822922, 0.001); + BOOST_CHECK_CLOSE(motion1.get_dlon_coslat().value(), 81.521286852914, 0.001); + BOOST_CHECK_CLOSE(motion1.get_ddist().value(), 67.823299831253, 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)); + + spherical_coslat_differential, quantity, + quantity> motion2(model_point); + BOOST_CHECK_CLOSE(motion2.get_dlat().value(), 63.434948822922, 0.001); + BOOST_CHECK_CLOSE(motion2.get_dlon_coslat().value(), 81.521286852914, 0.001); + BOOST_CHECK_CLOSE(motion2.get_ddist().value(), 67.823299831253, 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_coslat_differential_conversion_from_cartesian_differential) +{ + //constructing from spherical differential + auto cartesian_motion = make_cartesian_differential(20.0 * meters/seconds, + 60.0 * meters/seconds, 1.0 * meter/seconds); + auto motion1 = make_spherical_coslat_differential(cartesian_motion); + BOOST_CHECK_CLOSE(motion1.get_dlat().value(), 1.2490457723983, 0.001); + BOOST_CHECK_CLOSE(motion1.get_dlon_coslat().value(), 0.49173, 0.001); + BOOST_CHECK_CLOSE(motion1.get_ddist().value(), 63.253458403474, 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_coslat_differential_conversion_from_spherical_equatorial_differential) +{ + //constructing from spherical_equitorial differential + auto spherical_equatorial_motion = make_spherical_equatorial_differential + (0.523599 * si::radian, 60.0 * bud::degrees, 1.0 * meter/seconds); + auto motion2 = make_spherical_coslat_differential(spherical_equatorial_motion); + BOOST_CHECK_CLOSE(motion2.get_dlat().value(), 0.523599, 0.001); + BOOST_CHECK_CLOSE(motion2.get_dlon_coslat().value(), 0.45345, 0.001); + BOOST_CHECK_CLOSE(motion2.get_ddist().value(), 1.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(spherical_coslat_differential_conversion_from_spherical_differential) +{ + //constructing from spherical_coslat differential + auto spherical_motion = make_spherical_differential + (0.523599 * si::radian, 60.0 * bud::degrees, 1.0 * meters/seconds); + auto motion3 = make_spherical_coslat_differential(spherical_motion); + BOOST_CHECK_CLOSE(motion3.get_dlat().value(), 0.523599, 0.001); + BOOST_CHECK_CLOSE(motion3.get_dlon_coslat().value(), 0.9069, 0.001); + BOOST_CHECK_CLOSE(motion3.get_ddist().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_SUITE_END() + +BOOST_AUTO_TEST_SUITE(spherical_coslat_differential_operators) + +BOOST_AUTO_TEST_CASE(spherical_coslat_differential_addition_operator) +{ + auto motion1 = make_spherical_coslat_differential(15.0 * bud::degrees, 30.0 * bud::degrees, 10.0 * meters/seconds); + auto motion2 = make_spherical_coslat_differential(30.0 * bud::degrees, 45.0 * bud::degrees, 20.0 * meters/seconds); + + auto sum = make_spherical_coslat_differential(motion1 + motion2); + + BOOST_CHECK_CLOSE(sum.get_dlat().value(), 26.4022, 0.001); + BOOST_CHECK_CLOSE(sum.get_dlon_coslat().value(), 39.86, 0.001); + BOOST_CHECK_CLOSE(sum.get_ddist().value(), 29.4212, 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_coslat_differential_multiplication_operator) +{ + auto motion1 = make_spherical_coslat_differential(15.0 * bud::degrees, 30.0 * bud::degrees, 10.0 * meters/seconds); + + spherical_coslat_differential, quantity, + quantity> product = make_spherical_coslat_differential(motion1 * quantity(5.0*seconds)); + + BOOST_CHECK_CLOSE(product.get_dlat().value(), 15.0, 0.001); + BOOST_CHECK_CLOSE(product.get_dlon_coslat().value(), 30.0, 0.001); + BOOST_CHECK_CLOSE(product.get_ddist().value(), 50.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_SUITE_END() + diff --git a/test/coordinate/spherical_equatorial_representation.cpp b/test/coordinate/spherical_equatorial_representation.cpp index 3e5bb5ca..cd2daf65 100644 --- a/test/coordinate/spherical_equatorial_representation.cpp +++ b/test/coordinate/spherical_equatorial_representation.cpp @@ -196,25 +196,22 @@ BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE(spherical_equatorial_representation_arithmetic_functions) -// BOOST_AUTO_TEST_CASE(spherical_equatorial_representation_cross_product) -// { -// auto point1 = make_spherical_equatorial_representation(3.0 * bud::degrees, 50.0 * bud::degrees, 40.0 * meters); -// auto point2 = make_spherical_equatorial_representation(30.0 * bud::degrees, 45.0 * bud::degrees, 14.0 * meters); - -// auto result = cross(point1, point2); - -// BOOST_CHECK_CLOSE(result.get_lat().value(), -143.4774246228, 0.001); -// BOOST_CHECK_CLOSE(result.get_lon().value(), 45.186034054587, 0.001); -// BOOST_CHECK_CLOSE(result.get_dist().value(), 195.39050840581, 0.001); - -// //checking whether quantity stored is as expected or not -// BOOST_TEST((std::is_same::type>>::value)); -// BOOST_TEST((std::is_same::type>>::value)); -// BOOST_TEST((std::is_same::type>>::value)); -// } +BOOST_AUTO_TEST_CASE(spherical_equatorial_representation_cross_product) +{ + auto point1 = make_spherical_equatorial_representation(3.0 * bud::degrees, 50.0 * bud::degrees, 40.0 * meters); + auto point2 = make_spherical_equatorial_representation(30.0 * bud::degrees, 45.0 * bud::degrees, 14.0 * meters); + + auto result = cross(point1, point2); + + BOOST_CHECK_CLOSE(result.get_lat().value(), 176.47742460814121, 0.001); + BOOST_CHECK_CLOSE(result.get_lon().value(), 39.816895281423861, 0.001); + BOOST_CHECK_CLOSE(result.get_dist().value(), 180.459280550626, 0.001); + + BOOST_TEST((std::is_same>::value)); + BOOST_TEST((std::is_same>::value)); + BOOST_TEST((std::is_same::type>>::value)); +} BOOST_AUTO_TEST_CASE(spherical_equatorial_representation_dot_product) { @@ -246,6 +243,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 +289,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..514f2c41 100644 --- a/test/coordinate/spherical_representation.cpp +++ b/test/coordinate/spherical_representation.cpp @@ -196,25 +196,22 @@ BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE(spherical_representation_arithmetic_functions) -// BOOST_AUTO_TEST_CASE(spherical_representation_cross_product) -// { -// auto point1 = make_spherical_representation(3.0 * bud::degrees, 50.0 * bud::degrees, 40.0 * meters); -// auto point2 = make_spherical_representation(30.0 * bud::degrees, 45.0 * bud::degrees, 14.0 * meters); - -// auto result = cross(point1, point2); - -// BOOST_CHECK_CLOSE(result.get_lat().value(), -143.4774246228, 0.001); -// BOOST_CHECK_CLOSE(result.get_lon().value(), 45.186034054587, 0.001); -// BOOST_CHECK_CLOSE(result.get_dist().value(), 195.39050840581, 0.001); - -// //checking whether quantity stored is as expected or not -// BOOST_TEST((std::is_same::type>>::value)); -// BOOST_TEST((std::is_same::type>>::value)); -// BOOST_TEST((std::is_same::type>>::value)); -// } +BOOST_AUTO_TEST_CASE(spherical_representation_cross_product) +{ + auto point1 = make_spherical_equatorial_representation(3.0 * bud::degrees, 50.0 * bud::degrees, 40.0 * meters); + auto point2 = make_spherical_equatorial_representation(30.0 * bud::degrees, 45.0 * bud::degrees, 14.0 * meters); + + auto result = cross(point1, point2); + + BOOST_CHECK_CLOSE(result.get_lat().value(), 176.47742460814121, 0.001); + BOOST_CHECK_CLOSE(result.get_lon().value(), 39.816895281423861, 0.001); + BOOST_CHECK_CLOSE(result.get_dist().value(), 180.459280550626, 0.001); + + BOOST_TEST((std::is_same>::value)); + BOOST_TEST((std::is_same>::value)); + BOOST_TEST((std::is_same::type>>::value)); +} BOOST_AUTO_TEST_CASE(spherical_representation_dot_product) { @@ -246,6 +243,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 +290,23 @@ 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);