Boost-Geometry-Utils
view release on metacpan or search on metacpan
src/boost/geometry/strategies/spherical/distance_cross_track.hpp view on Meta::CPAN
}
return_type d2 = m_strategy.apply(sp2, p);
return_type crs_AD = course(sp1, p);
return_type crs_AB = course(sp1, sp2);
return_type crs_BA = crs_AB - geometry::math::pi<return_type>();
return_type crs_BD = course(sp2, p);
return_type d_crs1 = crs_AD - crs_AB;
return_type d_crs2 = crs_BD - crs_BA;
// d1, d2, d3 are in principle not needed, only the sign matters
return_type projection1 = cos( d_crs1 ) * d1 / d3;
return_type projection2 = cos( d_crs2 ) * d2 / d3;
#ifdef BOOST_GEOMETRY_DEBUG_CROSS_TRACK
std::cout << "Course " << dsv(sp1) << " to " << dsv(p) << " " << crs_AD * geometry::math::r2d << std::endl;
std::cout << "Course " << dsv(sp1) << " to " << dsv(sp2) << " " << crs_AB * geometry::math::r2d << std::endl;
std::cout << "Course " << dsv(sp2) << " to " << dsv(p) << " " << crs_BD * geometry::math::r2d << std::endl;
std::cout << "Projection AD-AB " << projection1 << " : " << d_crs1 * geometry::math::r2d << std::endl;
std::cout << "Projection BD-BA " << projection2 << " : " << d_crs2 * geometry::math::r2d << std::endl;
#endif
if(projection1 > 0.0 && projection2 > 0.0)
{
return_type XTD = m_radius * geometry::math::abs( asin( sin( d1 / m_radius ) * sin( d_crs1 ) ));
#ifdef BOOST_GEOMETRY_DEBUG_CROSS_TRACK
std::cout << "Projection ON the segment" << std::endl;
std::cout << "XTD: " << XTD << " d1: " << d1 << " d2: " << d2 << std::endl;
#endif
// Return shortest distance, projected point on segment sp1-sp2
return return_type(XTD);
}
else
{
#ifdef BOOST_GEOMETRY_DEBUG_CROSS_TRACK
std::cout << "Projection OUTSIDE the segment" << std::endl;
#endif
// Return shortest distance, project either on point sp1 or sp2
return return_type( (std::min)( d1 , d2 ) );
}
}
inline return_type radius() const { return m_radius; }
private :
BOOST_CONCEPT_ASSERT
(
(geometry::concept::PointDistanceStrategy<Strategy >)
);
return_type m_radius;
// Point-point distances are calculated in radians, on the unit sphere
Strategy m_strategy;
/// Calculate course (bearing) between two points. Might be moved to a "course formula" ...
inline return_type course(Point const& p1, Point const& p2) const
{
// http://williams.best.vwh.net/avform.htm#Crs
return_type dlon = get_as_radian<0>(p2) - get_as_radian<0>(p1);
return_type cos_p2lat = cos(get_as_radian<1>(p2));
// "An alternative formula, not requiring the pre-computation of d"
return atan2(sin(dlon) * cos_p2lat,
cos(get_as_radian<1>(p1)) * sin(get_as_radian<1>(p2))
- sin(get_as_radian<1>(p1)) * cos_p2lat * cos(dlon));
}
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
{
template <typename Point, typename PointOfSegment, typename CalculationType, typename Strategy>
struct tag<cross_track<Point, PointOfSegment, CalculationType, Strategy> >
{
typedef strategy_tag_distance_point_segment type;
};
template <typename Point, typename PointOfSegment, typename CalculationType, typename Strategy>
struct return_type<cross_track<Point, PointOfSegment, CalculationType, Strategy> >
{
typedef typename cross_track<Point, PointOfSegment, CalculationType, Strategy>::return_type type;
};
template
<
typename Point,
typename PointOfSegment,
typename CalculationType,
typename Strategy,
typename P,
typename PS
>
struct similar_type<cross_track<Point, PointOfSegment, CalculationType, Strategy>, P, PS>
{
typedef cross_track<Point, PointOfSegment, CalculationType, Strategy> type;
};
template
<
typename Point,
typename PointOfSegment,
typename CalculationType,
typename Strategy,
typename P,
typename PS
>
struct get_similar<cross_track<Point, PointOfSegment, CalculationType, Strategy>, P, PS>
{
static inline typename similar_type
<
cross_track<Point, PointOfSegment, CalculationType, Strategy>, P, PS
>::type apply(cross_track<Point, PointOfSegment, CalculationType, Strategy> const& strategy)
{
return cross_track<P, PS, CalculationType, Strategy>(strategy.radius());
}
( run in 1.420 second using v1.01-cache-2.11-cpan-0bb4e1dffa6 )