Chris@16
|
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
|
Chris@16
|
2
|
Chris@16
|
3 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
Chris@16
|
4 // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
|
Chris@16
|
5 // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
|
Chris@16
|
6
|
Chris@16
|
7 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
Chris@16
|
8 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
Chris@16
|
9
|
Chris@16
|
10 // Use, modification and distribution is subject to the Boost Software License,
|
Chris@16
|
11 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
12 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
13
|
Chris@16
|
14 #ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_AREA_SURVEYOR_HPP
|
Chris@16
|
15 #define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_AREA_SURVEYOR_HPP
|
Chris@16
|
16
|
Chris@16
|
17
|
Chris@16
|
18 #include <boost/mpl/if.hpp>
|
Chris@16
|
19
|
Chris@16
|
20 #include <boost/geometry/arithmetic/determinant.hpp>
|
Chris@16
|
21 #include <boost/geometry/core/coordinate_type.hpp>
|
Chris@16
|
22 #include <boost/geometry/core/coordinate_dimension.hpp>
|
Chris@16
|
23 #include <boost/geometry/util/select_most_precise.hpp>
|
Chris@16
|
24
|
Chris@16
|
25
|
Chris@16
|
26 namespace boost { namespace geometry
|
Chris@16
|
27 {
|
Chris@16
|
28
|
Chris@16
|
29 namespace strategy { namespace area
|
Chris@16
|
30 {
|
Chris@16
|
31
|
Chris@16
|
32 /*!
|
Chris@16
|
33 \brief Area calculation for cartesian points
|
Chris@16
|
34 \ingroup strategies
|
Chris@16
|
35 \details Calculates area using the Surveyor's formula, a well-known
|
Chris@16
|
36 triangulation algorithm
|
Chris@16
|
37 \tparam PointOfSegment \tparam_segment_point
|
Chris@16
|
38 \tparam CalculationType \tparam_calculation
|
Chris@16
|
39
|
Chris@16
|
40 \qbk{
|
Chris@16
|
41 [heading See also]
|
Chris@16
|
42 [link geometry.reference.algorithms.area.area_2_with_strategy area (with strategy)]
|
Chris@16
|
43 }
|
Chris@16
|
44
|
Chris@16
|
45 */
|
Chris@16
|
46 template
|
Chris@16
|
47 <
|
Chris@16
|
48 typename PointOfSegment,
|
Chris@16
|
49 typename CalculationType = void
|
Chris@16
|
50 >
|
Chris@16
|
51 class surveyor
|
Chris@16
|
52 {
|
Chris@16
|
53 public :
|
Chris@16
|
54 // If user specified a calculation type, use that type,
|
Chris@16
|
55 // whatever it is and whatever the point-type is.
|
Chris@16
|
56 // Else, use the pointtype, but at least double
|
Chris@16
|
57 typedef typename
|
Chris@16
|
58 boost::mpl::if_c
|
Chris@16
|
59 <
|
Chris@16
|
60 boost::is_void<CalculationType>::type::value,
|
Chris@16
|
61 typename select_most_precise
|
Chris@16
|
62 <
|
Chris@16
|
63 typename coordinate_type<PointOfSegment>::type,
|
Chris@16
|
64 double
|
Chris@16
|
65 >::type,
|
Chris@16
|
66 CalculationType
|
Chris@16
|
67 >::type return_type;
|
Chris@16
|
68
|
Chris@16
|
69
|
Chris@16
|
70 private :
|
Chris@16
|
71
|
Chris@16
|
72 class summation
|
Chris@16
|
73 {
|
Chris@16
|
74 friend class surveyor;
|
Chris@16
|
75
|
Chris@16
|
76 return_type sum;
|
Chris@16
|
77 public :
|
Chris@16
|
78
|
Chris@16
|
79 inline summation() : sum(return_type())
|
Chris@16
|
80 {
|
Chris@16
|
81 // Strategy supports only 2D areas
|
Chris@16
|
82 assert_dimension<PointOfSegment, 2>();
|
Chris@16
|
83 }
|
Chris@16
|
84 inline return_type area() const
|
Chris@16
|
85 {
|
Chris@16
|
86 return_type result = sum;
|
Chris@16
|
87 return_type const two = 2;
|
Chris@16
|
88 result /= two;
|
Chris@16
|
89 return result;
|
Chris@16
|
90 }
|
Chris@16
|
91 };
|
Chris@16
|
92
|
Chris@16
|
93 public :
|
Chris@16
|
94 typedef summation state_type;
|
Chris@16
|
95 typedef PointOfSegment segment_point_type;
|
Chris@16
|
96
|
Chris@16
|
97 static inline void apply(PointOfSegment const& p1,
|
Chris@16
|
98 PointOfSegment const& p2,
|
Chris@16
|
99 summation& state)
|
Chris@16
|
100 {
|
Chris@16
|
101 // SUM += x2 * y1 - x1 * y2;
|
Chris@16
|
102 state.sum += detail::determinant<return_type>(p2, p1);
|
Chris@16
|
103 }
|
Chris@16
|
104
|
Chris@16
|
105 static inline return_type result(summation const& state)
|
Chris@16
|
106 {
|
Chris@16
|
107 return state.area();
|
Chris@16
|
108 }
|
Chris@16
|
109
|
Chris@16
|
110 };
|
Chris@16
|
111
|
Chris@16
|
112 #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
|
Chris@16
|
113
|
Chris@16
|
114 namespace services
|
Chris@16
|
115 {
|
Chris@16
|
116 template <typename Point>
|
Chris@16
|
117 struct default_strategy<cartesian_tag, Point>
|
Chris@16
|
118 {
|
Chris@16
|
119 typedef strategy::area::surveyor<Point> type;
|
Chris@16
|
120 };
|
Chris@16
|
121
|
Chris@16
|
122 } // namespace services
|
Chris@16
|
123
|
Chris@16
|
124 #endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
|
Chris@16
|
125
|
Chris@16
|
126
|
Chris@16
|
127 }} // namespace strategy::area
|
Chris@16
|
128
|
Chris@16
|
129
|
Chris@16
|
130
|
Chris@16
|
131 }} // namespace boost::geometry
|
Chris@16
|
132
|
Chris@16
|
133
|
Chris@16
|
134 #endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_AREA_SURVEYOR_HPP
|