Chris@16: // Boost.Geometry (aka GGL, Generic Geometry Library) Chris@16: Chris@16: // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. Chris@16: // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. Chris@16: // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. Chris@16: Chris@16: // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library Chris@16: // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. Chris@16: Chris@16: // Use, modification and distribution is subject to the Boost Software License, Chris@16: // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #ifndef BOOST_GEOMETRY_STRATEGIES_SIDE_INFO_HPP Chris@16: #define BOOST_GEOMETRY_STRATEGIES_SIDE_INFO_HPP Chris@16: Chris@16: #include Chris@16: #include Chris@101: Chris@101: #if defined(BOOST_GEOMETRY_DEBUG_INTERSECTION) || defined(BOOST_GEOMETRY_DEBUG_ROBUSTNESS) Chris@101: # include Chris@16: #endif Chris@16: Chris@16: namespace boost { namespace geometry Chris@16: { Chris@16: Chris@16: // Silence warning C4127: conditional expression is constant Chris@16: #if defined(_MSC_VER) Chris@101: #pragma warning(push) Chris@101: #pragma warning(disable : 4127) Chris@16: #endif Chris@16: Chris@16: /*! Chris@16: \brief Class side_info: small class wrapping for sides (-1,0,1) Chris@16: */ Chris@16: class side_info Chris@16: { Chris@16: public : Chris@16: inline side_info(int side_a1 = 0, int side_a2 = 0, Chris@16: int side_b1 = 0, int side_b2 = 0) Chris@16: { Chris@16: sides[0].first = side_a1; Chris@16: sides[0].second = side_a2; Chris@16: sides[1].first = side_b1; Chris@16: sides[1].second = side_b2; Chris@16: } Chris@16: Chris@16: template Chris@16: inline void set(int first, int second) Chris@16: { Chris@16: sides[Which].first = first; Chris@16: sides[Which].second = second; Chris@16: } Chris@16: Chris@16: template Chris@16: inline void correct_to_zero() Chris@16: { Chris@16: if (Index == 0) Chris@16: { Chris@16: sides[Which].first = 0; Chris@16: } Chris@16: else Chris@16: { Chris@16: sides[Which].second = 0; Chris@16: } Chris@16: } Chris@16: Chris@16: template Chris@16: inline int get() const Chris@16: { Chris@16: return Index == 0 ? sides[Which].first : sides[Which].second; Chris@16: } Chris@16: Chris@16: Chris@16: // Returns true if both lying on the same side WRT the other Chris@16: // (so either 1,1 or -1-1) Chris@16: template Chris@16: inline bool same() const Chris@16: { Chris@16: return sides[Which].first * sides[Which].second == 1; Chris@16: } Chris@16: Chris@16: inline bool collinear() const Chris@16: { Chris@16: return sides[0].first == 0 Chris@16: && sides[0].second == 0 Chris@16: && sides[1].first == 0 Chris@16: && sides[1].second == 0; Chris@16: } Chris@16: Chris@16: inline bool crossing() const Chris@16: { Chris@16: return sides[0].first * sides[0].second == -1 Chris@16: && sides[1].first * sides[1].second == -1; Chris@16: } Chris@16: Chris@16: inline bool touching() const Chris@16: { Chris@16: return (sides[0].first * sides[1].first == -1 Chris@16: && sides[0].second == 0 && sides[1].second == 0) Chris@16: || (sides[1].first * sides[0].first == -1 Chris@16: && sides[1].second == 0 && sides[0].second == 0); Chris@16: } Chris@16: Chris@16: template Chris@16: inline bool one_touching() const Chris@16: { Chris@16: // This is normally a situation which can't occur: Chris@16: // If one is completely left or right, the other cannot touch Chris@16: return one_zero() Chris@16: && sides[1 - Which].first * sides[1 - Which].second == 1; Chris@16: } Chris@16: Chris@16: inline bool meeting() const Chris@16: { Chris@16: // Two of them (in each segment) zero, two not Chris@16: return one_zero<0>() && one_zero<1>(); Chris@16: } Chris@16: Chris@16: template Chris@16: inline bool zero() const Chris@16: { Chris@16: return sides[Which].first == 0 && sides[Which].second == 0; Chris@16: } Chris@16: Chris@16: template Chris@16: inline bool one_zero() const Chris@16: { Chris@16: return (sides[Which].first == 0 && sides[Which].second != 0) Chris@16: || (sides[Which].first != 0 && sides[Which].second == 0); Chris@16: } Chris@16: Chris@16: inline bool one_of_all_zero() const Chris@16: { Chris@16: int const sum = std::abs(sides[0].first) Chris@16: + std::abs(sides[0].second) Chris@16: + std::abs(sides[1].first) Chris@16: + std::abs(sides[1].second); Chris@16: return sum == 3; Chris@16: } Chris@16: Chris@16: Chris@16: template Chris@16: inline int zero_index() const Chris@16: { Chris@16: return sides[Which].first == 0 ? 0 : 1; Chris@16: } Chris@16: Chris@101: #if defined(BOOST_GEOMETRY_DEBUG_INTERSECTION) || defined(BOOST_GEOMETRY_DEBUG_ROBUSTNESS) Chris@16: inline void debug() const Chris@16: { Chris@16: std::cout << sides[0].first << " " Chris@16: << sides[0].second << " " Chris@16: << sides[1].first << " " Chris@101: << sides[1].second Chris@16: << std::endl; Chris@16: } Chris@16: #endif Chris@16: Chris@16: inline void reverse() Chris@16: { Chris@16: std::swap(sides[0], sides[1]); Chris@16: } Chris@16: Chris@16: //private : Chris@16: std::pair sides[2]; Chris@16: Chris@16: }; Chris@16: Chris@16: #if defined(_MSC_VER) Chris@101: #pragma warning(pop) Chris@16: #endif Chris@16: Chris@16: }} // namespace boost::geometry Chris@16: Chris@16: Chris@16: #endif // BOOST_GEOMETRY_STRATEGIES_SIDE_INFO_HPP