Chris@102
|
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
|
Chris@102
|
2 // Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands.
|
Chris@102
|
3 // Use, modification and distribution is subject to the Boost Software License,
|
Chris@102
|
4 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@102
|
5 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@102
|
6
|
Chris@102
|
7 #ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_SIDE_STRAIGHT_HPP
|
Chris@102
|
8 #define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_SIDE_STRAIGHT_HPP
|
Chris@102
|
9
|
Chris@102
|
10 #include <cstddef>
|
Chris@102
|
11
|
Chris@102
|
12 #include <boost/geometry/core/coordinate_type.hpp>
|
Chris@102
|
13 #include <boost/geometry/core/access.hpp>
|
Chris@102
|
14 #include <boost/geometry/util/math.hpp>
|
Chris@102
|
15 #include <boost/geometry/util/select_most_precise.hpp>
|
Chris@102
|
16
|
Chris@102
|
17 #include <boost/geometry/strategies/buffer.hpp>
|
Chris@102
|
18 #include <boost/geometry/strategies/side.hpp>
|
Chris@102
|
19
|
Chris@102
|
20
|
Chris@102
|
21
|
Chris@102
|
22 namespace boost { namespace geometry
|
Chris@102
|
23 {
|
Chris@102
|
24
|
Chris@102
|
25 namespace strategy { namespace buffer
|
Chris@102
|
26 {
|
Chris@102
|
27
|
Chris@102
|
28
|
Chris@102
|
29
|
Chris@102
|
30 /*!
|
Chris@102
|
31 \brief Let the buffer use straight sides along segments (the default)
|
Chris@102
|
32 \ingroup strategies
|
Chris@102
|
33 \details This strategy can be used as SideStrategy for the buffer algorithm.
|
Chris@102
|
34 It is currently the only provided strategy for this purpose
|
Chris@102
|
35
|
Chris@102
|
36 \qbk{
|
Chris@102
|
37 [heading Example]
|
Chris@102
|
38 See the examples for other buffer strategies\, for example
|
Chris@102
|
39 [link geometry.reference.strategies.strategy_buffer_join_round join_round]
|
Chris@102
|
40 [heading See also]
|
Chris@102
|
41 \* [link geometry.reference.algorithms.buffer.buffer_7_with_strategies buffer (with strategies)]
|
Chris@102
|
42 }
|
Chris@102
|
43 */
|
Chris@102
|
44 class side_straight
|
Chris@102
|
45 {
|
Chris@102
|
46 public :
|
Chris@102
|
47 #ifndef DOXYGEN_SHOULD_SKIP_THIS
|
Chris@102
|
48 template
|
Chris@102
|
49 <
|
Chris@102
|
50 typename Point,
|
Chris@102
|
51 typename OutputRange,
|
Chris@102
|
52 typename DistanceStrategy
|
Chris@102
|
53 >
|
Chris@102
|
54 static inline void apply(
|
Chris@102
|
55 Point const& input_p1, Point const& input_p2,
|
Chris@102
|
56 strategy::buffer::buffer_side_selector side,
|
Chris@102
|
57 DistanceStrategy const& distance,
|
Chris@102
|
58 OutputRange& output_range)
|
Chris@102
|
59 {
|
Chris@102
|
60 typedef typename coordinate_type<Point>::type coordinate_type;
|
Chris@102
|
61 typedef typename geometry::select_most_precise
|
Chris@102
|
62 <
|
Chris@102
|
63 coordinate_type,
|
Chris@102
|
64 double
|
Chris@102
|
65 >::type promoted_type;
|
Chris@102
|
66
|
Chris@102
|
67 // Generate a block along (left or right of) the segment
|
Chris@102
|
68
|
Chris@102
|
69 // Simulate a vector d (dx,dy)
|
Chris@102
|
70 coordinate_type const dx = get<0>(input_p2) - get<0>(input_p1);
|
Chris@102
|
71 coordinate_type const dy = get<1>(input_p2) - get<1>(input_p1);
|
Chris@102
|
72
|
Chris@102
|
73 // For normalization [0,1] (=dot product d.d, sqrt)
|
Chris@102
|
74 promoted_type const length = geometry::math::sqrt(dx * dx + dy * dy);
|
Chris@102
|
75
|
Chris@102
|
76 if (geometry::math::equals(length, 0))
|
Chris@102
|
77 {
|
Chris@102
|
78 // Coordinates are simplified and therefore most often not equal.
|
Chris@102
|
79 // But if simplify is skipped, or for lines with two
|
Chris@102
|
80 // equal points, length is 0 and we cannot generate output.
|
Chris@102
|
81 return;
|
Chris@102
|
82 }
|
Chris@102
|
83
|
Chris@102
|
84 // Generate the normalized perpendicular p, to the left (ccw)
|
Chris@102
|
85 promoted_type const px = -dy / length;
|
Chris@102
|
86 promoted_type const py = dx / length;
|
Chris@102
|
87
|
Chris@102
|
88 promoted_type const d = distance.apply(input_p1, input_p2, side);
|
Chris@102
|
89
|
Chris@102
|
90 output_range.resize(2);
|
Chris@102
|
91
|
Chris@102
|
92 set<0>(output_range.front(), get<0>(input_p1) + px * d);
|
Chris@102
|
93 set<1>(output_range.front(), get<1>(input_p1) + py * d);
|
Chris@102
|
94 set<0>(output_range.back(), get<0>(input_p2) + px * d);
|
Chris@102
|
95 set<1>(output_range.back(), get<1>(input_p2) + py * d);
|
Chris@102
|
96 }
|
Chris@102
|
97 #endif // DOXYGEN_SHOULD_SKIP_THIS
|
Chris@102
|
98 };
|
Chris@102
|
99
|
Chris@102
|
100
|
Chris@102
|
101 }} // namespace strategy::buffer
|
Chris@102
|
102
|
Chris@102
|
103 }} // namespace boost::geometry
|
Chris@102
|
104
|
Chris@102
|
105 #endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_SIDE_STRAIGHT_HPP
|