area.hpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  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. // Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
  6. // This file was modified by Oracle on 2016-2020.
  7. // Modifications copyright (c) 2016-2020, Oracle and/or its affiliates.
  8. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  9. // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
  10. // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
  11. // Use, modification and distribution is subject to the Boost Software License,
  12. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  13. // http://www.boost.org/LICENSE_1_0.txt)
  14. #ifndef BOOST_GEOMETRY_STRATEGY_CARTESIAN_AREA_HPP
  15. #define BOOST_GEOMETRY_STRATEGY_CARTESIAN_AREA_HPP
  16. //#include <boost/geometry/arithmetic/determinant.hpp>
  17. #include <boost/geometry/core/access.hpp>
  18. #include <boost/geometry/core/coordinate_type.hpp>
  19. #include <boost/geometry/core/coordinate_dimension.hpp>
  20. #include <boost/geometry/strategy/area.hpp>
  21. #include <boost/geometry/util/select_most_precise.hpp>
  22. namespace boost { namespace geometry
  23. {
  24. namespace strategy { namespace area
  25. {
  26. /*!
  27. \brief Cartesian area calculation
  28. \ingroup strategies
  29. \details Calculates cartesian area using the trapezoidal rule
  30. \tparam CalculationType \tparam_calculation
  31. \qbk{
  32. [heading See also]
  33. [link geometry.reference.algorithms.area.area_2_with_strategy area (with strategy)]
  34. }
  35. */
  36. template
  37. <
  38. typename CalculationType = void
  39. >
  40. class cartesian
  41. {
  42. public :
  43. template <typename Geometry>
  44. struct result_type
  45. : strategy::area::detail::result_type
  46. <
  47. Geometry,
  48. CalculationType
  49. >
  50. {};
  51. template <typename Geometry>
  52. class state
  53. {
  54. friend class cartesian;
  55. typedef typename result_type<Geometry>::type return_type;
  56. public:
  57. inline state()
  58. : sum(0)
  59. {
  60. // Strategy supports only 2D areas
  61. assert_dimension<Geometry, 2>();
  62. }
  63. private:
  64. inline return_type area() const
  65. {
  66. return_type const two = 2;
  67. return sum / two;
  68. }
  69. return_type sum;
  70. };
  71. template <typename PointOfSegment, typename Geometry>
  72. static inline void apply(PointOfSegment const& p1,
  73. PointOfSegment const& p2,
  74. state<Geometry>& st)
  75. {
  76. typedef typename state<Geometry>::return_type return_type;
  77. // Below formulas are equivalent, however the two lower ones
  78. // suffer less from accuracy loss for great values of coordinates.
  79. // See: https://svn.boost.org/trac/boost/ticket/11928
  80. // SUM += x2 * y1 - x1 * y2;
  81. // state.sum += detail::determinant<return_type>(p2, p1);
  82. // SUM += (x2 - x1) * (y2 + y1)
  83. //state.sum += (return_type(get<0>(p2)) - return_type(get<0>(p1)))
  84. // * (return_type(get<1>(p2)) + return_type(get<1>(p1)));
  85. // SUM += (x1 + x2) * (y1 - y2)
  86. st.sum += (return_type(get<0>(p1)) + return_type(get<0>(p2)))
  87. * (return_type(get<1>(p1)) - return_type(get<1>(p2)));
  88. }
  89. template <typename Geometry>
  90. static inline auto result(state<Geometry>& st)
  91. {
  92. return st.area();
  93. }
  94. };
  95. #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
  96. namespace services
  97. {
  98. template <>
  99. struct default_strategy<cartesian_tag>
  100. {
  101. typedef strategy::area::cartesian<> type;
  102. };
  103. } // namespace services
  104. #endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
  105. }} // namespace strategy::area
  106. }} // namespace boost::geometry
  107. #endif // BOOST_GEOMETRY_STRATEGY_CARTESIAN_AREA_HPP