arithmetic.hpp 7.4 KB

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