segment.hpp 6.7 KB

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