• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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