Index: geometry/strategies/spherical/distance_cross_track.hpp =================================================================== --- geometry/strategies/spherical/distance_cross_track.hpp (revision 79131) +++ geometry/strategies/spherical/distance_cross_track.hpp (working copy) @@ -107,17 +107,34 @@ return_type crs_AD = course(sp1, p); return_type crs_AB = course(sp1, sp2); - return_type XTD = m_radius * geometry::math::abs(asin(sin(d1 / m_radius) * sin(crs_AD - crs_AB))); -#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 << "XTD: " << XTD << " d1: " << d1 << " d2: " << d2 << std::endl; + return_type d_crs = crs_AD - crs_AB; + + if( ( geometry::math::abs( d_crs ) < geometry::math::pi< return_type >() * 0.5 ) + || ( geometry::math::abs( d_crs ) > geometry::math::pi< return_type >() * 1.5 ) ) + { + return_type XTD = m_radius * geometry::math::abs( asin( sin( d1 / m_radius ) * sin( crs_AD - crs_AB ) )); + + #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 << "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 << "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; +#endif - // Return shortest distance, either to projected point on segment sp1-sp2, or to sp1, or to sp2 - return return_type((std::min)((std::min)(d1, d2), XTD)); + // Return shortest distance, either to sp1, or to sp2 + return return_type( std::min( d1 , d2 ) ); + } + } inline return_type radius() const { return m_radius; }