Chris@102: // Boost.Geometry (aka GGL, Generic Geometry Library) Chris@102: // Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands. 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_SIDE_STRAIGHT_HPP Chris@102: #define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_SIDE_STRAIGHT_HPP Chris@102: Chris@102: #include Chris@102: Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: Chris@102: #include Chris@102: #include Chris@102: Chris@102: Chris@102: Chris@102: namespace boost { namespace geometry Chris@102: { Chris@102: Chris@102: namespace strategy { namespace buffer Chris@102: { Chris@102: Chris@102: Chris@102: Chris@102: /*! Chris@102: \brief Let the buffer use straight sides along segments (the default) Chris@102: \ingroup strategies Chris@102: \details This strategy can be used as SideStrategy for the buffer algorithm. Chris@102: It is currently the only provided strategy for this purpose Chris@102: Chris@102: \qbk{ Chris@102: [heading Example] Chris@102: See the examples for other buffer strategies\, for example Chris@102: [link geometry.reference.strategies.strategy_buffer_join_round join_round] Chris@102: [heading See also] Chris@102: \* [link geometry.reference.algorithms.buffer.buffer_7_with_strategies buffer (with strategies)] Chris@102: } Chris@102: */ Chris@102: class side_straight Chris@102: { Chris@102: public : Chris@102: #ifndef DOXYGEN_SHOULD_SKIP_THIS Chris@102: template Chris@102: < Chris@102: typename Point, Chris@102: typename OutputRange, Chris@102: typename DistanceStrategy Chris@102: > Chris@102: static inline void apply( Chris@102: Point const& input_p1, Point const& input_p2, Chris@102: strategy::buffer::buffer_side_selector side, Chris@102: DistanceStrategy const& distance, Chris@102: OutputRange& output_range) Chris@102: { Chris@102: typedef typename coordinate_type::type coordinate_type; 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: // Generate a block along (left or right of) the segment Chris@102: Chris@102: // Simulate a vector d (dx,dy) Chris@102: coordinate_type const dx = get<0>(input_p2) - get<0>(input_p1); Chris@102: coordinate_type const dy = get<1>(input_p2) - get<1>(input_p1); Chris@102: Chris@102: // For normalization [0,1] (=dot product d.d, sqrt) Chris@102: promoted_type const length = geometry::math::sqrt(dx * dx + dy * dy); Chris@102: Chris@102: if (geometry::math::equals(length, 0)) Chris@102: { Chris@102: // Coordinates are simplified and therefore most often not equal. Chris@102: // But if simplify is skipped, or for lines with two Chris@102: // equal points, length is 0 and we cannot generate output. Chris@102: return; Chris@102: } Chris@102: Chris@102: // Generate the normalized perpendicular p, to the left (ccw) Chris@102: promoted_type const px = -dy / length; Chris@102: promoted_type const py = dx / length; Chris@102: Chris@102: promoted_type const d = distance.apply(input_p1, input_p2, side); Chris@102: Chris@102: output_range.resize(2); Chris@102: Chris@102: set<0>(output_range.front(), get<0>(input_p1) + px * d); Chris@102: set<1>(output_range.front(), get<1>(input_p1) + py * d); Chris@102: set<0>(output_range.back(), get<0>(input_p2) + px * d); Chris@102: set<1>(output_range.back(), get<1>(input_p2) + py * d); 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_SIDE_STRAIGHT_HPP