123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- // Boost.Geometry
- // Copyright (c) 2020, Oracle and/or its affiliates.
- // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
- // Licensed under the Boost Software License version 1.0.
- // http://www.boost.org/users/license.html
- #ifndef BOOST_GEOMETRY_STRATEGY_CARTESIAN_PRECISE_AREA_HPP
- #define BOOST_GEOMETRY_STRATEGY_CARTESIAN_PRECISE_AREA_HPP
- #include <boost/mpl/if.hpp>
- //#include <boost/geometry/arithmetic/determinant.hpp>
- #include <boost/geometry/core/access.hpp>
- #include <boost/geometry/core/coordinate_type.hpp>
- #include <boost/geometry/core/coordinate_dimension.hpp>
- #include <boost/geometry/strategy/area.hpp>
- #include <boost/geometry/util/select_most_precise.hpp>
- #include <boost/geometry/util/precise_math.hpp>
- namespace boost { namespace geometry
- {
- namespace strategy { namespace area
- {
- /*!
- \brief Cartesian area calculation
- \ingroup strategies
- \details Calculates cartesian area using the trapezoidal rule and precise
- summation (useful to increase precision with floating point arithmetic)
- \tparam CalculationType \tparam_calculation
- \qbk{
- [heading See also]
- [link geometry.reference.algorithms.area.area_2_with_strategy area (with strategy)]
- }
- */
- template
- <
- typename CalculationType = void
- >
- class precise_cartesian
- {
- public :
- template <typename Geometry>
- struct result_type
- : strategy::area::detail::result_type
- <
- Geometry,
- CalculationType
- >
- {};
- template <typename Geometry>
- class state
- {
- friend class precise_cartesian;
- typedef typename result_type<Geometry>::type return_type;
- public:
- inline state()
- : sum1(0)
- , sum2(0)
- {
- // Strategy supports only 2D areas
- assert_dimension<Geometry, 2>();
- }
- private:
- inline return_type area() const
- {
- return_type const two = 2;
- return (sum1 + sum2) / two;
- }
- return_type sum1;
- return_type sum2;
- };
- template <typename PointOfSegment, typename Geometry>
- static inline void apply(PointOfSegment const& p1,
- PointOfSegment const& p2,
- state<Geometry>& st)
- {
- typedef typename state<Geometry>::return_type return_type;
- auto const det = (return_type(get<0>(p1)) + return_type(get<0>(p2)))
- * (return_type(get<1>(p1)) - return_type(get<1>(p2)));
- auto const res = boost::geometry::detail::precise_math::two_sum(st.sum1, det);
- st.sum1 = res[0];
- st.sum2 += res[1];
- }
- template <typename Geometry>
- static inline auto result(state<Geometry>& st)
- {
- return st.area();
- }
- };
- }} // namespace strategy::area
- }} // namespace boost::geometry
- #endif // BOOST_GEOMETRY_STRATEGY_CARTESIAN_PRECISE_AREA_HPP
|