]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/boost/boost/geometry/strategy/cartesian/precise_area.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / geometry / strategy / cartesian / precise_area.hpp
diff --git a/ceph/src/boost/boost/geometry/strategy/cartesian/precise_area.hpp b/ceph/src/boost/boost/geometry/strategy/cartesian/precise_area.hpp
new file mode 100644 (file)
index 0000000..f9b09de
--- /dev/null
@@ -0,0 +1,117 @@
+// 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