1 // Boost.Geometry (aka GGL, Generic Geometry Library)
3 // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
4 // Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
5 // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
7 // This file was modified by Oracle on 2021.
8 // Modifications copyright (c) 2021 Oracle and/or its affiliates.
9 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
11 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
12 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
14 // Use, modification and distribution is subject to the Boost Software License,
15 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
16 // http://www.boost.org/LICENSE_1_0.txt)
18 #ifndef BOOST_GEOMETRY_ARITHMETIC_ARITHMETIC_HPP
19 #define BOOST_GEOMETRY_ARITHMETIC_ARITHMETIC_HPP
23 #include <boost/call_traits.hpp>
24 #include <boost/concept/requires.hpp>
26 #include <boost/geometry/core/coordinate_type.hpp>
27 #include <boost/geometry/geometries/concepts/point_concept.hpp>
28 #include <boost/geometry/util/algorithm.hpp>
29 #include <boost/geometry/util/select_coordinate_type.hpp>
32 namespace boost { namespace geometry
35 #ifndef DOXYGEN_NO_DETAIL
40 template <typename Point>
43 typedef typename boost::call_traits
45 typename coordinate_type<Point>::type
51 #endif // DOXYGEN_NO_DETAIL
54 \brief Adds the same value to each coordinate of a point
57 \tparam Point \tparam_point
59 \param value value to add
61 template <typename Point>
62 inline void add_value(Point& p, typename detail::param<Point>::type value)
64 BOOST_CONCEPT_ASSERT( (concepts::Point<Point>) );
66 detail::for_each_dimension<Point>([&](auto index)
68 set<index>(p, get<index>(p) + value);
73 \brief Adds a point to another
75 \details The coordinates of the second point will be added to those of the first point.
76 The second point is not modified.
77 \tparam Point1 \tparam_point
78 \tparam Point2 \tparam_point
80 \param p2 second point
82 template <typename Point1, typename Point2>
83 inline void add_point(Point1& p1, Point2 const& p2)
85 BOOST_CONCEPT_ASSERT( (concepts::Point<Point1>) );
86 BOOST_CONCEPT_ASSERT( (concepts::ConstPoint<Point2>) );
88 detail::for_each_dimension<Point1>([&](auto index)
90 using calc_t = typename select_coordinate_type<Point1, Point2>::type;
91 set<index>(p1, calc_t(get<index>(p1)) + calc_t(get<index>(p2)));
96 \brief Subtracts the same value to each coordinate of a point
99 \tparam Point \tparam_point
101 \param value value to subtract
103 template <typename Point>
104 inline void subtract_value(Point& p, typename detail::param<Point>::type value)
106 BOOST_CONCEPT_ASSERT( (concepts::Point<Point>) );
108 detail::for_each_dimension<Point>([&](auto index)
110 set<index>(p, get<index>(p) - value);
115 \brief Subtracts a point to another
117 \details The coordinates of the second point will be subtracted to those of the first point.
118 The second point is not modified.
119 \tparam Point1 \tparam_point
120 \tparam Point2 \tparam_point
121 \param p1 first point
122 \param p2 second point
124 template <typename Point1, typename Point2>
125 inline void subtract_point(Point1& p1, Point2 const& p2)
127 BOOST_CONCEPT_ASSERT( (concepts::Point<Point1>) );
128 BOOST_CONCEPT_ASSERT( (concepts::ConstPoint<Point2>) );
130 detail::for_each_dimension<Point1>([&](auto index)
132 using calc_t = typename select_coordinate_type<Point1, Point2>::type;
133 set<index>(p1, calc_t(get<index>(p1)) - calc_t(get<index>(p2)));
138 \brief Multiplies each coordinate of a point by the same value
141 \tparam Point \tparam_point
143 \param value value to multiply by
145 template <typename Point>
146 inline void multiply_value(Point& p, typename detail::param<Point>::type value)
148 BOOST_CONCEPT_ASSERT( (concepts::Point<Point>) );
150 detail::for_each_dimension<Point>([&](auto index)
152 set<index>(p, get<index>(p) * value);
157 \brief Multiplies a point by another
159 \details The coordinates of the first point will be multiplied 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 \note This is *not* a dot, cross or wedge product. It is a mere field-by-field multiplication.
167 template <typename Point1, typename Point2>
168 inline void multiply_point(Point1& p1, Point2 const& p2)
170 BOOST_CONCEPT_ASSERT( (concepts::Point<Point1>) );
171 BOOST_CONCEPT_ASSERT( (concepts::ConstPoint<Point2>) );
173 detail::for_each_dimension<Point1>([&](auto index)
175 using calc_t = typename select_coordinate_type<Point1, Point2>::type;
176 set<index>(p1, calc_t(get<index>(p1)) * calc_t(get<index>(p2)));
181 \brief Divides each coordinate of the same point by a value
184 \tparam Point \tparam_point
186 \param value value to divide by
188 template <typename Point>
189 inline void divide_value(Point& p, typename detail::param<Point>::type value)
191 BOOST_CONCEPT_ASSERT( (concepts::Point<Point>) );
193 detail::for_each_dimension<Point>([&](auto index)
195 set<index>(p, get<index>(p) / value);
200 \brief Divides a point by another
202 \details The coordinates of the first point will be divided by those of the second point.
203 The second point is not modified.
204 \tparam Point1 \tparam_point
205 \tparam Point2 \tparam_point
206 \param p1 first point
207 \param p2 second point
209 template <typename Point1, typename Point2>
210 inline void divide_point(Point1& p1, Point2 const& p2)
212 BOOST_CONCEPT_ASSERT( (concepts::Point<Point1>) );
213 BOOST_CONCEPT_ASSERT( (concepts::ConstPoint<Point2>) );
215 detail::for_each_dimension<Point1>([&](auto index)
217 using calc_t = typename select_coordinate_type<Point1, Point2>::type;
218 set<index>(p1, calc_t(get<index>(p1)) / calc_t(get<index>(p2)));
223 \brief Assign each coordinate of a point the same value
226 \tparam Point \tparam_point
228 \param value value to assign
230 template <typename Point>
231 inline void assign_value(Point& p, typename detail::param<Point>::type value)
233 BOOST_CONCEPT_ASSERT( (concepts::Point<Point>) );
235 detail::for_each_dimension<Point>([&](auto index)
237 set<index>(p, value);
242 \brief Assign a point with another
244 \details The coordinates of the first point will be assigned those of the second point.
245 The second point is not modified.
246 \tparam Point1 \tparam_point
247 \tparam Point2 \tparam_point
248 \param p1 first point
249 \param p2 second point
251 template <typename Point1, typename Point2>
252 inline void assign_point(Point1& p1, Point2 const& p2)
254 BOOST_CONCEPT_ASSERT( (concepts::Point<Point1>) );
255 BOOST_CONCEPT_ASSERT( (concepts::ConstPoint<Point2>) );
257 detail::for_each_dimension<Point1>([&](auto index)
259 set<index>(p1, get<index>(p2));
264 }} // namespace boost::geometry
267 #endif // BOOST_GEOMETRY_ARITHMETIC_ARITHMETIC_HPP