mirror of
https://github.com/boostorg/geometry.git
synced 2026-02-12 12:12:10 +00:00
Merge branch 'develop' into bg-prepare
Conflicts: test/algorithms/buffer/multi_point_buffer.cpp
This commit is contained in:
@@ -168,6 +168,9 @@ struct buffered_piece_collection
|
||||
|
||||
struct piece
|
||||
{
|
||||
typedef robust_ring_type piece_robust_ring_type;
|
||||
typedef geometry::section<robust_box_type, 1> section_type;
|
||||
|
||||
strategy::buffer::piece_type type;
|
||||
int index;
|
||||
|
||||
@@ -191,6 +194,10 @@ struct buffered_piece_collection
|
||||
bool is_monotonic_increasing[2]; // 0=x, 1=y
|
||||
bool is_monotonic_decreasing[2]; // 0=x, 1=y
|
||||
|
||||
// Monotonic sections of pieces around points
|
||||
std::vector<section_type> sections;
|
||||
|
||||
|
||||
// Robust representations
|
||||
// 3: complete ring
|
||||
robust_ring_type robust_ring;
|
||||
@@ -199,8 +206,6 @@ struct buffered_piece_collection
|
||||
robust_box_type robust_offsetted_envelope;
|
||||
|
||||
std::vector<robust_turn> robust_turns; // Used only in insert_rescaled_piece_turns - we might use a map instead
|
||||
|
||||
typedef robust_ring_type piece_robust_ring_type;
|
||||
};
|
||||
|
||||
struct robust_original
|
||||
@@ -647,6 +652,29 @@ struct buffered_piece_collection
|
||||
}
|
||||
}
|
||||
|
||||
inline void prepare_buffered_point_piece(piece& pc)
|
||||
{
|
||||
// create monotonic sections in y-dimension
|
||||
typedef boost::mpl::vector_c<std::size_t, 1> dimensions;
|
||||
geometry::sectionalize<false, dimensions>(pc.robust_ring,
|
||||
detail::no_rescale_policy(), pc.sections);
|
||||
|
||||
// TODO (next phase) determine min/max radius
|
||||
}
|
||||
|
||||
inline void prepare_buffered_point_pieces()
|
||||
{
|
||||
for (typename piece_vector_type::iterator it = boost::begin(m_pieces);
|
||||
it != boost::end(m_pieces);
|
||||
++it)
|
||||
{
|
||||
if (it->type == geometry::strategy::buffer::buffered_point)
|
||||
{
|
||||
prepare_buffered_point_piece(*it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void get_turns()
|
||||
{
|
||||
for(typename boost::range_iterator<sections_type>::type it
|
||||
@@ -681,6 +709,8 @@ struct buffered_piece_collection
|
||||
|
||||
determine_properties();
|
||||
|
||||
prepare_buffered_point_pieces();
|
||||
|
||||
{
|
||||
// Check if it is inside any of the pieces
|
||||
turn_in_piece_visitor
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <boost/geometry/algorithms/detail/disjoint/box_box.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/segment_identifier.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
|
||||
#include <boost/geometry/algorithms/detail/sections/section_functions.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
@@ -88,6 +89,38 @@ class piece_turn_visitor
|
||||
return result;
|
||||
}
|
||||
|
||||
template <std::size_t Dimension, typename Iterator, typename Box>
|
||||
inline void move_begin_iterator(Iterator& it_begin, Iterator it_beyond,
|
||||
int& index, int dir, Box const& other_bounding_box)
|
||||
{
|
||||
for(; it_begin != it_beyond
|
||||
&& it_begin + 1 != it_beyond
|
||||
&& detail::section::preceding<Dimension>(dir, *(it_begin + 1),
|
||||
other_bounding_box, m_robust_policy);
|
||||
++it_begin, index++)
|
||||
{}
|
||||
}
|
||||
|
||||
template <std::size_t Dimension, typename Iterator, typename Box>
|
||||
inline void move_end_iterator(Iterator it_begin, Iterator& it_beyond,
|
||||
int dir, Box const& other_bounding_box)
|
||||
{
|
||||
while (it_beyond != it_begin
|
||||
&& it_beyond - 1 != it_begin
|
||||
&& it_beyond - 2 != it_begin)
|
||||
{
|
||||
if (detail::section::exceeding<Dimension>(dir, *(it_beyond - 2),
|
||||
other_bounding_box, m_robust_policy))
|
||||
{
|
||||
--it_beyond;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Piece, typename Section>
|
||||
inline void calculate_turns(Piece const& piece1, Piece const& piece2,
|
||||
Section const& section1, Section const& section2)
|
||||
@@ -113,17 +146,38 @@ class piece_turn_visitor
|
||||
|
||||
// get geometry and iterators over these sections
|
||||
ring_type const& ring1 = m_rings[piece1.first_seg_id.multi_index];
|
||||
iterator const it1_first = boost::begin(ring1) + sec1_first_index;
|
||||
iterator const it1_beyond = boost::begin(ring1) + sec1_last_index + 1;
|
||||
iterator it1_first = boost::begin(ring1) + sec1_first_index;
|
||||
iterator it1_beyond = boost::begin(ring1) + sec1_last_index + 1;
|
||||
|
||||
ring_type const& ring2 = m_rings[piece2.first_seg_id.multi_index];
|
||||
iterator const it2_first = boost::begin(ring2) + sec2_first_index;
|
||||
iterator const it2_beyond = boost::begin(ring2) + sec2_last_index + 1;
|
||||
iterator it2_first = boost::begin(ring2) + sec2_first_index;
|
||||
iterator it2_beyond = boost::begin(ring2) + sec2_last_index + 1;
|
||||
|
||||
// Set begin/end of monotonic ranges, in both x/y directions
|
||||
int index1 = sec1_first_index;
|
||||
move_begin_iterator<0>(it1_first, it1_beyond, index1,
|
||||
section1.directions[0], section2.bounding_box);
|
||||
move_end_iterator<0>(it1_first, it1_beyond,
|
||||
section1.directions[0], section2.bounding_box);
|
||||
move_begin_iterator<1>(it1_first, it1_beyond, index1,
|
||||
section1.directions[1], section2.bounding_box);
|
||||
move_end_iterator<1>(it1_first, it1_beyond,
|
||||
section1.directions[1], section2.bounding_box);
|
||||
|
||||
int index2 = sec2_first_index;
|
||||
move_begin_iterator<0>(it2_first, it2_beyond, index2,
|
||||
section2.directions[0], section1.bounding_box);
|
||||
move_end_iterator<0>(it2_first, it2_beyond,
|
||||
section2.directions[0], section1.bounding_box);
|
||||
move_begin_iterator<1>(it2_first, it2_beyond, index2,
|
||||
section2.directions[1], section1.bounding_box);
|
||||
move_end_iterator<1>(it2_first, it2_beyond,
|
||||
section2.directions[1], section1.bounding_box);
|
||||
|
||||
turn_type the_model;
|
||||
the_model.operations[0].piece_index = piece1.index;
|
||||
the_model.operations[0].seg_id = piece1.first_seg_id;
|
||||
the_model.operations[0].seg_id.segment_index = sec1_first_index; // override
|
||||
the_model.operations[0].seg_id.segment_index = index1; // override
|
||||
|
||||
iterator it1 = it1_first;
|
||||
for (iterator prev1 = it1++;
|
||||
@@ -132,7 +186,7 @@ class piece_turn_visitor
|
||||
{
|
||||
the_model.operations[1].piece_index = piece2.index;
|
||||
the_model.operations[1].seg_id = piece2.first_seg_id;
|
||||
the_model.operations[1].seg_id.segment_index = sec2_first_index; // override
|
||||
the_model.operations[1].seg_id.segment_index = index2; // override
|
||||
|
||||
iterator next1 = next_point(ring1, it1);
|
||||
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// 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_ALGORITHMS_DETAIL_BUFFER_TURN_IN_INPUT_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_TURN_IN_INPUT_HPP
|
||||
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
#include <boost/geometry/algorithms/covered_by.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace buffer
|
||||
{
|
||||
|
||||
// Checks if an turn/intersection point is inside (or covered by) the input geometry
|
||||
|
||||
template <typename Tag>
|
||||
struct turn_in_input
|
||||
{
|
||||
};
|
||||
|
||||
template <>
|
||||
struct turn_in_input<polygon_tag>
|
||||
{
|
||||
template <typename Point, typename Geometry>
|
||||
static inline int apply(Point const& point, Geometry const& geometry)
|
||||
{
|
||||
return geometry::covered_by(point, geometry) ? 1 : -1;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct turn_in_input<linestring_tag>
|
||||
{
|
||||
template <typename Point, typename Geometry>
|
||||
static inline int apply(Point const& , Geometry const& )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct turn_in_input<point_tag>
|
||||
{
|
||||
template <typename Point, typename Geometry>
|
||||
static inline int apply(Point const& , Geometry const& )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct turn_in_input<multi_polygon_tag>
|
||||
{
|
||||
template <typename Point, typename Geometry>
|
||||
static inline int apply(Point const& point, Geometry const& geometry)
|
||||
{
|
||||
return geometry::covered_by(point, geometry) ? 1 : -1;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct turn_in_input<multi_linestring_tag>
|
||||
{
|
||||
template <typename Point, typename Geometry>
|
||||
static inline int apply(Point const& , Geometry const& )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct turn_in_input<multi_point_tag>
|
||||
{
|
||||
template <typename Point, typename Geometry>
|
||||
static inline int apply(Point const& , Geometry const& )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::buffer
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_TURN_IN_INPUT_HPP
|
||||
@@ -90,74 +90,134 @@ enum analyse_result
|
||||
analyse_near_offsetted
|
||||
};
|
||||
|
||||
class analyse_turn_wrt_piece
|
||||
template <typename Point>
|
||||
inline bool in_box(Point const& previous,
|
||||
Point const& current, Point const& point)
|
||||
{
|
||||
template <typename Point>
|
||||
static inline bool in_box(Point const& previous,
|
||||
Point const& current, Point const& point)
|
||||
{
|
||||
// Get its box (TODO: this can be prepared-on-demand later)
|
||||
typedef geometry::model::box<Point> box_type;
|
||||
box_type box;
|
||||
geometry::assign_inverse(box);
|
||||
geometry::expand(box, previous);
|
||||
geometry::expand(box, current);
|
||||
// Get its box (TODO: this can be prepared-on-demand later)
|
||||
typedef geometry::model::box<Point> box_type;
|
||||
box_type box;
|
||||
geometry::assign_inverse(box);
|
||||
geometry::expand(box, previous);
|
||||
geometry::expand(box, current);
|
||||
|
||||
return geometry::covered_by(point, box);
|
||||
return geometry::covered_by(point, box);
|
||||
}
|
||||
|
||||
template <typename Point, typename Turn>
|
||||
inline analyse_result check_segment(Point const& previous,
|
||||
Point const& current, Turn const& turn,
|
||||
bool from_monotonic)
|
||||
{
|
||||
typedef typename strategy::side::services::default_strategy
|
||||
<
|
||||
typename cs_tag<Point>::type
|
||||
>::type side_strategy;
|
||||
typedef typename geometry::coordinate_type<Point>::type coordinate_type;
|
||||
|
||||
coordinate_type const twice_area
|
||||
= side_strategy::template side_value
|
||||
<
|
||||
coordinate_type,
|
||||
coordinate_type
|
||||
>(previous, current, turn.robust_point);
|
||||
|
||||
if (twice_area == 0)
|
||||
{
|
||||
// Collinear, only on segment if it is covered by its bbox
|
||||
if (in_box(previous, current, turn.robust_point))
|
||||
{
|
||||
return analyse_on_offsetted;
|
||||
}
|
||||
}
|
||||
else if (twice_area < 0)
|
||||
{
|
||||
// It is in the triangle right-of the segment where the
|
||||
// segment is the hypothenusa. Check if it is close
|
||||
// (within rounding-area)
|
||||
if (twice_area * twice_area < geometry::comparable_distance(previous, current)
|
||||
&& in_box(previous, current, turn.robust_point))
|
||||
{
|
||||
return analyse_near_offsetted;
|
||||
}
|
||||
else if (from_monotonic)
|
||||
{
|
||||
return analyse_within;
|
||||
}
|
||||
}
|
||||
else if (twice_area > 0 && from_monotonic)
|
||||
{
|
||||
// Left of segment
|
||||
return analyse_disjoint;
|
||||
}
|
||||
|
||||
template <typename Point, typename Turn>
|
||||
static inline analyse_result check_segment(Point const& previous,
|
||||
Point const& current, Turn const& turn,
|
||||
bool from_monotonic)
|
||||
// Not monotonic, on left or right side: continue analysing
|
||||
return analyse_continue;
|
||||
}
|
||||
|
||||
|
||||
class analyse_turn_wrt_point_piece
|
||||
{
|
||||
public :
|
||||
template <typename Turn, typename Piece>
|
||||
static inline analyse_result apply(Turn const& turn, Piece const& piece)
|
||||
{
|
||||
typedef typename strategy::side::services::default_strategy
|
||||
<
|
||||
typename cs_tag<Point>::type
|
||||
>::type side_strategy;
|
||||
typedef typename geometry::coordinate_type<Point>::type coordinate_type;
|
||||
typedef typename Piece::section_type section_type;
|
||||
typedef typename Turn::robust_point_type point_type;
|
||||
typedef typename geometry::coordinate_type<point_type>::type coordinate_type;
|
||||
|
||||
coordinate_type const twice_area
|
||||
= side_strategy::template side_value
|
||||
<
|
||||
coordinate_type,
|
||||
coordinate_type
|
||||
>(previous, current, turn.robust_point);
|
||||
coordinate_type const point_y = geometry::get<1>(turn.robust_point);
|
||||
|
||||
if (twice_area == 0)
|
||||
typedef strategy::within::winding<point_type> strategy_type;
|
||||
|
||||
typename strategy_type::state_type state;
|
||||
strategy_type strategy;
|
||||
|
||||
for (std::size_t s = 0; s < piece.sections.size(); s++)
|
||||
{
|
||||
// Collinear, only on segment if it is covered by its bbox
|
||||
if (in_box(previous, current, turn.robust_point))
|
||||
section_type const& section = piece.sections[s];
|
||||
// If point within vertical range of monotonic section:
|
||||
if (! section.duplicate
|
||||
&& section.begin_index < section.end_index
|
||||
&& point_y >= geometry::get<min_corner, 1>(section.bounding_box) - 1
|
||||
&& point_y <= geometry::get<max_corner, 1>(section.bounding_box) + 1)
|
||||
{
|
||||
return analyse_on_offsetted;
|
||||
for (int i = section.begin_index + 1; i <= section.end_index; i++)
|
||||
{
|
||||
point_type const& previous = piece.robust_ring[i - 1];
|
||||
point_type const& current = piece.robust_ring[i];
|
||||
|
||||
analyse_result code = check_segment(previous, current, turn, false);
|
||||
if (code != analyse_continue)
|
||||
{
|
||||
return code;
|
||||
}
|
||||
|
||||
// Get the state (to determine it is within), we don't have
|
||||
// to cover the on-segment case (covered above)
|
||||
strategy.apply(turn.robust_point, previous, current, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (twice_area < 0)
|
||||
|
||||
int const code = strategy.result(state);
|
||||
if (code == 1)
|
||||
{
|
||||
// It is in the triangle right-of the segment where the
|
||||
// segment is the hypothenusa. Check if it is close
|
||||
// (within rounding-area)
|
||||
if (twice_area * twice_area < geometry::comparable_distance(previous, current)
|
||||
&& in_box(previous, current, turn.robust_point))
|
||||
{
|
||||
return analyse_near_offsetted;
|
||||
}
|
||||
else if (from_monotonic)
|
||||
{
|
||||
return analyse_within;
|
||||
}
|
||||
return analyse_within;
|
||||
}
|
||||
else if (twice_area > 0 && from_monotonic)
|
||||
else if (code == -1)
|
||||
{
|
||||
// Left of segment
|
||||
return analyse_disjoint;
|
||||
}
|
||||
|
||||
// Not monotonic, on left or right side: continue analysing
|
||||
return analyse_continue;
|
||||
// Should normally not occur - on-segment is covered
|
||||
return analyse_unknown;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class analyse_turn_wrt_piece
|
||||
{
|
||||
template <typename Point, typename Turn>
|
||||
static inline analyse_result check_helper_segment(Point const& s1,
|
||||
Point const& s2, Turn const& turn,
|
||||
@@ -389,7 +449,7 @@ public :
|
||||
}
|
||||
}
|
||||
|
||||
return analyse_unknown;
|
||||
return analyse_unknown;
|
||||
}
|
||||
|
||||
};
|
||||
@@ -466,8 +526,10 @@ public:
|
||||
}
|
||||
|
||||
// TODO: mutable_piece to make some on-demand preparations in analyse
|
||||
analyse_result analyse_code
|
||||
= analyse_turn_wrt_piece::apply(turn, piece);
|
||||
analyse_result analyse_code =
|
||||
piece.type == geometry::strategy::buffer::buffered_point
|
||||
? analyse_turn_wrt_point_piece::apply(turn, piece)
|
||||
: analyse_turn_wrt_piece::apply(turn, piece);
|
||||
|
||||
Turn& mutable_turn = m_turns[turn.turn_index];
|
||||
switch(analyse_code)
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
|
||||
#include <boost/geometry/algorithms/detail/sections/range_by_section.hpp>
|
||||
#include <boost/geometry/algorithms/detail/sections/sectionalize.hpp>
|
||||
#include <boost/geometry/algorithms/detail/sections/section_functions.hpp>
|
||||
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_INTERSECTION
|
||||
# include <sstream>
|
||||
@@ -228,7 +229,7 @@ public :
|
||||
// section 2: [--------------]
|
||||
// section 1: |----|---|---|---|---|
|
||||
for (prev1 = it1++, next1++;
|
||||
it1 != end1 && ! exceeding<0>(dir1, *prev1, sec2.bounding_box, robust_policy);
|
||||
it1 != end1 && ! detail::section::exceeding<0>(dir1, *prev1, sec2.bounding_box, robust_policy);
|
||||
++prev1, ++it1, ++index1, ++next1, ++ndi1)
|
||||
{
|
||||
ever_circling_iterator<range1_iterator> nd_next1(
|
||||
@@ -246,7 +247,7 @@ public :
|
||||
next2++;
|
||||
|
||||
for (prev2 = it2++, next2++;
|
||||
it2 != end2 && ! exceeding<0>(dir2, *prev2, sec1.bounding_box, robust_policy);
|
||||
it2 != end2 && ! detail::section::exceeding<0>(dir2, *prev2, sec1.bounding_box, robust_policy);
|
||||
++prev2, ++it2, ++index2, ++next2, ++ndi2)
|
||||
{
|
||||
bool skip = same_source;
|
||||
@@ -317,25 +318,6 @@ private :
|
||||
typedef typename model::referring_segment<point1_type const> segment1_type;
|
||||
typedef typename model::referring_segment<point2_type const> segment2_type;
|
||||
|
||||
|
||||
template <size_t Dim, typename Point, typename Box, typename RobustPolicy>
|
||||
static inline bool preceding(int dir, Point const& point, Box const& box, RobustPolicy const& robust_policy)
|
||||
{
|
||||
typename robust_point_type<Point, RobustPolicy>::type robust_point;
|
||||
geometry::recalculate(robust_point, point, robust_policy);
|
||||
return (dir == 1 && get<Dim>(robust_point) < get<min_corner, Dim>(box))
|
||||
|| (dir == -1 && get<Dim>(robust_point) > get<max_corner, Dim>(box));
|
||||
}
|
||||
|
||||
template <size_t Dim, typename Point, typename Box, typename RobustPolicy>
|
||||
static inline bool exceeding(int dir, Point const& point, Box const& box, RobustPolicy const& robust_policy)
|
||||
{
|
||||
typename robust_point_type<Point, RobustPolicy>::type robust_point;
|
||||
geometry::recalculate(robust_point, point, robust_policy);
|
||||
return (dir == 1 && get<Dim>(robust_point) > get<max_corner, Dim>(box))
|
||||
|| (dir == -1 && get<Dim>(robust_point) < get<min_corner, Dim>(box));
|
||||
}
|
||||
|
||||
template <typename Iterator, typename RangeIterator, typename Section, typename RobustPolicy>
|
||||
static inline void advance_to_non_duplicate_next(Iterator& next,
|
||||
RangeIterator const& it, Section const& section, RobustPolicy const& robust_policy)
|
||||
@@ -386,7 +368,7 @@ private :
|
||||
// Mimic section-iterator:
|
||||
// Skip to point such that section interects other box
|
||||
prev = it++;
|
||||
for(; it != end && preceding<0>(dir, *it, other_bounding_box, robust_policy);
|
||||
for(; it != end && detail::section::preceding<0>(dir, *it, other_bounding_box, robust_policy);
|
||||
prev = it++, index++, ndi++)
|
||||
{}
|
||||
// Go back one step because we want to start completely preceding
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2015 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// 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_ALGORITHMS_DETAIL_SECTIONS_FUNCTIONS_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_SECTIONS_FUNCTIONS_HPP
|
||||
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
#include <boost/geometry/algorithms/detail/recalculate.hpp>
|
||||
#include <boost/geometry/policies/robustness/robust_point_type.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace section
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
std::size_t Dimension,
|
||||
typename Point,
|
||||
typename RobustBox,
|
||||
typename RobustPolicy
|
||||
>
|
||||
static inline bool preceding(int dir, Point const& point,
|
||||
RobustBox const& robust_box,
|
||||
RobustPolicy const& robust_policy)
|
||||
{
|
||||
typename geometry::robust_point_type<Point, RobustPolicy>::type robust_point;
|
||||
geometry::recalculate(robust_point, point, robust_policy);
|
||||
return (dir == 1 && get<Dimension>(robust_point) < get<min_corner, Dimension>(robust_box))
|
||||
|| (dir == -1 && get<Dimension>(robust_point) > get<max_corner, Dimension>(robust_box));
|
||||
}
|
||||
|
||||
template
|
||||
<
|
||||
std::size_t Dimension,
|
||||
typename Point,
|
||||
typename RobustBox,
|
||||
typename RobustPolicy
|
||||
>
|
||||
static inline bool exceeding(int dir, Point const& point,
|
||||
RobustBox const& robust_box,
|
||||
RobustPolicy const& robust_policy)
|
||||
{
|
||||
typename geometry::robust_point_type<Point, RobustPolicy>::type robust_point;
|
||||
geometry::recalculate(robust_point, point, robust_policy);
|
||||
return (dir == 1 && get<Dimension>(robust_point) > get<max_corner, Dimension>(robust_box))
|
||||
|| (dir == -1 && get<Dimension>(robust_point) < get<min_corner, Dimension>(robust_box));
|
||||
}
|
||||
|
||||
|
||||
}} // namespace detail::section
|
||||
#endif
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_SECTIONS_FUNCTIONS_HPP
|
||||
@@ -74,6 +74,7 @@ template
|
||||
struct section
|
||||
{
|
||||
typedef Box box_type;
|
||||
static std::size_t const dimension_count = DimensionCount;
|
||||
|
||||
int directions[DimensionCount];
|
||||
ring_identifier ring_id;
|
||||
@@ -286,13 +287,14 @@ struct sectionalize_part
|
||||
std::size_t max_count)
|
||||
{
|
||||
boost::ignore_unused_variable_warning(robust_policy);
|
||||
|
||||
typedef typename boost::range_value<Sections>::type section_type;
|
||||
BOOST_STATIC_ASSERT
|
||||
(
|
||||
(static_cast<int>(Sections::value)
|
||||
(static_cast<int>(section_type::dimension_count)
|
||||
== static_cast<int>(boost::mpl::size<DimensionVector>::value))
|
||||
);
|
||||
|
||||
typedef typename boost::range_value<Sections>::type section_type;
|
||||
typedef typename geometry::robust_point_type
|
||||
<
|
||||
Point,
|
||||
@@ -765,17 +767,13 @@ inline void sectionalize(Geometry const& geometry,
|
||||
{
|
||||
concept::check<Geometry const>();
|
||||
|
||||
BOOST_STATIC_ASSERT
|
||||
(
|
||||
(static_cast<int>(Sections::value)
|
||||
== static_cast<int>(boost::mpl::size<DimensionVector>::value))
|
||||
);
|
||||
typedef typename boost::range_value<Sections>::type section_type;
|
||||
|
||||
// Compiletime check for point type of section boxes
|
||||
// and point type related to robust policy
|
||||
typedef typename geometry::coordinate_type
|
||||
<
|
||||
typename Sections::box_type
|
||||
typename section_type::box_type
|
||||
>::type ctype1;
|
||||
typedef typename geometry::coordinate_type
|
||||
<
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <boost/geometry/strategies/within.hpp>
|
||||
#include <boost/geometry/strategies/covered_by.hpp>
|
||||
|
||||
#include <boost/geometry/util/range.hpp>
|
||||
#include <boost/geometry/views/detail/normalized_view.hpp>
|
||||
|
||||
namespace boost { namespace geometry {
|
||||
@@ -197,11 +198,11 @@ struct point_in_geometry<Linestring, linestring_tag>
|
||||
return -1; // exterior
|
||||
|
||||
// if the linestring doesn't have a boundary
|
||||
if ( detail::equals::equals_point_point(*boost::begin(linestring), *(--boost::end(linestring))) )
|
||||
if (detail::equals::equals_point_point(range::front(linestring), range::back(linestring)))
|
||||
return 1; // interior
|
||||
// else if the point is equal to the one of the terminal points
|
||||
else if ( detail::equals::equals_point_point(point, *boost::begin(linestring))
|
||||
|| detail::equals::equals_point_point(point, *(--boost::end(linestring))) )
|
||||
else if (detail::equals::equals_point_point(point, range::front(linestring))
|
||||
|| detail::equals::equals_point_point(point, range::back(linestring)))
|
||||
return 0; // boundary
|
||||
else
|
||||
return 1; // interior
|
||||
@@ -210,7 +211,7 @@ struct point_in_geometry<Linestring, linestring_tag>
|
||||
// throw an exception here?
|
||||
/*else if ( count == 1 )
|
||||
{
|
||||
if ( detail::equals::equals_point_point(point, *boost::begin(linestring)) )
|
||||
if ( detail::equals::equals_point_point(point, range::front(linestring)) )
|
||||
return 1;
|
||||
}*/
|
||||
|
||||
@@ -336,8 +337,8 @@ struct point_in_geometry<Geometry, multi_linestring_tag>
|
||||
if ( boost::size(*it) < 2 )
|
||||
continue;
|
||||
|
||||
point_type const& front = *boost::begin(*it);
|
||||
point_type const& back = *(--boost::end(*it));
|
||||
point_type const& front = range::front(*it);
|
||||
point_type const& back = range::back(*it);
|
||||
|
||||
// is closed_ring - no boundary
|
||||
if ( detail::equals::equals_point_point(front, back) )
|
||||
|
||||
@@ -95,8 +95,9 @@ public :
|
||||
|
||||
//! \brief Constructs the strategy
|
||||
//! \param points_per_circle points which would be used for a full circle
|
||||
//! (if points_per_circle is smaller than 4, it is internally set to 4)
|
||||
explicit inline end_round(std::size_t points_per_circle = 90)
|
||||
: m_points_per_circle(points_per_circle)
|
||||
: m_points_per_circle((points_per_circle < 4u) ? 4u : points_per_circle)
|
||||
{}
|
||||
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||
@@ -106,7 +107,7 @@ public :
|
||||
inline void apply(Point const& penultimate_point,
|
||||
Point const& perp_left_point,
|
||||
Point const& ultimate_point,
|
||||
Point const& ,
|
||||
Point const& perp_right_point,
|
||||
buffer_side_selector side,
|
||||
DistanceStrategy const& distance,
|
||||
RangeOut& range_out) const
|
||||
@@ -142,6 +143,13 @@ public :
|
||||
set<1>(shifted_point, get<1>(ultimate_point) + dist_half_diff * sin(alpha));
|
||||
generate_points(shifted_point, alpha, (dist_left + dist_right) / two, range_out);
|
||||
}
|
||||
|
||||
if (m_points_per_circle % 2 == 1)
|
||||
{
|
||||
// For a half circle, if the number of points is not even,
|
||||
// we should insert the end point too, to generate a full cap
|
||||
range_out.push_back(perp_right_point);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename NumericType>
|
||||
|
||||
@@ -35,6 +35,8 @@ namespace strategy { namespace buffer
|
||||
their length. The miter is not changed to a bevel form (as done in some
|
||||
other software), it is just adapted to the specified miter_limit but keeps
|
||||
its miter form.
|
||||
If the buffer distance is 5.0, and the miter limit is 2.0, generated points
|
||||
will be located at a distance of at most 10.0 (2*5) units.
|
||||
This strategy is only applicable for Cartesian coordinate systems.
|
||||
|
||||
\qbk{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2012-2015 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -9,6 +9,8 @@
|
||||
#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_JOIN_ROUND_HPP
|
||||
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_JOIN_ROUND_HPP
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/geometry/core/cs.hpp>
|
||||
#include <boost/geometry/policies/compare.hpp>
|
||||
@@ -83,15 +85,13 @@ private :
|
||||
{
|
||||
angle2 -= two_pi;
|
||||
}
|
||||
PromotedType const dangle = angle1 - angle2;
|
||||
|
||||
// Divide the angle into an integer amount of steps to make it
|
||||
// visually correct also for a low number of points / circle
|
||||
int const n = static_cast<int>
|
||||
(
|
||||
m_points_per_circle * (angle1 - angle2) / two_pi
|
||||
);
|
||||
int const n = static_cast<int>(m_points_per_circle * dangle / two_pi);
|
||||
|
||||
PromotedType const diff = (angle1 - angle2) / static_cast<PromotedType>(n);
|
||||
PromotedType const diff = dangle / static_cast<PromotedType>(n);
|
||||
PromotedType a = angle1 - diff;
|
||||
for (int i = 0; i < n - 1; i++, a -= diff)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
// Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// Copyright (c) 2012-2015 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// This file was modified by Oracle on 2015.
|
||||
// Modifications copyright (c) 2015, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, 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)
|
||||
@@ -45,9 +52,10 @@ class point_circle
|
||||
{
|
||||
public :
|
||||
//! \brief Constructs the strategy
|
||||
//! \param count number of points for the created circle
|
||||
//! \param count number of points for the created circle (if count
|
||||
//! is smaller than 3, count is internally set to 3)
|
||||
explicit point_circle(std::size_t count = 90)
|
||||
: m_count(count)
|
||||
: m_count((count < 3u) ? 3u : count)
|
||||
{}
|
||||
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||
|
||||
@@ -138,7 +138,7 @@ back(BidirectionalRange const& rng)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT(( boost::BidirectionalRangeConcept<BidirectionalRange const> ));
|
||||
BOOST_ASSERT(!boost::empty(rng));
|
||||
return *(--boost::end(rng));
|
||||
return *(boost::rbegin(rng));
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -151,7 +151,7 @@ back(BidirectionalRange & rng)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT(( boost::BidirectionalRangeConcept<BidirectionalRange> ));
|
||||
BOOST_ASSERT(!boost::empty(rng));
|
||||
return *(--boost::end(rng));
|
||||
return *(boost::rbegin(rng));
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user