summaryrefslogtreecommitdiff
path: root/boost/geometry/algorithms/detail/distance/segment_to_segment.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/geometry/algorithms/detail/distance/segment_to_segment.hpp')
-rw-r--r--boost/geometry/algorithms/detail/distance/segment_to_segment.hpp150
1 files changed, 150 insertions, 0 deletions
diff --git a/boost/geometry/algorithms/detail/distance/segment_to_segment.hpp b/boost/geometry/algorithms/detail/distance/segment_to_segment.hpp
new file mode 100644
index 0000000000..2dcde64946
--- /dev/null
+++ b/boost/geometry/algorithms/detail/distance/segment_to_segment.hpp
@@ -0,0 +1,150 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_SEGMENT_TO_SEGMENT_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_SEGMENT_TO_SEGMENT_HPP
+
+#include <algorithm>
+#include <iterator>
+
+#include <boost/core/addressof.hpp>
+
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/strategies/distance.hpp>
+#include <boost/geometry/strategies/tags.hpp>
+
+#include <boost/geometry/algorithms/assign.hpp>
+#include <boost/geometry/algorithms/intersects.hpp>
+
+#include <boost/geometry/algorithms/detail/distance/is_comparable.hpp>
+
+#include <boost/geometry/algorithms/dispatch/distance.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace distance
+{
+
+
+
+// compute segment-segment distance
+template<typename Segment1, typename Segment2, typename Strategy>
+class segment_to_segment
+{
+private:
+ typedef typename strategy::distance::services::comparable_type
+ <
+ Strategy
+ >::type comparable_strategy;
+
+ typedef typename strategy::distance::services::return_type
+ <
+ comparable_strategy,
+ typename point_type<Segment1>::type,
+ typename point_type<Segment2>::type
+ >::type comparable_return_type;
+
+public:
+ typedef typename strategy::distance::services::return_type
+ <
+ Strategy,
+ typename point_type<Segment1>::type,
+ typename point_type<Segment2>::type
+ >::type return_type;
+
+ static inline return_type
+ apply(Segment1 const& segment1, Segment2 const& segment2,
+ Strategy const& strategy)
+ {
+ if (geometry::intersects(segment1, segment2))
+ {
+ return 0;
+ }
+
+ typename point_type<Segment1>::type p[2];
+ detail::assign_point_from_index<0>(segment1, p[0]);
+ detail::assign_point_from_index<1>(segment1, p[1]);
+
+ typename point_type<Segment2>::type q[2];
+ detail::assign_point_from_index<0>(segment2, q[0]);
+ detail::assign_point_from_index<1>(segment2, q[1]);
+
+ comparable_strategy cstrategy =
+ strategy::distance::services::get_comparable
+ <
+ Strategy
+ >::apply(strategy);
+
+ comparable_return_type d[4];
+ d[0] = cstrategy.apply(q[0], p[0], p[1]);
+ d[1] = cstrategy.apply(q[1], p[0], p[1]);
+ d[2] = cstrategy.apply(p[0], q[0], q[1]);
+ d[3] = cstrategy.apply(p[1], q[0], q[1]);
+
+ std::size_t imin = std::distance(boost::addressof(d[0]),
+ std::min_element(d, d + 4));
+
+ if (is_comparable<Strategy>::value)
+ {
+ return d[imin];
+ }
+
+ switch (imin)
+ {
+ case 0:
+ return strategy.apply(q[0], p[0], p[1]);
+ case 1:
+ return strategy.apply(q[1], p[0], p[1]);
+ case 2:
+ return strategy.apply(p[0], q[0], q[1]);
+ default:
+ return strategy.apply(p[1], q[0], q[1]);
+ }
+ }
+};
+
+
+
+
+}} // namespace detail::distance
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+
+// segment-segment
+template <typename Segment1, typename Segment2, typename Strategy>
+struct distance
+ <
+ Segment1, Segment2, Strategy, segment_tag, segment_tag,
+ strategy_tag_distance_point_segment, false
+ >
+ : detail::distance::segment_to_segment<Segment1, Segment2, Strategy>
+{};
+
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_SEGMENT_TO_SEGMENT_HPP