mirror of
https://github.com/boostorg/geometry.git
synced 2025-05-11 13:34:10 +00:00
Buffer, added intersection check on already splitted of rings. This is necessary for cases like #indentation7 where the new helper-line crosses an already moved other helperline.
[SVN r76776]
This commit is contained in:
parent
a4e0d5c384
commit
1f5e4c45e4
@ -63,6 +63,7 @@ public :
|
||||
|
||||
inline void append_begin_join(point_type const& point)
|
||||
{
|
||||
DEBUG("begin join");
|
||||
check(point);
|
||||
|
||||
cleanup();
|
||||
@ -73,11 +74,15 @@ public :
|
||||
|
||||
inline void append_end_join(point_type const& point)
|
||||
{
|
||||
clean_split_offs();
|
||||
|
||||
DEBUG("end join");
|
||||
do_append(point);
|
||||
}
|
||||
|
||||
inline void append_begin_hooklet(point_type const& point)
|
||||
{
|
||||
DEBUG("begin hooklet");
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
|
||||
const_cast<Mapper&>(m_mapper).map(point, "fill:rgb(0,0,192);", 3);
|
||||
#endif
|
||||
@ -93,6 +98,7 @@ public :
|
||||
|
||||
inline void append_end_hooklet(point_type const& point)
|
||||
{
|
||||
DEBUG("end hooklet");
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
|
||||
const_cast<Mapper&>(m_mapper).map(point, "fill:rgb(0,0,255);", 4);
|
||||
#endif
|
||||
@ -149,16 +155,34 @@ private :
|
||||
{
|
||||
if (rit->end >= rit->begin
|
||||
&& calculate_ip(point, *rit))
|
||||
{
|
||||
// We HAVE to leave here
|
||||
// because the deque is cleared in between
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Second loop to check for intersections on intersected pieces
|
||||
for (typename std::deque<piece>::const_reverse_iterator rit
|
||||
= m_pieces.rbegin();
|
||||
rit != m_pieces.rend();
|
||||
++rit)
|
||||
{
|
||||
if (rit->end >= rit->begin)
|
||||
{
|
||||
// We HAVE to leave here
|
||||
// because the deque is cleared in between
|
||||
return;
|
||||
if (calculate_ip2(point, *rit))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
|
||||
const_cast<Mapper&>(m_mapper).map(point, "fill:rgb(0,255,0);", 5);
|
||||
#endif
|
||||
if (! m_pieces.empty() && m_pieces.back().end > m_pieces.back().begin)
|
||||
{
|
||||
const_cast<Mapper&>(m_mapper).map(point, "fill:rgb(0,255,0);", 4);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
inline bool calculate_ip(point_type const& point, piece const& the_piece)
|
||||
@ -201,6 +225,46 @@ private :
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool calculate_ip2(point_type const& point, piece const& the_piece)
|
||||
{
|
||||
segment_type segment1(m_previous_point, point);
|
||||
|
||||
// No IP found. Check if it is in the split off
|
||||
if (! the_piece.split_off.empty() && the_piece.type == 'I')
|
||||
{
|
||||
//typedef typename boost::reverse_iterator<Range const>::type ritt;
|
||||
typedef typename Range::const_reverse_iterator ritt;
|
||||
ritt previous = the_piece.split_off.rbegin();
|
||||
for (ritt rit = previous++; rit != the_piece.split_off.rend(); ++rit)
|
||||
{
|
||||
segment_type segment2(*rit, *previous);
|
||||
segment_intersection_points<point_type> is
|
||||
= policy::apply(segment1, segment2);
|
||||
if (is.count == 1)
|
||||
{
|
||||
Range split_off;
|
||||
if (get_valid_split(is.intersections[0], the_piece.begin + 1, split_off))
|
||||
{
|
||||
DEBUG("split off from splitted off");
|
||||
|
||||
add_ip(is.intersections[0], the_piece.begin + 1, the_piece, split_off);
|
||||
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
|
||||
const_cast<Mapper&>(m_mapper).map(is.intersections[0], "fill:rgb(255,255,0);", 4);
|
||||
const_cast<Mapper&>(m_mapper).map(m_range[the_piece.begin], "fill:rgb(255,192,0);", 4);
|
||||
const_cast<Mapper&>(m_mapper).map(split_off, "fill:none;stroke:rgb(255,192,0);stroke-width:2");
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
previous = rit;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -249,6 +313,32 @@ private :
|
||||
m_pieces.resize(0);
|
||||
}
|
||||
}
|
||||
|
||||
inline void clean_split_offs()
|
||||
{
|
||||
for (typename std::deque<piece>::iterator it = m_pieces.begin();
|
||||
it != m_pieces.end();
|
||||
++it)
|
||||
{
|
||||
it->split_off.resize(0);
|
||||
}
|
||||
}
|
||||
|
||||
inline void DEBUG(std::string const& caption)
|
||||
{
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_BUFFER_APPENDER
|
||||
std::cout << " " << caption;
|
||||
for (typename std::deque<piece>::iterator it
|
||||
= m_pieces.begin();
|
||||
it != m_pieces.end();
|
||||
++it)
|
||||
{
|
||||
std::cout << " " << it->type << " " << it->begin << "-" << it->end
|
||||
<< " " << it->split_off.size();
|
||||
}
|
||||
std::cout << std::endl;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -106,10 +106,12 @@ void test_all()
|
||||
test_one<polygon_type, buf::join_round, polygon_type>("arrow6", arrow, 'r', 32.2572740033805, 0.6);
|
||||
|
||||
test_one<polygon_type, buf::join_miter, polygon_type>(true, "tipped_aitch3", tipped_aitch, 'm', 54.865, 0.3);
|
||||
test_one<polygon_type, buf::join_miter, polygon_type>(true, "tipped_aitch9", tipped_aitch, 'm', 75.685, 0.9);
|
||||
test_one<polygon_type, buf::join_miter, polygon_type>(true, "tipped_aitch9", tipped_aitch, 'm', 77.44, 0.9);
|
||||
test_one<polygon_type, buf::join_miter, polygon_type>(true, "tipped_aitch13", tipped_aitch, 'm', 89.365, 1.3);
|
||||
|
||||
// SQL Server: 55.205415532967 76.6468846383224 90.642916957136
|
||||
test_one<polygon_type, buf::join_round, polygon_type>(true, "tipped_aitch3", tipped_aitch, 'r', 54.7552, 0.3);
|
||||
test_one<polygon_type, buf::join_round, polygon_type>(true, "tipped_aitch9", tipped_aitch, 'r', 75.2957, 0.9);
|
||||
test_one<polygon_type, buf::join_round, polygon_type>(true, "tipped_aitch9", tipped_aitch, 'r', 76.6457, 0.9);
|
||||
test_one<polygon_type, buf::join_round, polygon_type>(true, "tipped_aitch13", tipped_aitch, 'r', 88.6906, 1.3);
|
||||
|
||||
test_one<polygon_type, buf::join_miter, polygon_type>(true, "snake4", snake, 'm', 63.76, 0.4);
|
||||
@ -120,29 +122,33 @@ void test_all()
|
||||
//return;
|
||||
|
||||
|
||||
test_one<polygon_type, buf::join_round, polygon_type>(true, "flower1", flower, 'r', 71.986, 0.1);
|
||||
test_one<polygon_type, buf::join_miter, polygon_type>("flower1", flower, 'm', 67.613949189084963, 0.1);
|
||||
test_one<polygon_type, buf::join_miter, polygon_type>("flower20", flower, 'm', 74.7020267929856, 0.20);
|
||||
test_one<polygon_type, buf::join_miter, polygon_type>("flower25", flower, 'm', 78.225583936485492, 0.25);
|
||||
test_one<polygon_type, buf::join_miter, polygon_type>("flower30", flower, 'm', 81.492494146177947, 0.30);
|
||||
//test_one<polygon_type, buf::join_miter, polygon_type>("flower35", flower, 'm', 84.694183819917185, 0.35);
|
||||
test_one<polygon_type, buf::join_miter, polygon_type>("flower4", flower, 'm', 87.8306529577, 0.4);
|
||||
test_one<polygon_type, buf::join_miter, polygon_type>("flower40", flower, 'm', 87.8306529577, 0.40);
|
||||
test_one<polygon_type, buf::join_miter, polygon_type>("flower45", flower, 'm', 90.901901559536029, 0.45);
|
||||
test_one<polygon_type, buf::join_miter, polygon_type>("flower50", flower, 'm', 93.907929625415662, 0.50);
|
||||
test_one<polygon_type, buf::join_miter, polygon_type>("flower55", flower, 'm', 96.848737155342079, 0.55);
|
||||
test_one<polygon_type, buf::join_miter, polygon_type>("flower60", flower, 'm', 99.724324149315279, 0.60);
|
||||
|
||||
test_one<polygon_type, buf::join_miter, polygon_type>("flower1", flower, 'm', 67.613949189084963, 0.1);
|
||||
test_one<polygon_type, buf::join_round, polygon_type>("flower25", flower, 'r', 78.0709684961456, 0.25);
|
||||
test_one<polygon_type, buf::join_round, polygon_type>("flower30", flower, 'r', 81.3528270913593, 0.30);
|
||||
test_one<polygon_type, buf::join_round, polygon_type>("flower35", flower, 'r', 84.5467340913191, 0.35);
|
||||
test_one<polygon_type, buf::join_round, polygon_type>("flower4", flower, 'r', 87.6653813523005, 0.4);
|
||||
test_one<polygon_type, buf::join_round, polygon_type>("flower45", flower, 'r', 90.7092077149493, 0.45);
|
||||
test_one<polygon_type, buf::join_round, polygon_type>("flower50", flower, 'r', 93.6802057531291, 0.50);
|
||||
test_one<polygon_type, buf::join_round, polygon_type>("flower55", flower, 'r', 96.5796252237181, 0.55);
|
||||
test_one<polygon_type, buf::join_round, polygon_type>("flower60", flower, 'r', 99.4081550761828, 0.60);
|
||||
test_one<polygon_type, buf::join_round, polygon_type>(true, "flower1", flower, 'r', 71.986, 0.1);
|
||||
test_one<polygon_type, buf::join_round, polygon_type>(true, "flower20", flower, 'r', 74.7020267929856, 0.20);
|
||||
test_one<polygon_type, buf::join_round, polygon_type>(true, "flower25", flower, 'r', 78.0709684961456, 0.25);
|
||||
test_one<polygon_type, buf::join_round, polygon_type>(true, "flower30", flower, 'r', 81.3528270913593, 0.30);
|
||||
test_one<polygon_type, buf::join_round, polygon_type>(true, "flower35", flower, 'r', 84.5467340913191, 0.35);
|
||||
test_one<polygon_type, buf::join_round, polygon_type>(true, "flower40", flower, 'r', 87.6653813523005, 0.40);
|
||||
test_one<polygon_type, buf::join_round, polygon_type>(true, "flower45", flower, 'r', 90.7092077149493, 0.45);
|
||||
test_one<polygon_type, buf::join_round, polygon_type>(true, "flower50", flower, 'r', 93.6802057531291, 0.50);
|
||||
test_one<polygon_type, buf::join_round, polygon_type>(true, "flower55", flower, 'r', 96.5796252237181, 0.55);
|
||||
test_one<polygon_type, buf::join_round, polygon_type>(true, "flower60", flower, 'r', 99.4081550761828, 0.60);
|
||||
|
||||
//test_one<polygon_type, buf::join_miter, polygon_type>("flower35", flower, 'm', 84.694183819917185, 0.35);
|
||||
// Saw
|
||||
{
|
||||
// SQL Server:
|
||||
// 68.6258859984014 90.2254986930165 112.799509089077 136.392823913949 161.224547934625 187.427508982734
|
||||
//215.063576036522 244.167935815974 274.764905445676 306.878264367143 340.530496138041 375.720107548269
|
||||
int const n = 12;
|
||||
double expected_round[n] =
|
||||
{
|
||||
@ -166,18 +172,24 @@ void test_all()
|
||||
|
||||
// Bowl
|
||||
{
|
||||
// Note the values are not completely equal to SQL Server yet.
|
||||
// This will be caused by the sometimes sloppy rounded corners we still have
|
||||
// See query below.
|
||||
//1 43.2425133175081 60.0257800296593 78.3497997564532 98.2145746255142 119.620102487345 142.482792724034
|
||||
//2 166.499856911107 191.763334982583 218.446279387336 246.615018368511 276.300134755606 307.518458532186
|
||||
|
||||
int const n = 12;
|
||||
double expected_round[n] =
|
||||
{
|
||||
44.492, 60.025, 77.097, 95.710, 115.863, 137.472,
|
||||
160.235, 184.244, 209.672, 236.586, 265.015, 294.978
|
||||
166.485, 191.744, 209.672, 236.586, 265.015, 294.978
|
||||
};
|
||||
|
||||
|
||||
double expected_miter[n] =
|
||||
{
|
||||
44.865, 61.014, 78.948, 98.666, 120.169, 143.374,
|
||||
167.974, 193.943, 221.279, 250.000, 280.375, 312.500
|
||||
167.974, 207.443, 221.279, 250.000, 280.375, 312.500
|
||||
};
|
||||
|
||||
for (int i = 1; i <= n; i++)
|
||||
@ -274,3 +286,35 @@ int test_main(int, char* [])
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
BOWL QUERY
|
||||
===
|
||||
with bowl as
|
||||
(
|
||||
select geometry::STGeomFromText('POLYGON((1 2,1 7,2 7,3 5,5 4,7 5,8 7,9 7,9 2,1 2))',0) as q
|
||||
)
|
||||
select
|
||||
'1-6' as row
|
||||
,q.STBuffer(0.5).STArea() as b1
|
||||
,q.STBuffer(1.0).STArea() as b2
|
||||
,q.STBuffer(1.5).STArea() as b3
|
||||
,q.STBuffer(2.0).STArea() as b4
|
||||
,q.STBuffer(2.5).STArea() as b5
|
||||
,q.STBuffer(3.0).STArea() as b6
|
||||
|
||||
from bowl
|
||||
union all
|
||||
select
|
||||
'7-12'
|
||||
,q.STBuffer(3.5).STArea() as b7
|
||||
,q.STBuffer(4.0).STArea() as b8
|
||||
,q.STBuffer(4.5).STArea() as b9
|
||||
,q.STBuffer(5.0).STArea() as b10
|
||||
,q.STBuffer(5.5).STArea() as b11
|
||||
,q.STBuffer(6.0).STArea() as b12
|
||||
from bowl
|
||||
|
||||
|
||||
*/
|
@ -10,7 +10,7 @@
|
||||
#ifndef BOOST_GEOMETRY_TEST_BUFFER_HPP
|
||||
#define BOOST_GEOMETRY_TEST_BUFFER_HPP
|
||||
|
||||
// #define BOOST_GEOMETRY_DEBUG_WITH_MAPPER
|
||||
//#define BOOST_GEOMETRY_DEBUG_WITH_MAPPER
|
||||
#define TEST_WITH_SVG
|
||||
|
||||
#include <fstream>
|
||||
@ -112,6 +112,8 @@ void test_buffer(std::string const& caseid, Geometry const& geometry,
|
||||
<< string_from_type<coordinate_type>::name()
|
||||
<< "_" << join;
|
||||
|
||||
//std::cout << complete.str() << std::endl;
|
||||
|
||||
std::ostringstream filename;
|
||||
filename << "buffer_" << complete.str() << ".svg";
|
||||
|
||||
@ -183,17 +185,19 @@ void test_buffer(std::string const& caseid, Geometry const& geometry,
|
||||
}
|
||||
#endif
|
||||
|
||||
if (boost::contains(complete.str(), "indentation4_d")
|
||||
|| boost::contains(complete.str(), "indentation5_d")
|
||||
|| boost::contains(complete.str(), "indentation6_d")
|
||||
|| boost::contains(complete.str(), "indentation7_d")
|
||||
|| boost::contains(complete.str(), "indentation8_d")
|
||||
|| boost::contains(complete.str(), "indentation12_d")
|
||||
if (boost::contains(complete.str(), "bowl")
|
||||
|| boost::contains(complete.str(), "aitch")
|
||||
|| boost::contains(complete.str(), "snake")
|
||||
|| (boost::contains(complete.str(), "indentation")
|
||||
&& ! boost::contains(complete.str(), "neg"))
|
||||
|| (boost::contains(complete.str(), "flower")
|
||||
&& boost::contains(complete.str(), "d_r"))
|
||||
)
|
||||
{
|
||||
// We dissolve some controlled cases (already, later we will dissolve all),
|
||||
// such that we can detect regressions
|
||||
bg::dissolve(buffered_step1, buffered);
|
||||
mapper.map(buffered_step1, "opacity:0.3;fill:none;stroke:rgb(0,0,200);stroke-width:2");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user