Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add difference function and update unit_vector in arithmetic.hpp #128

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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