Imported Upstream version 1.72.0
[platform/upstream/boost.git] / boost / geometry / algorithms / detail / direction_code.hpp
index ab3b1e0..38c65af 100644 (file)
 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 // http://www.boost.org/LICENSE_1_0.txt)
 
-#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DIRECITON_CODE_HPP
-#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DIRECITON_CODE_HPP
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DIRECTION_CODE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DIRECTION_CODE_HPP
 
 
 #include <boost/geometry/core/access.hpp>
+#include <boost/geometry/arithmetic/infinite_line_functions.hpp>
+#include <boost/geometry/algorithms/detail/make/make.hpp>
 #include <boost/geometry/util/math.hpp>
 #include <boost/geometry/util/select_coordinate_type.hpp>
 #include <boost/geometry/util/normalize_spheroidal_coordinates.hpp>
@@ -32,20 +34,6 @@ namespace boost { namespace geometry
 namespace detail
 {
 
-
-// TODO: remove
-template <std::size_t Index, typename Point1, typename Point2>
-inline int sign_of_difference(Point1 const& point1, Point2 const& point2)
-{
-    return
-        math::equals(geometry::get<Index>(point1), geometry::get<Index>(point2))
-        ?
-        0
-        :
-        (geometry::get<Index>(point1) > geometry::get<Index>(point2) ? 1 : -1);
-}
-
-
 template <typename CSTag>
 struct direction_code_impl
 {
@@ -57,42 +45,30 @@ struct direction_code_impl<cartesian_tag>
 {
     template <typename Point1, typename Point2>
     static inline int apply(Point1 const& segment_a, Point1 const& segment_b,
-                            Point2 const& p)
+                            Point2 const& point)
     {
         typedef typename geometry::select_coordinate_type
             <
                 Point1, Point2
             >::type calc_t;
 
-        if ( (math::equals(geometry::get<0>(segment_b), geometry::get<0>(segment_a))
-           && math::equals(geometry::get<1>(segment_b), geometry::get<1>(segment_a)))
-          || (math::equals(geometry::get<0>(segment_b), geometry::get<0>(p))
-           && math::equals(geometry::get<1>(segment_b), geometry::get<1>(p))) )
+        typedef model::infinite_line<calc_t> line_type;
+
+        // point b is often equal to the specified point, check that first
+        line_type const q = detail::make::make_infinite_line<calc_t>(segment_b, point);
+        if (arithmetic::is_degenerate(q))
         {
             return 0;
         }
 
-        calc_t x1 = geometry::get<0>(segment_b) - geometry::get<0>(segment_a);
-        calc_t y1 = geometry::get<1>(segment_b) - geometry::get<1>(segment_a);
-        calc_t x2 = geometry::get<0>(segment_b) - geometry::get<0>(p);
-        calc_t y2 = geometry::get<1>(segment_b) - geometry::get<1>(p);
-
-        calc_t ax = (std::min)(math::abs(x1), math::abs(x2));
-        calc_t ay = (std::min)(math::abs(y1), math::abs(y2));
-
-        int s1 = 0, s2 = 0;
-        if (ax >= ay)
+        line_type const p = detail::make::make_infinite_line<calc_t>(segment_a, segment_b);
+        if (arithmetic::is_degenerate(p))
         {
-            s1 = x1 > 0 ? 1 : -1;
-            s2 = x2 > 0 ? 1 : -1;
-        }
-        else
-        {
-            s1 = y1 > 0 ? 1 : -1;
-            s2 = y2 > 0 ? 1 : -1;
+            return 0;
         }
 
-        return s1 == s2 ? -1 : 1;
+        // p extends a-b if direction is similar
+        return arithmetic::similar_direction(p, q) ? 1 : -1;
     }
 };
 
@@ -277,4 +253,4 @@ inline int direction_code(Point1 const& segment_a, Point1 const& segment_b,
 
 }} // namespace boost::geometry
 
-#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DIRECITON_CODE_HPP
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DIRECTION_CODE_HPP