arithmetic.hpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
  3. // Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
  4. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
  5. // This file was modified by Oracle on 2021.
  6. // Modifications copyright (c) 2021 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_ARITHMETIC_ARITHMETIC_HPP
  14. #define BOOST_GEOMETRY_ARITHMETIC_ARITHMETIC_HPP
  15. #include <functional>
  16. #include <boost/call_traits.hpp>
  17. #include <boost/concept/requires.hpp>
  18. #include <boost/geometry/core/coordinate_type.hpp>
  19. #include <boost/geometry/geometries/concepts/point_concept.hpp>
  20. #include <boost/geometry/util/algorithm.hpp>
  21. #include <boost/geometry/util/select_coordinate_type.hpp>
  22. namespace boost { namespace geometry
  23. {
  24. #ifndef DOXYGEN_NO_DETAIL
  25. namespace detail
  26. {
  27. template <typename Point>
  28. struct param
  29. {
  30. typedef typename boost::call_traits
  31. <
  32. typename coordinate_type<Point>::type
  33. >::param_type type;
  34. };
  35. } // namespace detail
  36. #endif // DOXYGEN_NO_DETAIL
  37. /*!
  38. \brief Adds the same value to each coordinate of a point
  39. \ingroup arithmetic
  40. \details
  41. \tparam Point \tparam_point
  42. \param p point
  43. \param value value to add
  44. */
  45. template <typename Point>
  46. inline void add_value(Point& p, typename detail::param<Point>::type value)
  47. {
  48. BOOST_CONCEPT_ASSERT( (concepts::Point<Point>) );
  49. detail::for_each_dimension<Point>([&](auto index)
  50. {
  51. set<index>(p, get<index>(p) + value);
  52. });
  53. }
  54. /*!
  55. \brief Adds a point to another
  56. \ingroup arithmetic
  57. \details The coordinates of the second point will be added to those of the first point.
  58. The second point is not modified.
  59. \tparam Point1 \tparam_point
  60. \tparam Point2 \tparam_point
  61. \param p1 first point
  62. \param p2 second point
  63. */
  64. template <typename Point1, typename Point2>
  65. inline void add_point(Point1& p1, Point2 const& p2)
  66. {
  67. BOOST_CONCEPT_ASSERT( (concepts::Point<Point1>) );
  68. BOOST_CONCEPT_ASSERT( (concepts::ConstPoint<Point2>) );
  69. detail::for_each_dimension<Point1>([&](auto index)
  70. {
  71. using calc_t = typename select_coordinate_type<Point1, Point2>::type;
  72. set<index>(p1, calc_t(get<index>(p1)) + calc_t(get<index>(p2)));
  73. });
  74. }
  75. /*!
  76. \brief Subtracts the same value to each coordinate of a point
  77. \ingroup arithmetic
  78. \details
  79. \tparam Point \tparam_point
  80. \param p point
  81. \param value value to subtract
  82. */
  83. template <typename Point>
  84. inline void subtract_value(Point& p, typename detail::param<Point>::type value)
  85. {
  86. BOOST_CONCEPT_ASSERT( (concepts::Point<Point>) );
  87. detail::for_each_dimension<Point>([&](auto index)
  88. {
  89. set<index>(p, get<index>(p) - value);
  90. });
  91. }
  92. /*!
  93. \brief Subtracts a point to another
  94. \ingroup arithmetic
  95. \details The coordinates of the second point will be subtracted to those of the first point.
  96. The second point is not modified.
  97. \tparam Point1 \tparam_point
  98. \tparam Point2 \tparam_point
  99. \param p1 first point
  100. \param p2 second point
  101. */
  102. template <typename Point1, typename Point2>
  103. inline void subtract_point(Point1& p1, Point2 const& p2)
  104. {
  105. BOOST_CONCEPT_ASSERT( (concepts::Point<Point1>) );
  106. BOOST_CONCEPT_ASSERT( (concepts::ConstPoint<Point2>) );
  107. detail::for_each_dimension<Point1>([&](auto index)
  108. {
  109. using calc_t = typename select_coordinate_type<Point1, Point2>::type;
  110. set<index>(p1, calc_t(get<index>(p1)) - calc_t(get<index>(p2)));
  111. });
  112. }
  113. /*!
  114. \brief Multiplies each coordinate of a point by the same value
  115. \ingroup arithmetic
  116. \details
  117. \tparam Point \tparam_point
  118. \param p point
  119. \param value value to multiply by
  120. */
  121. template <typename Point>
  122. inline void multiply_value(Point& p, typename detail::param<Point>::type value)
  123. {
  124. BOOST_CONCEPT_ASSERT( (concepts::Point<Point>) );
  125. detail::for_each_dimension<Point>([&](auto index)
  126. {
  127. set<index>(p, get<index>(p) * value);
  128. });
  129. }
  130. /*!
  131. \brief Multiplies a point by another
  132. \ingroup arithmetic
  133. \details The coordinates of the first point will be multiplied by those of the second point.
  134. The second point is not modified.
  135. \tparam Point1 \tparam_point
  136. \tparam Point2 \tparam_point
  137. \param p1 first point
  138. \param p2 second point
  139. \note This is *not* a dot, cross or wedge product. It is a mere field-by-field multiplication.
  140. */
  141. template <typename Point1, typename Point2>
  142. inline void multiply_point(Point1& p1, Point2 const& p2)
  143. {
  144. BOOST_CONCEPT_ASSERT( (concepts::Point<Point1>) );
  145. BOOST_CONCEPT_ASSERT( (concepts::ConstPoint<Point2>) );
  146. detail::for_each_dimension<Point1>([&](auto index)
  147. {
  148. using calc_t = typename select_coordinate_type<Point1, Point2>::type;
  149. set<index>(p1, calc_t(get<index>(p1)) * calc_t(get<index>(p2)));
  150. });
  151. }
  152. /*!
  153. \brief Divides each coordinate of the same point by a value
  154. \ingroup arithmetic
  155. \details
  156. \tparam Point \tparam_point
  157. \param p point
  158. \param value value to divide by
  159. */
  160. template <typename Point>
  161. inline void divide_value(Point& p, typename detail::param<Point>::type value)
  162. {
  163. BOOST_CONCEPT_ASSERT( (concepts::Point<Point>) );
  164. detail::for_each_dimension<Point>([&](auto index)
  165. {
  166. set<index>(p, get<index>(p) / value);
  167. });
  168. }
  169. /*!
  170. \brief Divides a point by another
  171. \ingroup arithmetic
  172. \details The coordinates of the first point will be divided by those of the second point.
  173. The second point is not modified.
  174. \tparam Point1 \tparam_point
  175. \tparam Point2 \tparam_point
  176. \param p1 first point
  177. \param p2 second point
  178. */
  179. template <typename Point1, typename Point2>
  180. inline void divide_point(Point1& p1, Point2 const& p2)
  181. {
  182. BOOST_CONCEPT_ASSERT( (concepts::Point<Point1>) );
  183. BOOST_CONCEPT_ASSERT( (concepts::ConstPoint<Point2>) );
  184. detail::for_each_dimension<Point1>([&](auto index)
  185. {
  186. using calc_t = typename select_coordinate_type<Point1, Point2>::type;
  187. set<index>(p1, calc_t(get<index>(p1)) / calc_t(get<index>(p2)));
  188. });
  189. }
  190. /*!
  191. \brief Assign each coordinate of a point the same value
  192. \ingroup arithmetic
  193. \details
  194. \tparam Point \tparam_point
  195. \param p point
  196. \param value value to assign
  197. */
  198. template <typename Point>
  199. inline void assign_value(Point& p, typename detail::param<Point>::type value)
  200. {
  201. BOOST_CONCEPT_ASSERT( (concepts::Point<Point>) );
  202. detail::for_each_dimension<Point>([&](auto index)
  203. {
  204. set<index>(p, value);
  205. });
  206. }
  207. /*!
  208. \brief Assign a point with another
  209. \ingroup arithmetic
  210. \details The coordinates of the first point will be assigned those of the second point.
  211. The second point is not modified.
  212. \tparam Point1 \tparam_point
  213. \tparam Point2 \tparam_point
  214. \param p1 first point
  215. \param p2 second point
  216. */
  217. template <typename Point1, typename Point2>
  218. inline void assign_point(Point1& p1, Point2 const& p2)
  219. {
  220. BOOST_CONCEPT_ASSERT( (concepts::Point<Point1>) );
  221. BOOST_CONCEPT_ASSERT( (concepts::ConstPoint<Point2>) );
  222. detail::for_each_dimension<Point1>([&](auto index)
  223. {
  224. set<index>(p1, get<index>(p2));
  225. });
  226. }
  227. }} // namespace boost::geometry
  228. #endif // BOOST_GEOMETRY_ARITHMETIC_ARITHMETIC_HPP