area.hpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  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, 2017, 2018.
  7. // Modifications copyright (c) 2016-2018, 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_STRATEGIES_CARTESIAN_AREA_HPP
  15. #define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_AREA_HPP
  16. #include <boost/mpl/if.hpp>
  17. //#include <boost/geometry/arithmetic/determinant.hpp>
  18. #include <boost/geometry/core/access.hpp>
  19. #include <boost/geometry/core/coordinate_type.hpp>
  20. #include <boost/geometry/core/coordinate_dimension.hpp>
  21. #include <boost/geometry/strategies/area.hpp>
  22. #include <boost/geometry/util/select_most_precise.hpp>
  23. namespace boost { namespace geometry
  24. {
  25. namespace strategy { namespace area
  26. {
  27. /*!
  28. \brief Cartesian area calculation
  29. \ingroup strategies
  30. \details Calculates cartesian area using the trapezoidal rule
  31. \tparam CalculationType \tparam_calculation
  32. \qbk{
  33. [heading See also]
  34. [link geometry.reference.algorithms.area.area_2_with_strategy area (with strategy)]
  35. }
  36. */
  37. template
  38. <
  39. typename CalculationType = void
  40. >
  41. class cartesian
  42. {
  43. public :
  44. template <typename Geometry>
  45. struct result_type
  46. : strategy::area::detail::result_type
  47. <
  48. Geometry,
  49. CalculationType
  50. >
  51. {};
  52. template <typename Geometry>
  53. class state
  54. {
  55. friend class cartesian;
  56. typedef typename result_type<Geometry>::type return_type;
  57. public:
  58. inline state()
  59. : sum(0)
  60. {
  61. // Strategy supports only 2D areas
  62. assert_dimension<Geometry, 2>();
  63. }
  64. private:
  65. inline return_type area() const
  66. {
  67. return_type const two = 2;
  68. return sum / two;
  69. }
  70. return_type sum;
  71. };
  72. template <typename PointOfSegment, typename Geometry>
  73. static inline void apply(PointOfSegment const& p1,
  74. PointOfSegment const& p2,
  75. state<Geometry>& st)
  76. {
  77. typedef typename state<Geometry>::return_type return_type;
  78. // Below formulas are equivalent, however the two lower ones
  79. // suffer less from accuracy loss for great values of coordinates.
  80. // See: https://svn.boost.org/trac/boost/ticket/11928
  81. // SUM += x2 * y1 - x1 * y2;
  82. // state.sum += detail::determinant<return_type>(p2, p1);
  83. // SUM += (x2 - x1) * (y2 + y1)
  84. //state.sum += (return_type(get<0>(p2)) - return_type(get<0>(p1)))
  85. // * (return_type(get<1>(p2)) + return_type(get<1>(p1)));
  86. // SUM += (x1 + x2) * (y1 - y2)
  87. st.sum += (return_type(get<0>(p1)) + return_type(get<0>(p2)))
  88. * (return_type(get<1>(p1)) - return_type(get<1>(p2)));
  89. }
  90. template <typename Geometry>
  91. static inline typename result_type<Geometry>::type
  92. result(state<Geometry>& st)
  93. {
  94. return st.area();
  95. }
  96. };
  97. #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
  98. namespace services
  99. {
  100. template <>
  101. struct default_strategy<cartesian_tag>
  102. {
  103. typedef strategy::area::cartesian<> type;
  104. };
  105. } // namespace services
  106. #endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
  107. }} // namespace strategy::area
  108. }} // namespace boost::geometry
  109. #endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_AREA_HPP