1 // Boost.Geometry (aka GGL, Generic Geometry Library) 2 3 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. 4 // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. 5 // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. 6 // Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland. 7 8 // This file was modified by Oracle on 2016, 2017, 2018. 9 // Modifications copyright (c) 2016-2018, Oracle and/or its affiliates. 10 11 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle 12 13 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library 14 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. 15 16 // Use, modification and distribution is subject to the Boost Software License, 17 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 18 // http://www.boost.org/LICENSE_1_0.txt) 19 20 #ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_AREA_HPP 21 #define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_AREA_HPP 22 23 24 #include <boost/mpl/if.hpp> 25 26 //#include <boost/geometry/arithmetic/determinant.hpp> 27 #include <boost/geometry/core/access.hpp> 28 #include <boost/geometry/core/coordinate_type.hpp> 29 #include <boost/geometry/core/coordinate_dimension.hpp> 30 #include <boost/geometry/strategies/area.hpp> 31 #include <boost/geometry/util/select_most_precise.hpp> 32 33 34 namespace boost { namespace geometry 35 { 36 37 namespace strategy { namespace area 38 { 39 40 /*! 41 \brief Cartesian area calculation 42 \ingroup strategies 43 \details Calculates cartesian area using the trapezoidal rule 44 \tparam CalculationType \tparam_calculation 45 46 \qbk{ 47 [heading See also] 48 [link geometry.reference.algorithms.area.area_2_with_strategy area (with strategy)] 49 } 50 51 */ 52 template 53 < 54 typename CalculationType = void 55 > 56 class cartesian 57 { 58 public : 59 template <typename Geometry> 60 struct result_type 61 : strategy::area::detail::result_type 62 < 63 Geometry, 64 CalculationType 65 > 66 {}; 67 68 template <typename Geometry> 69 class state 70 { 71 friend class cartesian; 72 73 typedef typename result_type<Geometry>::type return_type; 74 75 public: state()76 inline state() 77 : sum(0) 78 { 79 // Strategy supports only 2D areas 80 assert_dimension<Geometry, 2>(); 81 } 82 83 private: area() const84 inline return_type area() const 85 { 86 return_type const two = 2; 87 return sum / two; 88 } 89 90 return_type sum; 91 }; 92 93 template <typename PointOfSegment, typename Geometry> apply(PointOfSegment const & p1,PointOfSegment const & p2,state<Geometry> & st)94 static inline void apply(PointOfSegment const& p1, 95 PointOfSegment const& p2, 96 state<Geometry>& st) 97 { 98 typedef typename state<Geometry>::return_type return_type; 99 100 // Below formulas are equivalent, however the two lower ones 101 // suffer less from accuracy loss for great values of coordinates. 102 // See: https://svn.boost.org/trac/boost/ticket/11928 103 104 // SUM += x2 * y1 - x1 * y2; 105 // state.sum += detail::determinant<return_type>(p2, p1); 106 107 // SUM += (x2 - x1) * (y2 + y1) 108 //state.sum += (return_type(get<0>(p2)) - return_type(get<0>(p1))) 109 // * (return_type(get<1>(p2)) + return_type(get<1>(p1))); 110 111 // SUM += (x1 + x2) * (y1 - y2) 112 st.sum += (return_type(get<0>(p1)) + return_type(get<0>(p2))) 113 * (return_type(get<1>(p1)) - return_type(get<1>(p2))); 114 } 115 116 template <typename Geometry> 117 static inline typename result_type<Geometry>::type result(state<Geometry> & st)118 result(state<Geometry>& st) 119 { 120 return st.area(); 121 } 122 123 }; 124 125 #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS 126 127 namespace services 128 { 129 template <> 130 struct default_strategy<cartesian_tag> 131 { 132 typedef strategy::area::cartesian<> type; 133 }; 134 135 } // namespace services 136 137 #endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS 138 139 140 }} // namespace strategy::area 141 142 143 144 }} // namespace boost::geometry 145 146 147 #endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_AREA_HPP 148