Chris@16: // Boost.Geometry (aka GGL, Generic Geometry Library) Chris@16: Chris@16: // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. Chris@16: // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. Chris@16: // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. Chris@16: Chris@101: // This file was modified by Oracle on 2014, 2015. Chris@101: // Modifications copyright (c) 2014-2015 Oracle and/or its affiliates. Chris@101: Chris@101: // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle Chris@101: Chris@16: // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library Chris@16: // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. Chris@16: Chris@16: // Use, modification and distribution is subject to the Boost Software License, Chris@16: // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #ifndef BOOST_GEOMETRY_ALGORITHMS_CONVEX_HULL_HPP Chris@16: #define BOOST_GEOMETRY_ALGORITHMS_CONVEX_HULL_HPP Chris@16: Chris@16: #include Chris@16: Chris@101: #include Chris@101: #include Chris@101: #include Chris@101: Chris@16: #include Chris@16: #include Chris@101: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@101: #include Chris@101: Chris@101: #include Chris@16: Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: Chris@16: namespace boost { namespace geometry Chris@16: { Chris@16: Chris@16: Chris@16: #ifndef DOXYGEN_NO_DETAIL Chris@16: namespace detail { namespace convex_hull Chris@16: { Chris@16: Chris@101: template Chris@16: struct hull_insert Chris@16: { Chris@16: Chris@16: // Member template function (to avoid inconvenient declaration Chris@16: // of output-iterator-type, from hull_to_geometry) Chris@16: template Chris@16: static inline OutputIterator apply(Geometry const& geometry, Chris@16: OutputIterator out, Strategy const& strategy) Chris@16: { Chris@16: typename Strategy::state_type state; Chris@16: Chris@16: strategy.apply(geometry, state); Chris@101: strategy.result(state, out, Order == clockwise, Closure != open); Chris@16: return out; Chris@16: } Chris@16: }; Chris@16: Chris@16: struct hull_to_geometry Chris@16: { Chris@16: template Chris@16: static inline void apply(Geometry const& geometry, OutputGeometry& out, Chris@16: Strategy const& strategy) Chris@16: { Chris@16: hull_insert Chris@16: < Chris@101: geometry::point_order::value, Chris@101: geometry::closure::value Chris@16: >::apply(geometry, Chris@16: std::back_inserter( Chris@16: // Handle linestring, ring and polygon the same: Chris@16: detail::as_range Chris@16: < Chris@16: typename range_type::type Chris@16: >(out)), strategy); Chris@16: } Chris@16: }; Chris@16: Chris@16: }} // namespace detail::convex_hull Chris@16: #endif // DOXYGEN_NO_DETAIL Chris@16: Chris@16: Chris@16: #ifndef DOXYGEN_NO_DISPATCH Chris@16: namespace dispatch Chris@16: { Chris@16: Chris@16: Chris@16: template Chris@16: < Chris@16: typename Geometry, Chris@16: typename Tag = typename tag::type Chris@16: > Chris@16: struct convex_hull Chris@16: : detail::convex_hull::hull_to_geometry Chris@16: {}; Chris@16: Chris@16: template Chris@16: struct convex_hull Chris@16: { Chris@16: template Chris@16: static inline void apply(Box const& box, OutputGeometry& out, Chris@16: Strategy const& ) Chris@16: { Chris@16: static bool const Close Chris@16: = geometry::closure::value == closed; Chris@16: static bool const Reverse Chris@16: = geometry::point_order::value == counterclockwise; Chris@16: Chris@16: // A hull for boxes is trivial. Any strategy is (currently) skipped. Chris@16: boost::array::type, 4> range; Chris@16: geometry::detail::assign_box_corners_oriented(box, range); Chris@16: geometry::append(out, range); Chris@101: if (BOOST_GEOMETRY_CONDITION(Close)) Chris@16: { Chris@16: geometry::append(out, *boost::begin(range)); Chris@16: } Chris@16: } Chris@16: }; Chris@16: Chris@16: Chris@16: Chris@101: template Chris@16: struct convex_hull_insert Chris@101: : detail::convex_hull::hull_insert Chris@16: {}; Chris@16: Chris@16: Chris@16: } // namespace dispatch Chris@16: #endif // DOXYGEN_NO_DISPATCH Chris@16: Chris@16: Chris@101: namespace resolve_strategy { Chris@101: Chris@101: struct convex_hull Chris@101: { Chris@101: template Chris@101: static inline void apply(Geometry const& geometry, Chris@101: OutputGeometry& out, Chris@101: Strategy const& strategy) Chris@101: { Chris@101: BOOST_CONCEPT_ASSERT( (geometry::concept::ConvexHullStrategy) ); Chris@101: dispatch::convex_hull::apply(geometry, out, strategy); Chris@101: } Chris@101: Chris@101: template Chris@101: static inline void apply(Geometry const& geometry, Chris@101: OutputGeometry& out, Chris@101: default_strategy) Chris@101: { Chris@101: typedef typename strategy_convex_hull< Chris@101: Geometry, Chris@101: typename point_type::type Chris@101: >::type strategy_type; Chris@101: Chris@101: apply(geometry, out, strategy_type()); Chris@101: } Chris@101: }; Chris@101: Chris@101: struct convex_hull_insert Chris@101: { Chris@101: template Chris@101: static inline OutputIterator apply(Geometry const& geometry, Chris@101: OutputIterator& out, Chris@101: Strategy const& strategy) Chris@101: { Chris@101: BOOST_CONCEPT_ASSERT( (geometry::concept::ConvexHullStrategy) ); Chris@101: Chris@101: return dispatch::convex_hull_insert< Chris@101: geometry::point_order::value, Chris@101: geometry::closure::value Chris@101: >::apply(geometry, out, strategy); Chris@101: } Chris@101: Chris@101: template Chris@101: static inline OutputIterator apply(Geometry const& geometry, Chris@101: OutputIterator& out, Chris@101: default_strategy) Chris@101: { Chris@101: typedef typename strategy_convex_hull< Chris@101: Geometry, Chris@101: typename point_type::type Chris@101: >::type strategy_type; Chris@101: Chris@101: return apply(geometry, out, strategy_type()); Chris@101: } Chris@101: }; Chris@101: Chris@101: } // namespace resolve_strategy Chris@101: Chris@101: Chris@101: namespace resolve_variant { Chris@101: Chris@101: template Chris@101: struct convex_hull Chris@101: { Chris@101: template Chris@101: static inline void apply(Geometry const& geometry, OutputGeometry& out, Strategy const& strategy) Chris@101: { Chris@101: concept::check_concepts_and_equal_dimensions< Chris@101: const Geometry, Chris@101: OutputGeometry Chris@101: >(); Chris@101: Chris@101: resolve_strategy::convex_hull::apply(geometry, out, strategy); Chris@101: } Chris@101: }; Chris@101: Chris@101: template Chris@101: struct convex_hull > Chris@101: { Chris@101: template Chris@101: struct visitor: boost::static_visitor Chris@101: { Chris@101: OutputGeometry& m_out; Chris@101: Strategy const& m_strategy; Chris@101: Chris@101: visitor(OutputGeometry& out, Strategy const& strategy) Chris@101: : m_out(out), m_strategy(strategy) Chris@101: {} Chris@101: Chris@101: template Chris@101: void operator()(Geometry const& geometry) const Chris@101: { Chris@101: convex_hull::apply(geometry, m_out, m_strategy); Chris@101: } Chris@101: }; Chris@101: Chris@101: template Chris@101: static inline void Chris@101: apply(boost::variant const& geometry, Chris@101: OutputGeometry& out, Chris@101: Strategy const& strategy) Chris@101: { Chris@101: boost::apply_visitor(visitor(out, strategy), geometry); Chris@101: } Chris@101: }; Chris@101: Chris@101: template Chris@101: struct convex_hull_insert Chris@101: { Chris@101: template Chris@101: static inline OutputIterator apply(Geometry const& geometry, OutputIterator& out, Strategy const& strategy) Chris@101: { Chris@101: // Concept: output point type = point type of input geometry Chris@101: concept::check(); Chris@101: concept::check::type>(); Chris@101: Chris@101: return resolve_strategy::convex_hull_insert::apply(geometry, out, strategy); Chris@101: } Chris@101: }; Chris@101: Chris@101: template Chris@101: struct convex_hull_insert > Chris@101: { Chris@101: template Chris@101: struct visitor: boost::static_visitor Chris@101: { Chris@101: OutputIterator& m_out; Chris@101: Strategy const& m_strategy; Chris@101: Chris@101: visitor(OutputIterator& out, Strategy const& strategy) Chris@101: : m_out(out), m_strategy(strategy) Chris@101: {} Chris@101: Chris@101: template Chris@101: OutputIterator operator()(Geometry const& geometry) const Chris@101: { Chris@101: return convex_hull_insert::apply(geometry, m_out, m_strategy); Chris@101: } Chris@101: }; Chris@101: Chris@101: template Chris@101: static inline OutputIterator Chris@101: apply(boost::variant const& geometry, Chris@101: OutputIterator& out, Chris@101: Strategy const& strategy) Chris@101: { Chris@101: return boost::apply_visitor(visitor(out, strategy), geometry); Chris@101: } Chris@101: }; Chris@101: Chris@101: } // namespace resolve_variant Chris@101: Chris@101: Chris@16: template Chris@16: inline void convex_hull(Geometry const& geometry, Chris@16: OutputGeometry& out, Strategy const& strategy) Chris@16: { Chris@16: if (geometry::num_points(geometry) == 0) Chris@16: { Chris@16: // Leave output empty Chris@16: return; Chris@16: } Chris@16: Chris@101: resolve_variant::convex_hull::apply(geometry, out, strategy); Chris@16: } Chris@16: Chris@16: Chris@16: /*! Chris@16: \brief \brief_calc{convex hull} Chris@16: \ingroup convex_hull Chris@16: \details \details_calc{convex_hull,convex hull}. Chris@16: \tparam Geometry the input geometry type Chris@16: \tparam OutputGeometry the output geometry type Chris@16: \param geometry \param_geometry, input geometry Chris@16: \param hull \param_geometry \param_set{convex hull} Chris@16: Chris@16: \qbk{[include reference/algorithms/convex_hull.qbk]} Chris@16: */ Chris@16: template Chris@16: inline void convex_hull(Geometry const& geometry, Chris@16: OutputGeometry& hull) Chris@16: { Chris@101: convex_hull(geometry, hull, default_strategy()); Chris@16: } Chris@16: Chris@16: #ifndef DOXYGEN_NO_DETAIL Chris@16: namespace detail { namespace convex_hull Chris@16: { Chris@16: Chris@16: Chris@16: template Chris@16: inline OutputIterator convex_hull_insert(Geometry const& geometry, Chris@16: OutputIterator out, Strategy const& strategy) Chris@16: { Chris@101: return resolve_variant::convex_hull_insert Chris@101: ::apply(geometry, out, strategy); Chris@16: } Chris@16: Chris@16: Chris@16: /*! Chris@16: \brief Calculate the convex hull of a geometry, output-iterator version Chris@16: \ingroup convex_hull Chris@16: \tparam Geometry the input geometry type Chris@16: \tparam OutputIterator: an output-iterator Chris@16: \param geometry the geometry to calculate convex hull from Chris@16: \param out an output iterator outputing points of the convex hull Chris@16: \note This overloaded version outputs to an output iterator. Chris@16: In this case, nothing is known about its point-type or Chris@16: about its clockwise order. Therefore, the input point-type Chris@16: and order are copied Chris@16: Chris@16: */ Chris@16: template Chris@16: inline OutputIterator convex_hull_insert(Geometry const& geometry, Chris@16: OutputIterator out) Chris@16: { Chris@101: return convex_hull_insert(geometry, out, default_strategy()); Chris@16: } Chris@16: Chris@16: Chris@16: }} // namespace detail::convex_hull Chris@16: #endif // DOXYGEN_NO_DETAIL Chris@16: Chris@16: Chris@16: }} // namespace boost::geometry Chris@16: Chris@16: Chris@16: #endif // BOOST_GEOMETRY_ALGORITHMS_CONVEX_HULL_HPP