radius.hpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  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. // Copyright (c) 2024 Adam Wulkiewicz, Lodz, Poland.
  6. // This file was modified by Oracle on 2014-2020.
  7. // Modifications copyright (c) 2014-2020 Oracle and/or its affiliates.
  8. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  9. // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
  10. // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
  11. // Use, modification and distribution is subject to the Boost Software License,
  12. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  13. // http://www.boost.org/LICENSE_1_0.txt)
  14. #ifndef BOOST_GEOMETRY_CORE_RADIUS_HPP
  15. #define BOOST_GEOMETRY_CORE_RADIUS_HPP
  16. #include <cstddef>
  17. #include <boost/geometry/core/static_assert.hpp>
  18. #include <boost/geometry/core/tag.hpp>
  19. #include <boost/geometry/core/tags.hpp>
  20. #include <boost/geometry/util/type_traits_std.hpp>
  21. namespace boost { namespace geometry
  22. {
  23. namespace traits
  24. {
  25. /*!
  26. \brief Traits class to get/set radius of a circle/sphere/(ellipse)
  27. \details the radius access meta-functions give read/write access to the radius of a circle or a sphere,
  28. or to the major/minor axis or an ellipse, or to one of the 3 equatorial radii of an ellipsoid.
  29. It should be specialized per geometry, in namespace core_dispatch. Those specializations should
  30. forward the call via traits to the geometry class, which could be specified by the user.
  31. There is a corresponding generic radius_get and radius_set function
  32. \par Geometries:
  33. - n-sphere (circle,sphere)
  34. - upcoming ellipse
  35. \par Specializations should provide:
  36. - inline static T get(Geometry const& geometry)
  37. - inline static void set(Geometry& geometry, T const& radius)
  38. \ingroup traits
  39. */
  40. template <typename Geometry, std::size_t Dimension>
  41. struct radius_access {};
  42. /*!
  43. \brief Traits class indicating the type (double,float,...) of the radius of a circle or a sphere
  44. \par Geometries:
  45. - n-sphere (circle,sphere)
  46. - upcoming ellipse
  47. \par Specializations should provide:
  48. - typedef T type (double,float,int,etc)
  49. \ingroup traits
  50. */
  51. template <typename Geometry>
  52. struct radius_type {};
  53. } // namespace traits
  54. #ifndef DOXYGEN_NO_DISPATCH
  55. namespace core_dispatch
  56. {
  57. template <typename Tag, typename Geometry>
  58. struct radius_type
  59. {
  60. BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
  61. "Not implemented for this Geometry Tag type.",
  62. Geometry, Tag);
  63. //typedef core_dispatch_specialization_required type;
  64. };
  65. /*!
  66. \brief radius access meta-functions, used by concept n-sphere and upcoming ellipse.
  67. */
  68. template
  69. <
  70. typename Tag,
  71. typename Geometry,
  72. std::size_t Dimension,
  73. bool IsPointer
  74. >
  75. struct radius_access
  76. {
  77. BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
  78. "Not implemented for this Geometry Tag type.",
  79. Geometry, Tag);
  80. //static inline CoordinateType get(Geometry const& ) {}
  81. //static inline void set(Geometry& g, CoordinateType const& value) {}
  82. };
  83. } // namespace core_dispatch
  84. #endif // DOXYGEN_NO_DISPATCH
  85. /*!
  86. \brief Metafunction to get the type of radius of a circle / sphere / ellipse / etc.
  87. \ingroup access
  88. \tparam Geometry the type of geometry
  89. */
  90. template <typename Geometry>
  91. struct radius_type
  92. {
  93. using type = typename core_dispatch::radius_type
  94. <
  95. tag_t<Geometry>,
  96. util::remove_cptrref_t<Geometry>
  97. >::type;
  98. };
  99. template <typename Geometry>
  100. using radius_type_t = typename radius_type<Geometry>::type;
  101. /*!
  102. \brief Function to get radius of a circle / sphere / ellipse / etc.
  103. \return radius The radius for a given axis
  104. \ingroup access
  105. \param geometry the geometry to get the radius from
  106. \tparam I index of the axis
  107. */
  108. template <std::size_t I, typename Geometry>
  109. inline radius_type_t<Geometry> get_radius(Geometry const& geometry)
  110. {
  111. return core_dispatch::radius_access
  112. <
  113. tag_t<Geometry>,
  114. util::remove_cptrref_t<Geometry>,
  115. I,
  116. std::is_pointer<Geometry>::value
  117. >::get(geometry);
  118. }
  119. /*!
  120. \brief Function to set the radius of a circle / sphere / ellipse / etc.
  121. \ingroup access
  122. \tparam I index of the axis
  123. \param geometry the geometry to change
  124. \param radius the radius to set
  125. */
  126. template <std::size_t I, typename Geometry>
  127. inline void set_radius(Geometry& geometry,
  128. radius_type_t<Geometry> const& radius)
  129. {
  130. core_dispatch::radius_access
  131. <
  132. tag_t<Geometry>,
  133. util::remove_cptrref_t<Geometry>,
  134. I,
  135. std::is_pointer<Geometry>::value
  136. >::set(geometry, radius);
  137. }
  138. #ifndef DOXYGEN_NO_DETAIL
  139. namespace detail
  140. {
  141. template <typename Tag, typename Geometry, std::size_t Dimension>
  142. struct radius_access
  143. {
  144. static inline radius_type_t<Geometry> get(Geometry const& geometry)
  145. {
  146. return traits::radius_access<Geometry, Dimension>::get(geometry);
  147. }
  148. static inline void set(Geometry& geometry,
  149. radius_type_t<Geometry> const& value)
  150. {
  151. traits::radius_access<Geometry, Dimension>::set(geometry, value);
  152. }
  153. };
  154. } // namespace detail
  155. #endif // DOXYGEN_NO_DETAIL
  156. #ifndef DOXYGEN_NO_DISPATCH
  157. namespace core_dispatch
  158. {
  159. template
  160. <
  161. typename Tag,
  162. typename Geometry,
  163. std::size_t Dimension
  164. >
  165. struct radius_access<Tag, Geometry, Dimension, true>
  166. {
  167. static inline radius_type_t<Geometry> get(const Geometry * geometry)
  168. {
  169. return radius_access
  170. <
  171. Tag,
  172. Geometry,
  173. Dimension,
  174. std::is_pointer<Geometry>::value
  175. >::get(*geometry);
  176. }
  177. static inline void set(Geometry * geometry, radius_type_t<Geometry> const& value)
  178. {
  179. return radius_access
  180. <
  181. Tag,
  182. Geometry,
  183. Dimension,
  184. std::is_pointer<Geometry>::value
  185. >::set(*geometry, value);
  186. }
  187. };
  188. template <typename Geometry>
  189. struct radius_type<srs_sphere_tag, Geometry>
  190. {
  191. using type = typename traits::radius_type<Geometry>::type;
  192. };
  193. template <typename Geometry, std::size_t Dimension>
  194. struct radius_access<srs_sphere_tag, Geometry, Dimension, false>
  195. : detail::radius_access<srs_sphere_tag, Geometry, Dimension>
  196. {
  197. //BOOST_STATIC_ASSERT(Dimension == 0);
  198. BOOST_STATIC_ASSERT(Dimension < 3);
  199. };
  200. template <typename Geometry>
  201. struct radius_type<srs_spheroid_tag, Geometry>
  202. {
  203. using type = typename traits::radius_type<Geometry>::type;
  204. };
  205. template <typename Geometry, std::size_t Dimension>
  206. struct radius_access<srs_spheroid_tag, Geometry, Dimension, false>
  207. : detail::radius_access<srs_spheroid_tag, Geometry, Dimension>
  208. {
  209. //BOOST_STATIC_ASSERT(Dimension == 0 || Dimension == 2);
  210. BOOST_STATIC_ASSERT(Dimension < 3);
  211. };
  212. } // namespace core_dispatch
  213. #endif // DOXYGEN_NO_DISPATCH
  214. }} // namespace boost::geometry
  215. #endif // BOOST_GEOMETRY_CORE_RADIUS_HPP