Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:36:51

0001 // Boost.Geometry
0002 
0003 // Copyright (c) 2020, Oracle and/or its affiliates.
0004 
0005 // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
0006 
0007 // Licensed under the Boost Software License version 1.0.
0008 // http://www.boost.org/users/license.html
0009 
0010 #ifndef BOOST_GEOMETRY_STRATEGY_CARTESIAN_PRECISE_AREA_HPP
0011 #define BOOST_GEOMETRY_STRATEGY_CARTESIAN_PRECISE_AREA_HPP
0012 
0013 #include <boost/mpl/if.hpp>
0014 
0015 //#include <boost/geometry/arithmetic/determinant.hpp>
0016 #include <boost/geometry/core/access.hpp>
0017 #include <boost/geometry/core/coordinate_type.hpp>
0018 #include <boost/geometry/core/coordinate_dimension.hpp>
0019 #include <boost/geometry/strategy/area.hpp>
0020 #include <boost/geometry/util/select_most_precise.hpp>
0021 #include <boost/geometry/util/precise_math.hpp>
0022 
0023 namespace boost { namespace geometry
0024 {
0025 
0026 namespace strategy { namespace area
0027 {
0028 
0029 /*!
0030 \brief Cartesian area calculation
0031 \ingroup strategies
0032 \details Calculates cartesian area using the trapezoidal rule and precise
0033          summation (useful to increase precision with floating point arithmetic)
0034 \tparam CalculationType \tparam_calculation
0035 
0036 \qbk{
0037 [heading See also]
0038 [link geometry.reference.algorithms.area.area_2_with_strategy area (with strategy)]
0039 }
0040 
0041 */
0042 template
0043 <
0044     typename CalculationType = void
0045 >
0046 class precise_cartesian
0047 {
0048 public :
0049     template <typename Geometry>
0050     struct result_type
0051         : strategy::area::detail::result_type
0052             <
0053                 Geometry,
0054                 CalculationType
0055             >
0056     {};
0057 
0058     template <typename Geometry>
0059     class state
0060     {
0061         friend class precise_cartesian;
0062 
0063         typedef typename result_type<Geometry>::type return_type;
0064 
0065     public:
0066         inline state()
0067             : sum1(0)
0068             , sum2(0)
0069         {
0070             // Strategy supports only 2D areas
0071             assert_dimension<Geometry, 2>();
0072         }
0073 
0074     private:
0075         inline return_type area() const
0076         {
0077             return_type const two = 2;
0078             return (sum1 + sum2) / two;
0079         }
0080 
0081         return_type sum1;
0082         return_type sum2;
0083     };
0084 
0085     template <typename PointOfSegment, typename Geometry>
0086     static inline void apply(PointOfSegment const& p1,
0087                              PointOfSegment const& p2,
0088                              state<Geometry>& st)
0089     {
0090         typedef typename state<Geometry>::return_type return_type;
0091 
0092         auto const det = (return_type(get<0>(p1)) + return_type(get<0>(p2)))
0093                 * (return_type(get<1>(p1)) - return_type(get<1>(p2)));
0094 
0095         auto const res = boost::geometry::detail::precise_math::two_sum(st.sum1, det);
0096 
0097         st.sum1 = res[0];
0098         st.sum2 += res[1];
0099     }
0100 
0101     template <typename Geometry>
0102     static inline auto result(state<Geometry>& st)
0103     {
0104         return st.area();
0105     }
0106 
0107 };
0108 
0109 
0110 }} // namespace strategy::area
0111 
0112 
0113 
0114 }} // namespace boost::geometry
0115 
0116 
0117 #endif // BOOST_GEOMETRY_STRATEGY_CARTESIAN_PRECISE_AREA_HPP