Chris@102: // Boost.Geometry (aka GGL, Generic Geometry Library) Chris@102: Chris@102: // Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands. Chris@102: Chris@102: // Use, modification and distribution is subject to the Boost Software License, Chris@102: // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at Chris@102: // http://www.boost.org/LICENSE_1_0.txt) Chris@102: Chris@102: #ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_END_FLAT_HPP Chris@102: #define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_END_FLAT_HPP Chris@102: Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: Chris@102: #include Chris@102: Chris@102: Chris@102: Chris@102: namespace boost { namespace geometry Chris@102: { Chris@102: Chris@102: Chris@102: namespace strategy { namespace buffer Chris@102: { Chris@102: Chris@102: Chris@102: /*! Chris@102: \brief Let the buffer create flat ends Chris@102: \ingroup strategies Chris@102: \details This strategy can be used as EndStrategy for the buffer algorithm. Chris@102: It creates a flat end for each linestring-end. It can be applied Chris@102: for (multi)linestrings. Also it is applicable for spikes in (multi)polygons. Chris@102: This strategy is only applicable for Cartesian coordinate systems. Chris@102: Chris@102: \qbk{ Chris@102: [heading Example] Chris@102: [buffer_end_flat] Chris@102: [heading Output] Chris@102: [$img/strategies/buffer_end_flat.png] Chris@102: [heading See also] Chris@102: \* [link geometry.reference.algorithms.buffer.buffer_7_with_strategies buffer (with strategies)] Chris@102: \* [link geometry.reference.strategies.strategy_buffer_end_round end_round] Chris@102: } Chris@102: */ Chris@102: class end_flat Chris@102: { Chris@102: Chris@102: public : Chris@102: Chris@102: #ifndef DOXYGEN_SHOULD_SKIP_THIS Chris@102: //! Fills output_range with a flat end Chris@102: template Chris@102: inline void apply(Point const& penultimate_point, Chris@102: Point const& perp_left_point, Chris@102: Point const& ultimate_point, Chris@102: Point const& perp_right_point, Chris@102: buffer_side_selector side, Chris@102: DistanceStrategy const& distance, Chris@102: RangeOut& range_out) const Chris@102: { Chris@102: typedef typename coordinate_type::type coordinate_type; Chris@102: Chris@102: typedef typename geometry::select_most_precise Chris@102: < Chris@102: coordinate_type, Chris@102: double Chris@102: >::type promoted_type; Chris@102: Chris@102: promoted_type const dist_left = distance.apply(penultimate_point, ultimate_point, buffer_side_left); Chris@102: promoted_type const dist_right = distance.apply(penultimate_point, ultimate_point, buffer_side_right); Chris@102: Chris@102: bool reversed = (side == buffer_side_left && dist_right < 0 && -dist_right > dist_left) Chris@102: || (side == buffer_side_right && dist_left < 0 && -dist_left > dist_right) Chris@102: ; Chris@102: if (reversed) Chris@102: { Chris@102: range_out.push_back(perp_right_point); Chris@102: range_out.push_back(perp_left_point); Chris@102: } Chris@102: else Chris@102: { Chris@102: range_out.push_back(perp_left_point); Chris@102: range_out.push_back(perp_right_point); Chris@102: } Chris@102: // Don't add the ultimate_point (endpoint of the linestring). Chris@102: // The buffer might be generated completely at one side. Chris@102: // In other cases it does no harm but is further useless Chris@102: } Chris@102: Chris@102: template Chris@102: static inline NumericType max_distance(NumericType const& distance) Chris@102: { Chris@102: return distance; Chris@102: } Chris@102: Chris@102: //! Returns the piece_type (flat end) Chris@102: static inline piece_type get_piece_type() Chris@102: { Chris@102: return buffered_flat_end; Chris@102: } Chris@102: #endif // DOXYGEN_SHOULD_SKIP_THIS Chris@102: }; Chris@102: Chris@102: Chris@102: }} // namespace strategy::buffer Chris@102: Chris@102: }} // namespace boost::geometry Chris@102: Chris@102: #endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_END_FLAT_HPP