123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307 |
- // Boost.Geometry
- // Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
- // Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
- // Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
- // Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
- // This file was modified by Oracle on 2013-2019.
- // Modifications copyright (c) 2013-2019, Oracle and/or its affiliates.
- // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
- // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
- // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
- // Use, modification and distribution is subject to the Boost Software License,
- // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- #ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISJOINT_SEGMENT_BOX_HPP
- #define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISJOINT_SEGMENT_BOX_HPP
- #include <cstddef>
- #include <utility>
- #include <boost/geometry/core/access.hpp>
- #include <boost/geometry/core/tags.hpp>
- #include <boost/geometry/core/coordinate_dimension.hpp>
- #include <boost/geometry/core/point_type.hpp>
- #include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
- #include <boost/geometry/strategies/cartesian/point_in_box.hpp>
- #include <boost/geometry/strategies/disjoint.hpp>
- #include <boost/geometry/util/math.hpp>
- #include <boost/geometry/util/numeric_cast.hpp>
- #include <boost/geometry/util/calculation_type.hpp>
- namespace boost { namespace geometry { namespace strategy { namespace disjoint
- {
- namespace detail
- {
- template <std::size_t I>
- struct compute_tmin_tmax_per_dim
- {
- template <typename SegmentPoint, typename Box, typename RelativeDistance>
- static inline void apply(SegmentPoint const& p0,
- SegmentPoint const& p1,
- Box const& box,
- RelativeDistance& ti_min,
- RelativeDistance& ti_max,
- RelativeDistance& diff)
- {
- typedef typename coordinate_type<Box>::type box_coordinate_type;
- typedef typename coordinate_type
- <
- SegmentPoint
- >::type point_coordinate_type;
- RelativeDistance c_p0 = util::numeric_cast
- <
- point_coordinate_type
- >( geometry::get<I>(p0) );
- RelativeDistance c_p1 = util::numeric_cast
- <
- point_coordinate_type
- >( geometry::get<I>(p1) );
- RelativeDistance c_b_min = util::numeric_cast
- <
- box_coordinate_type
- >( geometry::get<geometry::min_corner, I>(box) );
- RelativeDistance c_b_max = util::numeric_cast
- <
- box_coordinate_type
- >( geometry::get<geometry::max_corner, I>(box) );
- if ( geometry::get<I>(p1) >= geometry::get<I>(p0) )
- {
- diff = c_p1 - c_p0;
- ti_min = c_b_min - c_p0;
- ti_max = c_b_max - c_p0;
- }
- else
- {
- diff = c_p0 - c_p1;
- ti_min = c_p0 - c_b_max;
- ti_max = c_p0 - c_b_min;
- }
- }
- };
- template
- <
- typename RelativeDistance,
- typename SegmentPoint,
- typename Box,
- std::size_t I,
- std::size_t Dimension
- >
- struct disjoint_segment_box_impl
- {
- template <typename RelativeDistancePair>
- static inline bool apply(SegmentPoint const& p0,
- SegmentPoint const& p1,
- Box const& box,
- RelativeDistancePair& t_min,
- RelativeDistancePair& t_max)
- {
- RelativeDistance ti_min, ti_max, diff;
- compute_tmin_tmax_per_dim<I>::apply(p0, p1, box, ti_min, ti_max, diff);
- if ( geometry::math::equals(diff, 0) )
- {
- if ( (geometry::math::equals(t_min.second, 0)
- && t_min.first > ti_max)
- ||
- (geometry::math::equals(t_max.second, 0)
- && t_max.first < ti_min)
- ||
- (math::sign(ti_min) * math::sign(ti_max) > 0) )
- {
- return true;
- }
- }
- RelativeDistance t_min_x_diff = t_min.first * diff;
- RelativeDistance t_max_x_diff = t_max.first * diff;
- if ( t_min_x_diff > ti_max * t_min.second
- || t_max_x_diff < ti_min * t_max.second )
- {
- return true;
- }
- if ( ti_min * t_min.second > t_min_x_diff )
- {
- t_min.first = ti_min;
- t_min.second = diff;
- }
- if ( ti_max * t_max.second < t_max_x_diff )
- {
- t_max.first = ti_max;
- t_max.second = diff;
- }
- if ( t_min.first > t_min.second || t_max.first < 0 )
- {
- return true;
- }
- return disjoint_segment_box_impl
- <
- RelativeDistance,
- SegmentPoint,
- Box,
- I + 1,
- Dimension
- >::apply(p0, p1, box, t_min, t_max);
- }
- };
- template
- <
- typename RelativeDistance,
- typename SegmentPoint,
- typename Box,
- std::size_t Dimension
- >
- struct disjoint_segment_box_impl
- <
- RelativeDistance, SegmentPoint, Box, 0, Dimension
- >
- {
- static inline bool apply(SegmentPoint const& p0,
- SegmentPoint const& p1,
- Box const& box)
- {
- std::pair<RelativeDistance, RelativeDistance> t_min, t_max;
- RelativeDistance diff;
- compute_tmin_tmax_per_dim<0>::apply(p0, p1, box,
- t_min.first, t_max.first, diff);
- if ( geometry::math::equals(diff, 0) )
- {
- if ( geometry::math::equals(t_min.first, 0) ) { t_min.first = -1; }
- if ( geometry::math::equals(t_max.first, 0) ) { t_max.first = 1; }
- if (math::sign(t_min.first) * math::sign(t_max.first) > 0)
- {
- return true;
- }
- }
- if ( t_min.first > diff || t_max.first < 0 )
- {
- return true;
- }
- t_min.second = t_max.second = diff;
- return disjoint_segment_box_impl
- <
- RelativeDistance, SegmentPoint, Box, 1, Dimension
- >::apply(p0, p1, box, t_min, t_max);
- }
- };
- template
- <
- typename RelativeDistance,
- typename SegmentPoint,
- typename Box,
- std::size_t Dimension
- >
- struct disjoint_segment_box_impl
- <
- RelativeDistance, SegmentPoint, Box, Dimension, Dimension
- >
- {
- template <typename RelativeDistancePair>
- static inline bool apply(SegmentPoint const&, SegmentPoint const&,
- Box const&,
- RelativeDistancePair&, RelativeDistancePair&)
- {
- return false;
- }
- };
- } // namespace detail
- // NOTE: This may be temporary place for this or corresponding strategy
- // It seems to be more appropriate to implement the opposite of it
- // e.g. intersection::segment_box because in disjoint() algorithm
- // other strategies that are used are intersection and covered_by strategies.
- struct segment_box
- {
- typedef covered_by::cartesian_point_box disjoint_point_box_strategy_type;
- static inline disjoint_point_box_strategy_type get_disjoint_point_box_strategy()
- {
- return disjoint_point_box_strategy_type();
- }
- template <typename Segment, typename Box>
- static inline bool apply(Segment const& segment, Box const& box)
- {
- assert_dimension_equal<Segment, Box>();
- typedef typename util::calculation_type::geometric::binary
- <
- Segment, Box, void
- >::type relative_distance_type;
- typedef typename point_type<Segment>::type segment_point_type;
- segment_point_type p0, p1;
- geometry::detail::assign_point_from_index<0>(segment, p0);
- geometry::detail::assign_point_from_index<1>(segment, p1);
- return detail::disjoint_segment_box_impl
- <
- relative_distance_type, segment_point_type, Box,
- 0, dimension<Box>::value
- >::apply(p0, p1, box);
- }
- };
- #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
- namespace services
- {
- template <typename Linear, typename Box, typename LinearTag>
- struct default_strategy<Linear, Box, LinearTag, box_tag, 1, 2, cartesian_tag, cartesian_tag>
- {
- typedef disjoint::segment_box type;
- };
- template <typename Box, typename Linear, typename LinearTag>
- struct default_strategy<Box, Linear, box_tag, LinearTag, 2, 1, cartesian_tag, cartesian_tag>
- {
- typedef disjoint::segment_box type;
- };
- } // namespace services
- #endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
- }}}} // namespace boost::geometry::strategy::disjoint
- #endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISJOINT_SEGMENT_BOX_HPP
|