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 */ segment(Point const & p1,Point const & p2)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 */ referring_segment(point_type & p1,point_type & p2)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 getboost::geometry::traits::indexed_access140 static inline coordinate_type get(segment_type const& s) 141 { 142 return geometry::get<Dimension>(s.first); 143 } 144 setboost::geometry::traits::indexed_access145 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 getboost::geometry::traits::indexed_access158 static inline coordinate_type get(segment_type const& s) 159 { 160 return geometry::get<Dimension>(s.second); 161 } 162 setboost::geometry::traits::indexed_access163 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 getboost::geometry::traits::indexed_access188 static inline coordinate_type get(segment_type const& s) 189 { 190 return geometry::get<Dimension>(s.first); 191 } 192 setboost::geometry::traits::indexed_access193 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 getboost::geometry::traits::indexed_access206 static inline coordinate_type get(segment_type const& s) 207 { 208 return geometry::get<Dimension>(s.second); 209 } 210 setboost::geometry::traits::indexed_access211 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