]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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( (concepts::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 | concepts::Point<ConstOrNonConstPoint>, | |
93 | concepts::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 |