point_in_poly_crossings_multiply.hpp 3.5 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. // This file was modified by Oracle on 2018, 2019.
  6. // Modifications copyright (c) 2018, 2019, Oracle and/or its affiliates.
  7. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  8. // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
  9. // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
  10. // Use, modification and distribution is subject to the Boost Software License,
  11. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  12. // http://www.boost.org/LICENSE_1_0.txt)
  13. #ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_POINT_IN_POLY_CROSSINGS_MULTIPLY_HPP
  14. #define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_POINT_IN_POLY_CROSSINGS_MULTIPLY_HPP
  15. #include <boost/geometry/core/access.hpp>
  16. #include <boost/geometry/core/coordinate_type.hpp>
  17. #include <boost/geometry/util/select_calculation_type.hpp>
  18. namespace boost { namespace geometry
  19. {
  20. namespace strategy { namespace within
  21. {
  22. /*!
  23. \brief Within detection using cross counting,
  24. \ingroup strategies
  25. \tparam Point \tparam_point
  26. \tparam PointOfSegment \tparam_segment_point
  27. \tparam CalculationType \tparam_calculation
  28. \see http://tog.acm.org/resources/GraphicsGems/gemsiv/ptpoly_haines/ptinpoly.c
  29. \note Does NOT work correctly for point ON border
  30. \qbk{
  31. [heading See also]
  32. [link geometry.reference.algorithms.within.within_3_with_strategy within (with strategy)]
  33. }
  34. */
  35. template
  36. <
  37. typename Point_, // for backward compatibility
  38. typename PointOfSegment_ = Point_, // for backward compatibility
  39. typename CalculationType = void
  40. >
  41. class crossings_multiply
  42. {
  43. template <typename Point, typename PointOfSegment>
  44. struct calculation_type
  45. : select_calculation_type
  46. <
  47. Point,
  48. PointOfSegment,
  49. CalculationType
  50. >
  51. {};
  52. class flags
  53. {
  54. bool inside_flag;
  55. bool first;
  56. bool yflag0;
  57. public :
  58. friend class crossings_multiply;
  59. inline flags()
  60. : inside_flag(false)
  61. , first(true)
  62. , yflag0(false)
  63. {}
  64. };
  65. public :
  66. typedef flags state_type;
  67. template <typename Point, typename PointOfSegment>
  68. static inline bool apply(Point const& point,
  69. PointOfSegment const& seg1, PointOfSegment const& seg2,
  70. flags& state)
  71. {
  72. typedef typename calculation_type<Point, PointOfSegment>::type calc_t;
  73. calc_t const tx = get<0>(point);
  74. calc_t const ty = get<1>(point);
  75. calc_t const x0 = get<0>(seg1);
  76. calc_t const y0 = get<1>(seg1);
  77. calc_t const x1 = get<0>(seg2);
  78. calc_t const y1 = get<1>(seg2);
  79. if (state.first)
  80. {
  81. state.first = false;
  82. state.yflag0 = y0 >= ty;
  83. }
  84. bool yflag1 = y1 >= ty;
  85. if (state.yflag0 != yflag1)
  86. {
  87. if ( ((y1-ty) * (x0-x1) >= (x1-tx) * (y0-y1)) == yflag1 )
  88. {
  89. state.inside_flag = ! state.inside_flag;
  90. }
  91. }
  92. state.yflag0 = yflag1;
  93. return true;
  94. }
  95. static inline int result(flags const& state)
  96. {
  97. return state.inside_flag ? 1 : -1;
  98. }
  99. };
  100. }} // namespace strategy::within
  101. }} // namespace boost::geometry
  102. #endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_POINT_IN_POLY_CROSSINGS_MULTIPLY_HPP