1 | // Boost.Geometry (aka GGL, Generic Geometry Library) |
2 | |
3 | // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. |
4 | // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. |
5 | // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. |
6 | |
7 | // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library |
8 | // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. |
9 | |
10 | // Use, modification and distribution is subject to the Boost Software License, |
11 | // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at |
12 | // http://www.boost.org/LICENSE_1_0.txt) |
13 | |
14 | #ifndef BOOST_GEOMETRY_GEOMETRIES_SEGMENT_HPP |
15 | #define BOOST_GEOMETRY_GEOMETRIES_SEGMENT_HPP |
16 | |
17 | #include <cstddef> |
18 | |
19 | #include <boost/concept/assert.hpp> |
20 | #include <boost/mpl/if.hpp> |
21 | #include <boost/type_traits/is_const.hpp> |
22 | |
23 | #include <boost/geometry/geometries/concepts/point_concept.hpp> |
24 | |
25 | namespace boost { namespace geometry |
26 | { |
27 | |
28 | namespace model |
29 | { |
30 | |
31 | /*! |
32 | \brief Class segment: small class containing two points |
33 | \ingroup geometries |
34 | \details From Wikipedia: In geometry, a line segment is a part of a line that is bounded |
35 | by two distinct end points, and contains every point on the line between its end points. |
36 | \note There is also a point-referring-segment, class referring_segment, |
37 | containing point references, where points are NOT copied |
38 | |
39 | \qbk{[include reference/geometries/segment.qbk]} |
40 | \qbk{before.synopsis, |
41 | [heading Model of] |
42 | [link geometry.reference.concepts.concept_segment Segment Concept] |
43 | } |
44 | */ |
45 | template<typename Point> |
46 | class segment : public std::pair<Point, Point> |
47 | { |
48 | BOOST_CONCEPT_ASSERT( (concept::Point<Point>) ); |
49 | |
50 | public : |
51 | |
52 | #ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS |
53 | /// \constructor_default_no_init |
54 | segment() = default; |
55 | #else |
56 | /// \constructor_default_no_init |
57 | inline segment() |
58 | {} |
59 | #endif |
60 | |
61 | /*! |
62 | \brief Constructor taking the first and the second point |
63 | */ |
64 | inline segment(Point const& p1, Point const& p2) |
65 | { |
66 | this->first = p1; |
67 | this->second = p2; |
68 | } |
69 | }; |
70 | |
71 | |
72 | /*! |
73 | \brief Class segment: small class containing two (templatized) point references |
74 | \ingroup geometries |
75 | \details From Wikipedia: In geometry, a line segment is a part of a line that is bounded |
76 | by two distinct end points, and contains every point on the line between its end points. |
77 | \note The structure is like std::pair, and can often be used interchangeable. |
78 | Difference is that it refers to points, does not have points. |
79 | \note Like std::pair, points are public available. |
80 | \note type is const or non const, so geometry::segment<P> or geometry::segment<P const> |
81 | \note We cannot derive from std::pair<P&, P&> because of |
82 | reference assignments. |
83 | \tparam ConstOrNonConstPoint point type of the segment, maybe a point or a const point |
84 | */ |
85 | template<typename ConstOrNonConstPoint> |
86 | class referring_segment |
87 | { |
88 | BOOST_CONCEPT_ASSERT( ( |
89 | typename boost::mpl::if_ |
90 | < |
91 | boost::is_const<ConstOrNonConstPoint>, |
92 | concept::Point<ConstOrNonConstPoint>, |
93 | concept::ConstPoint<ConstOrNonConstPoint> |
94 | > |
95 | ) ); |
96 | |
97 | typedef ConstOrNonConstPoint point_type; |
98 | |
99 | public: |
100 | |
101 | point_type& first; |
102 | point_type& second; |
103 | |
104 | /*! |
105 | \brief Constructor taking the first and the second point |
106 | */ |
107 | inline referring_segment(point_type& p1, point_type& p2) |
108 | : first(p1) |
109 | , second(p2) |
110 | {} |
111 | }; |
112 | |
113 | |
114 | } // namespace model |
115 | |
116 | |
117 | // Traits specializations for segment above |
118 | #ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS |
119 | namespace traits |
120 | { |
121 | |
122 | template <typename Point> |
123 | struct tag<model::segment<Point> > |
124 | { |
125 | typedef segment_tag type; |
126 | }; |
127 | |
128 | template <typename Point> |
129 | struct point_type<model::segment<Point> > |
130 | { |
131 | typedef Point type; |
132 | }; |
133 | |
134 | template <typename Point, std::size_t Dimension> |
135 | struct indexed_access<model::segment<Point>, 0, Dimension> |
136 | { |
137 | typedef model::segment<Point> segment_type; |
138 | typedef typename geometry::coordinate_type<segment_type>::type coordinate_type; |
139 | |
140 | static inline coordinate_type get(segment_type const& s) |
141 | { |
142 | return geometry::get<Dimension>(s.first); |
143 | } |
144 | |
145 | static inline void set(segment_type& s, coordinate_type const& value) |
146 | { |
147 | geometry::set<Dimension>(s.first, value); |
148 | } |
149 | }; |
150 | |
151 | |
152 | template <typename Point, std::size_t Dimension> |
153 | struct indexed_access<model::segment<Point>, 1, Dimension> |
154 | { |
155 | typedef model::segment<Point> segment_type; |
156 | typedef typename geometry::coordinate_type<segment_type>::type coordinate_type; |
157 | |
158 | static inline coordinate_type get(segment_type const& s) |
159 | { |
160 | return geometry::get<Dimension>(s.second); |
161 | } |
162 | |
163 | static inline void set(segment_type& s, coordinate_type const& value) |
164 | { |
165 | geometry::set<Dimension>(s.second, value); |
166 | } |
167 | }; |
168 | |
169 | |
170 | template <typename ConstOrNonConstPoint> |
171 | struct tag<model::referring_segment<ConstOrNonConstPoint> > |
172 | { |
173 | typedef segment_tag type; |
174 | }; |
175 | |
176 | template <typename ConstOrNonConstPoint> |
177 | struct point_type<model::referring_segment<ConstOrNonConstPoint> > |
178 | { |
179 | typedef ConstOrNonConstPoint type; |
180 | }; |
181 | |
182 | template <typename ConstOrNonConstPoint, std::size_t Dimension> |
183 | struct indexed_access<model::referring_segment<ConstOrNonConstPoint>, 0, Dimension> |
184 | { |
185 | typedef model::referring_segment<ConstOrNonConstPoint> segment_type; |
186 | typedef typename geometry::coordinate_type<segment_type>::type coordinate_type; |
187 | |
188 | static inline coordinate_type get(segment_type const& s) |
189 | { |
190 | return geometry::get<Dimension>(s.first); |
191 | } |
192 | |
193 | static inline void set(segment_type& s, coordinate_type const& value) |
194 | { |
195 | geometry::set<Dimension>(s.first, value); |
196 | } |
197 | }; |
198 | |
199 | |
200 | template <typename ConstOrNonConstPoint, std::size_t Dimension> |
201 | struct indexed_access<model::referring_segment<ConstOrNonConstPoint>, 1, Dimension> |
202 | { |
203 | typedef model::referring_segment<ConstOrNonConstPoint> segment_type; |
204 | typedef typename geometry::coordinate_type<segment_type>::type coordinate_type; |
205 | |
206 | static inline coordinate_type get(segment_type const& s) |
207 | { |
208 | return geometry::get<Dimension>(s.second); |
209 | } |
210 | |
211 | static inline void set(segment_type& s, coordinate_type const& value) |
212 | { |
213 | geometry::set<Dimension>(s.second, value); |
214 | } |
215 | }; |
216 | |
217 | |
218 | |
219 | } // namespace traits |
220 | #endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS |
221 | |
222 | }} // namespace boost::geometry |
223 | |
224 | #endif // BOOST_GEOMETRY_GEOMETRIES_SEGMENT_HPP |
225 | |