area_surveyor.hpp 3.3 KB

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