Skip to content

Commit

Permalink
add difference function and update unit_vector in arithmetic.hpp
Browse files Browse the repository at this point in the history
  • Loading branch information
rjnrohit committed Apr 14, 2020
1 parent feec6d4 commit 6bbe800
Show file tree
Hide file tree
Showing 4 changed files with 179 additions and 0 deletions.
75 changes: 75 additions & 0 deletions include/boost/astronomy/coordinate/arithmetic.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,25 @@ auto unit_vector(Coordinate const& vector)
return tempVector;
}

//! Returns unit vector directing from representation2 to representation1
template<typename Representation1, typename Representation2>
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<typename Representation1, typename Representation2>
Expand Down Expand Up @@ -310,6 +329,62 @@ Representation1 sum
return Representation1(result);
}

//! Returns difference of representation1 and representation2 (difference vector towards representation1)
template<typename Representation1, typename Representation2>
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<typename cartesian1_type::quantity1>(cartesian2.get_x()).value()));
bg::set<1>(result, (cartesian1.get_y().value() -
static_cast<typename cartesian1_type::quantity2>(cartesian2.get_y()).value()));
bg::set<2>(result, (cartesian1.get_z().value() -
static_cast<typename cartesian1_type::quantity3>(cartesian2.get_z()).value()));

return Representation1(result);
}

//! Returns mean of representation1 and representation2
template<typename Representation1, typename Representation2>
Expand Down
36 changes: 36 additions & 0 deletions test/coordinate/cartesian_representation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,23 @@ BOOST_AUTO_TEST_CASE(cartesian_representation_unit_vector)
BOOST_TEST((std::is_same<decltype(result.get_z()), quantity<si::length>>::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<decltype(result.get_x()), quantity<si::length>>::value));
BOOST_TEST((std::is_same<decltype(result.get_y()), quantity<si::length>>::value));
BOOST_TEST((std::is_same<decltype(result.get_z()), quantity<si::length>>::value));
}

BOOST_AUTO_TEST_CASE(cartesian_representation_magnitude)
{
auto point1 = make_cartesian_representation
Expand Down Expand Up @@ -287,6 +304,25 @@ BOOST_AUTO_TEST_CASE(cartesian_representation_sum)
BOOST_TEST((std::is_same<decltype(result.get_z()), quantity<si::length>>::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<decltype(result.get_x()), quantity<si::length>>::value));
BOOST_TEST((std::is_same<decltype(result.get_y()), quantity<decltype(si::kilo*meter)>>::value));
BOOST_TEST((std::is_same<decltype(result.get_z()), quantity<si::length>>::value));
}

BOOST_AUTO_TEST_CASE(cartesian_representation_mean)
{
auto point1 = make_cartesian_representation
Expand Down
33 changes: 33 additions & 0 deletions test/coordinate/spherical_equatorial_representation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,22 @@ BOOST_AUTO_TEST_CASE(spherical_equatorial_representation_unit_vector)
BOOST_TEST((std::is_same<decltype(result.get_dist()), quantity<si::length>>::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<decltype(result.get_lat()), quantity<bud::plane_angle>>::value));
BOOST_TEST((std::is_same<decltype(result.get_lon()), quantity<bud::plane_angle>>::value));
BOOST_TEST((std::is_same<decltype(result.get_dist()), quantity<si::length>>::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);
Expand Down Expand Up @@ -276,6 +292,23 @@ BOOST_AUTO_TEST_CASE(spherical_equatorial_representation_sum)
BOOST_TEST((std::is_same<decltype(result.get_dist()), quantity<si::length>>::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<decltype(result.get_lat()), quantity<bud::plane_angle>>::value));
BOOST_TEST((std::is_same<decltype(result.get_lon()), quantity<bud::plane_angle>>::value));
BOOST_TEST((std::is_same<decltype(result.get_dist()), quantity<si::length>>::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);
Expand Down
35 changes: 35 additions & 0 deletions test/coordinate/spherical_representation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,23 @@ BOOST_AUTO_TEST_CASE(spherical_representation_unit_vector)
BOOST_TEST((std::is_same<decltype(result.get_dist()), quantity<si::length>>::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<decltype(result.get_lat()), quantity<bud::plane_angle>>::value));
BOOST_TEST((std::is_same<decltype(result.get_lon()), quantity<bud::plane_angle>>::value));
BOOST_TEST((std::is_same<decltype(result.get_dist()), quantity<si::length>>::value));
}

BOOST_AUTO_TEST_CASE(spherical_representation_magnitude)
{
auto point1 = make_spherical_representation(25.0 * bud::degrees, 36.0 * bud::degrees, 9.0 * meters);
Expand Down Expand Up @@ -276,6 +293,24 @@ BOOST_AUTO_TEST_CASE(spherical_representation_sum)
BOOST_TEST((std::is_same<decltype(result.get_dist()), quantity<si::length>>::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<decltype(result.get_lat()), quantity<bud::plane_angle>>::value));
BOOST_TEST((std::is_same<decltype(result.get_lon()), quantity<bud::plane_angle>>::value));
BOOST_TEST((std::is_same<decltype(result.get_dist()), quantity<si::length>>::value));
}


BOOST_AUTO_TEST_CASE(spherical_representation_mean)
{
auto point1 = make_spherical_representation(15.0 * bud::degrees, 30.0 * bud::degrees, 10.0 * meter);
Expand Down

0 comments on commit 6bbe800

Please sign in to comment.