mirror of https://github.com/CGAL/cgal
Merge pull request #2342 from sloriot/Argt-overlap_intersect_at_insertion
Reworking the handling of overlaps
This commit is contained in:
commit
2cec8e6aca
|
|
@ -2441,7 +2441,7 @@ protected:
|
|||
{
|
||||
x = x_left + x_jump*i;
|
||||
disc = app_sqr_rad - CGAL::square(x - app_xcenter);
|
||||
CGAL_precondition(disc >= 0);
|
||||
if (disc < 0) disc = 0;
|
||||
if(is_up)
|
||||
y = app_ycenter + std::sqrt(disc);
|
||||
else
|
||||
|
|
|
|||
|
|
@ -450,8 +450,7 @@ protected:
|
|||
* \param curve The subcurve to add.
|
||||
* \return (true) if an overlap occured; (false) otherwise.
|
||||
*/
|
||||
virtual bool _add_curve_to_right(Event* event, Subcurve* curve,
|
||||
bool overlap_exist = false);
|
||||
virtual bool _add_curve_to_right(Event* event, Subcurve* curve);
|
||||
|
||||
/*! Remove a curve from the status line. */
|
||||
void _remove_curve_from_status_line(Subcurve *leftCurve);
|
||||
|
|
|
|||
|
|
@ -225,9 +225,19 @@ bool Construction_test<T_Geom_traits, T_Topol_traits>::are_same_results()
|
|||
<< m_num_faces << ")" << std::endl;
|
||||
}
|
||||
|
||||
if (m_arr->number_of_vertices() != m_num_vertices) return false;
|
||||
if (m_arr->number_of_edges() != m_num_edges) return false;
|
||||
if (m_arr->number_of_faces() != m_num_faces) return false;
|
||||
if ((m_arr->number_of_vertices() != m_num_vertices) ||
|
||||
(m_arr->number_of_edges() != m_num_edges) ||
|
||||
(m_arr->number_of_faces() != m_num_faces)) {
|
||||
std::cout << "# vertices, edge, faces obtained: ("
|
||||
<< m_arr->number_of_vertices() << ","
|
||||
<< m_arr->number_of_edges() << ","
|
||||
<< m_arr->number_of_faces() << ")"
|
||||
<< ", expected: ("
|
||||
<< m_num_vertices << ","
|
||||
<< m_num_edges << ","
|
||||
<< m_num_faces << ")" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
Point_container points_res(m_num_vertices);
|
||||
typename Point_container::iterator pit = points_res.begin();
|
||||
|
|
@ -239,13 +249,20 @@ bool Construction_test<T_Geom_traits, T_Topol_traits>::are_same_results()
|
|||
std::sort(points_res.begin(), pit, pt_compare);
|
||||
|
||||
if (m_verbose_level > 2) {
|
||||
std::copy(points_res.begin(), pit,
|
||||
std::copy(points_res.begin(), points_res.end(),
|
||||
std::ostream_iterator<Point_2>(std::cout, "\n"));
|
||||
}
|
||||
|
||||
Point_equal point_eq(m_geom_traits);
|
||||
if (! std::equal(points_res.begin(), pit, m_points.begin(), point_eq))
|
||||
if (! std::equal(points_res.begin(), pit, m_points.begin(), point_eq)) {
|
||||
std::cout << "Expected: " << std::endl;
|
||||
std::copy(m_points.begin(), m_points.end(),
|
||||
std::ostream_iterator<Point_2>(std::cout, "\n"));
|
||||
std::cout << "Obtained: " << std::endl;
|
||||
std::copy(points_res.begin(), points_res.end(),
|
||||
std::ostream_iterator<Point_2>(std::cout, "\n"));
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<X_monotone_curve_2> curves_res(m_arr->number_of_edges());
|
||||
typename Xcurve_container::iterator xcit = curves_res.begin();
|
||||
|
|
@ -259,13 +276,23 @@ bool Construction_test<T_Geom_traits, T_Topol_traits>::are_same_results()
|
|||
std::sort(curves_res.begin(), xcit, curve_compare);
|
||||
|
||||
if (m_verbose_level > 2) {
|
||||
std::copy(curves_res.begin(), xcit,
|
||||
std::ostream_iterator<X_monotone_curve_2>(std::cout, "\n"));
|
||||
for (typename Xcurve_container::iterator it = curves_res.begin();
|
||||
it != curves_res.end(); ++it)
|
||||
std::cout << *it << " " << it->data() << std::endl;
|
||||
}
|
||||
|
||||
Curve_equal curve_eq(m_geom_traits);
|
||||
if (! std::equal(curves_res.begin(), xcit, m_xcurves.begin(), curve_eq))
|
||||
if (! std::equal(curves_res.begin(), xcit, m_xcurves.begin(), curve_eq)) {
|
||||
std::cout << "Expected: " << std::endl;
|
||||
for (typename Xcurve_container::iterator it = m_xcurves.begin();
|
||||
it != m_xcurves.end(); ++it)
|
||||
std::cout << *it << " " << it->data() << std::endl;
|
||||
std::cout << "Obtained: " << std::endl;
|
||||
for (typename Xcurve_container::iterator it = curves_res.begin();
|
||||
it != curves_res.end(); ++it)
|
||||
std::cout << *it << " " << it->data() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_arr->number_of_faces() == 1) {
|
||||
Face_const_iterator fit = m_arr->faces_begin();
|
||||
|
|
|
|||
|
|
@ -686,6 +686,18 @@ function(test_construction_spherical_arcs)
|
|||
compile_and_run_with_flags( test_construction geodesic_arcs_on_sphere "${flags}")
|
||||
endfunction()
|
||||
|
||||
#---------------------------------------------------------------------#
|
||||
# construction with polylines
|
||||
#---------------------------------------------------------------------#
|
||||
function(test_construction_polylines)
|
||||
set(nt ${CGAL_GMPQ_NT})
|
||||
set(kernel ${CARTESIAN_KERNEL})
|
||||
set(geom_traits ${POLYLINE_GEOM_TRAITS})
|
||||
set(flags "-DTEST_NT=${nt} -DTEST_KERNEL=${kernel} -DTEST_GEOM_TRAITS=${geom_traits}")
|
||||
compile_and_run_with_flags( test_construction polylines "${flags}")
|
||||
endfunction()
|
||||
|
||||
|
||||
#---------------------------------------------------------------------#
|
||||
# overlay with segments
|
||||
#---------------------------------------------------------------------#
|
||||
|
|
@ -1371,6 +1383,7 @@ compile_and_run(test_vert_ray_shoot_vert_segments)
|
|||
test_construction_segments()
|
||||
test_construction_linear_curves()
|
||||
test_construction_spherical_arcs()
|
||||
test_construction_polylines()
|
||||
|
||||
test_overlay_segments()
|
||||
test_overlay_spherical_arcs()
|
||||
|
|
|
|||
|
|
@ -873,6 +873,18 @@ test_construction_spherical_arcs()
|
|||
compile_and_run_with_flags test_construction geodesic_arcs_on_sphere "$flags"
|
||||
}
|
||||
|
||||
#---------------------------------------------------------------------#
|
||||
# construction with polylines
|
||||
#---------------------------------------------------------------------#
|
||||
test_construction_polylines()
|
||||
{
|
||||
local nt=$CGAL_GMPQ_NT;
|
||||
local kernel=$CARTESIAN_KERNEL;
|
||||
local geom_traits=$POLYLINE_GEOM_TRAITS;
|
||||
local flags="-DTEST_NT=$nt -DTEST_KERNEL=$kernel -DTEST_GEOM_TRAITS=$geom_traits";
|
||||
compile_and_run_with_flags test_construction polylines "$flags"
|
||||
}
|
||||
|
||||
#---------------------------------------------------------------------#
|
||||
# overlay with segments
|
||||
#---------------------------------------------------------------------#
|
||||
|
|
@ -1699,6 +1711,7 @@ compile_and_run test_vert_ray_shoot_vert_segments
|
|||
test_construction_segments
|
||||
test_construction_linear
|
||||
test_construction_spherical_arcs
|
||||
test_construction_polylines
|
||||
|
||||
test_overlay_segments
|
||||
test_overlay_spherical_arcs
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
test06 covers the case "Overlap with common ancestors"
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
3
|
||||
2 0 0 7 0
|
||||
3 3 1 4 0 6 0
|
||||
3 1 0 3 2 5 0
|
||||
0
|
||||
|
||||
7
|
||||
7
|
||||
2
|
||||
|
||||
0 0
|
||||
1 0
|
||||
3 1
|
||||
4 0
|
||||
5 0
|
||||
6 0
|
||||
7 0
|
||||
|
||||
2 0 0 1 0 1
|
||||
2 1 0 4 0 1
|
||||
3 1 0 3 2 5 0 1
|
||||
2 3 1 4 0 1
|
||||
2 4 0 5 0 2
|
||||
2 5 0 6 0 2
|
||||
2 6 0 7 0 1
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
3
|
||||
2 0 0 7 0
|
||||
4 1 0 3 1 4 0 6 0
|
||||
3 0 -1 3 2 5 0
|
||||
|
||||
0
|
||||
|
||||
7
|
||||
8
|
||||
3
|
||||
|
||||
0 -1
|
||||
0 0
|
||||
1 0
|
||||
4 0
|
||||
5 0
|
||||
6 0
|
||||
7 0
|
||||
|
||||
2 0 -1 1 0 1
|
||||
2 0 0 1 0 1
|
||||
2 1 0 4 0 1
|
||||
3 1 0 3 1 4 0 1
|
||||
3 1 0 3 2 5 0 1
|
||||
2 4 0 5 0 2
|
||||
2 5 0 6 0 2
|
||||
2 6 0 7 0 1
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
3
|
||||
4 5 0 4 1 3 1 2 1
|
||||
5 5 0 4 1 3 1 2 1 0 0
|
||||
3 1 2 3 1 4 1
|
||||
0
|
||||
6
|
||||
5
|
||||
1
|
||||
0 0
|
||||
1 2
|
||||
2 1
|
||||
3 1
|
||||
4 1
|
||||
5 0
|
||||
2 2 1 0 0 1
|
||||
2 1 2 3 1 1
|
||||
2 2 1 3 1 2
|
||||
2 3 1 4 1 3
|
||||
2 4 1 5 0 2
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
3
|
||||
4 1 2 2 1 3 1 4 0
|
||||
4 0 0 2 1 3 1 4 0
|
||||
2 2 1 3 1
|
||||
0
|
||||
5
|
||||
4
|
||||
1
|
||||
0 0
|
||||
1 2
|
||||
2 1
|
||||
3 1
|
||||
4 0
|
||||
2 0 0 2 1 1
|
||||
2 1 2 2 1 1
|
||||
2 2 1 3 1 3
|
||||
2 3 1 4 0 2
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
3
|
||||
3 0 3 1 2 2 0
|
||||
3 0 1 1 2 2 0
|
||||
2 0 2 3 0
|
||||
0
|
||||
8
|
||||
8
|
||||
2
|
||||
0 1
|
||||
0 2
|
||||
0 3
|
||||
3/5 8/5
|
||||
1 2
|
||||
3/2 1
|
||||
2 0
|
||||
3 0
|
||||
|
||||
2 0 1 3/5 8/5 1
|
||||
2 0 2 3/5 8/5 1
|
||||
2 0 3 1 2 1
|
||||
2 3/5 8/5 3/2 1 1
|
||||
2 3/5 8/5 1 2 1
|
||||
2 1 2 3/2 1 2
|
||||
2 3/2 1 2 0 2
|
||||
2 3/2 1 3 0 1
|
||||
Binary file not shown.
|
|
@ -0,0 +1,35 @@
|
|||
4
|
||||
3 0 0 2 3 3 0
|
||||
2 0 3 4 0
|
||||
3 0 2 2 3 3 0
|
||||
3 0 1 2 3 3 0
|
||||
0
|
||||
11
|
||||
13
|
||||
4
|
||||
|
||||
0 0
|
||||
0 1
|
||||
0 2
|
||||
0 3
|
||||
4/5 12/5
|
||||
8/7 15/7
|
||||
4/3 2
|
||||
2 3
|
||||
8/3 1
|
||||
3 0
|
||||
4 0
|
||||
|
||||
2 0 0 4/3 2 1
|
||||
2 0 1 8/7 15/7 1
|
||||
2 0 2 4/5 12/5 1
|
||||
2 0 3 4/5 12/5 1
|
||||
2 4/5 12/5 8/7 15/7 1
|
||||
2 4/5 12/5 2 3 1
|
||||
2 8/7 15/7 4/3 2 1
|
||||
2 8/7 15/7 2 3 1
|
||||
2 4/3 2 8/3 1 1
|
||||
2 4/3 2 2 3 1
|
||||
2 2 3 8/3 1 3
|
||||
2 8/3 1 3 0 3
|
||||
2 8/3 1 4 0 1
|
||||
Binary file not shown.
|
|
@ -0,0 +1,54 @@
|
|||
3
|
||||
11 0 1 2 1 3 0 5 0 6 1 8 1 9 0 11 0 12 1 14 1 15 0
|
||||
11 0 0 1 1 3 1 4 0 6 0 7 1 9 1 10 0 12 0 13 1 15 1
|
||||
12 0 0 1 0 2 1 4 1 5 0 7 0 8 1 10 1 11 0 13 0 14 1 15 1
|
||||
0
|
||||
18
|
||||
26
|
||||
10
|
||||
|
||||
0 0
|
||||
0 1
|
||||
1 1
|
||||
2 1
|
||||
3 1
|
||||
4 0
|
||||
5 0
|
||||
6 0
|
||||
7 1
|
||||
8 1
|
||||
9 1
|
||||
10 0
|
||||
11 0
|
||||
12 0
|
||||
13 1
|
||||
14 1
|
||||
15 0
|
||||
15 1
|
||||
|
||||
3 0 0 1 0 2 1 1
|
||||
2 0 0 1 1 1
|
||||
2 0 1 1 1 1
|
||||
2 1 1 2 1 2
|
||||
3 2 1 3 0 4 0 1
|
||||
2 2 1 3 1 2
|
||||
2 3 1 4 0 1
|
||||
3 3 1 4 1 5 0 1
|
||||
2 4 0 5 0 2
|
||||
2 5 0 6 0 2
|
||||
3 5 0 6 1 7 1 1
|
||||
3 6 0 7 0 8 1 1
|
||||
2 6 0 7 1 1
|
||||
2 7 1 8 1 2
|
||||
3 8 1 9 0 10 0 1
|
||||
2 8 1 9 1 2
|
||||
2 9 1 10 0 1
|
||||
3 9 1 10 1 11 0 1
|
||||
2 10 0 11 0 2
|
||||
2 11 0 12 0 2
|
||||
3 11 0 12 1 13 1 1
|
||||
3 12 0 13 0 14 1 1
|
||||
2 12 0 13 1 1
|
||||
2 13 1 14 1 2
|
||||
2 14 1 15 0 1
|
||||
2 14 1 15 1 2
|
||||
Binary file not shown.
|
|
@ -0,0 +1,41 @@
|
|||
4
|
||||
4 0 0 4 1 11 1 15 0
|
||||
6 0 0 1 0 5 1 10 1 14 0 15 0
|
||||
6 0 0 2 0 6 1 9 1 13 0 15 0
|
||||
6 0 0 3 0 7 1 8 1 12 0 15 0
|
||||
0
|
||||
|
||||
12
|
||||
17
|
||||
7
|
||||
|
||||
0 0
|
||||
1 0
|
||||
2 0
|
||||
5 1
|
||||
6 1
|
||||
7 1
|
||||
8 1
|
||||
9 1
|
||||
10 1
|
||||
13 0
|
||||
14 0
|
||||
15 0
|
||||
|
||||
2 0 0 1 0 3
|
||||
3 0 0 4 1 5 1 1
|
||||
2 1 0 2 0 2
|
||||
2 1 0 5 1 1
|
||||
3 2 0 3 0 7 1 1
|
||||
2 2 0 6 1 1
|
||||
2 5 1 6 1 2
|
||||
2 6 1 7 1 3
|
||||
2 7 1 8 1 4
|
||||
3 8 1 12 0 13 0 1
|
||||
2 8 1 9 1 3
|
||||
2 9 1 13 0 1
|
||||
2 9 1 10 1 2
|
||||
2 10 1 14 0 1
|
||||
3 10 1 11 1 15 0 1
|
||||
2 13 0 14 0 2
|
||||
2 14 0 15 0 3
|
||||
Binary file not shown.
|
|
@ -0,0 +1,75 @@
|
|||
4
|
||||
4 0 4 4 0 13 0 17 4
|
||||
4 0 3 5 0 12 0 17 3
|
||||
4 0 2 6 0 11 0 17 2
|
||||
4 0 1 7 0 10 0 17 1
|
||||
0
|
||||
|
||||
26
|
||||
37
|
||||
13
|
||||
|
||||
0 1
|
||||
0 2
|
||||
0 3
|
||||
0 4
|
||||
5/2 3/2
|
||||
3 1
|
||||
7/2 1/2
|
||||
15/4 3/4
|
||||
35/8 3/8
|
||||
5 0
|
||||
21/4 1/4
|
||||
6 0
|
||||
7 0
|
||||
10 0
|
||||
11 0
|
||||
47/4 1/4
|
||||
12 0
|
||||
101/8 3/8
|
||||
53/4 3/4
|
||||
27/2 1/2
|
||||
14 1
|
||||
29/2 3/2
|
||||
17 1
|
||||
17 2
|
||||
17 3
|
||||
17 4
|
||||
|
||||
2 0 1 7/2 1/2 1
|
||||
2 0 2 3 1 1
|
||||
2 0 3 5/2 3/2 1
|
||||
2 0 4 5/2 3/2 1
|
||||
2 5/2 3/2 3 1 1
|
||||
2 5/2 3/2 15/4 3/4 1
|
||||
2 3 1 7/2 1/2 1
|
||||
2 3 1 15/4 3/4 1
|
||||
3 7/2 1/2 4 0 5 0 1
|
||||
2 7/2 1/2 35/8 3/8 1
|
||||
2 15/4 3/4 35/8 3/8 1
|
||||
2 15/4 3/4 21/4 1/4 1
|
||||
2 35/8 3/8 5 0 1
|
||||
2 35/8 3/8 21/4 1/4 1
|
||||
2 5 0 6 0 2
|
||||
2 21/4 1/4 6 0 1
|
||||
2 21/4 1/4 7 0 1
|
||||
2 6 0 7 0 3
|
||||
2 7 0 10 0 4
|
||||
2 10 0 11 0 3
|
||||
2 10 0 47/4 1/4 1
|
||||
2 11 0 12 0 2
|
||||
2 11 0 47/4 1/4 1
|
||||
2 47/4 1/4 101/8 3/8 1
|
||||
2 47/4 1/4 53/4 3/4 1
|
||||
3 12 0 13 0 27/2 1/2 1
|
||||
2 12 0 101/8 3/8 1
|
||||
2 101/8 3/8 27/2 1/2 1
|
||||
2 101/8 3/8 53/4 3/4 1
|
||||
2 53/4 3/4 14 1 1
|
||||
2 53/4 3/4 29/2 3/2 1
|
||||
2 27/2 1/2 17 1 1
|
||||
2 27/2 1/2 14 1 1
|
||||
2 14 1 17 2 1
|
||||
2 14 1 29/2 3/2 1
|
||||
2 29/2 3/2 17 3 1
|
||||
2 29/2 3/2 17 4 1
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
3
|
||||
4 0 4 4 0 13 0 17 4
|
||||
4 0 3 5 0 12 0 17 3
|
||||
4 0 2 6 0 11 0 17 2
|
||||
0
|
||||
|
||||
16
|
||||
21
|
||||
7
|
||||
|
||||
0 2
|
||||
0 3
|
||||
0 4
|
||||
5/2 3/2
|
||||
3 1
|
||||
15/4 3/4
|
||||
5 0
|
||||
6 0
|
||||
11 0
|
||||
12 0
|
||||
53/4 3/4
|
||||
14 1
|
||||
29/2 3/2
|
||||
17 2
|
||||
17 3
|
||||
17 4
|
||||
|
||||
2 0 2 3 1 1
|
||||
2 0 3 5/2 3/2 1
|
||||
2 0 4 5/2 3/2 1
|
||||
2 5/2 3/2 3 1 1
|
||||
2 5/2 3/2 15/4 3/4 1
|
||||
3 3 1 4 0 5 0 1
|
||||
2 3 1 15/4 3/4 1
|
||||
2 15/4 3/4 5 0 1
|
||||
2 15/4 3/4 6 0 1
|
||||
2 5 0 6 0 2
|
||||
2 6 0 11 0 3
|
||||
2 11 0 12 0 2
|
||||
2 11 0 53/4 3/4 1
|
||||
3 12 0 13 0 14 1 1
|
||||
2 12 0 53/4 3/4 1
|
||||
2 53/4 3/4 14 1 1
|
||||
2 53/4 3/4 29/2 3/2 1
|
||||
2 14 1 17 2 1
|
||||
2 14 1 29/2 3/2 1
|
||||
2 29/2 3/2 17 3 1
|
||||
2 29/2 3/2 17 4 1
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
6
|
||||
1 3 4 0
|
||||
4 0 5 0
|
||||
5 0 7 2
|
||||
0 0 9 0
|
||||
3 0 6 0
|
||||
2 0 8 0
|
||||
|
||||
0
|
||||
|
||||
10
|
||||
9
|
||||
1
|
||||
|
||||
0 0
|
||||
1 3
|
||||
2 0
|
||||
3 0
|
||||
4 0
|
||||
5 0
|
||||
6 0
|
||||
7 2
|
||||
8 0
|
||||
9 0
|
||||
|
||||
0 0 2 0 1
|
||||
1 3 4 0 1
|
||||
2 0 3 0 2
|
||||
3 0 4 0 3
|
||||
4 0 5 0 4
|
||||
5 0 6 0 3
|
||||
5 0 7 2 1
|
||||
6 0 8 0 2
|
||||
8 0 9 0 1
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
5
|
||||
1 3 4 0
|
||||
4 0 5 0
|
||||
0 0 9 0
|
||||
3 0 6 0
|
||||
2 0 8 0
|
||||
|
||||
0
|
||||
|
||||
9
|
||||
8
|
||||
1
|
||||
|
||||
0 0
|
||||
1 3
|
||||
2 0
|
||||
3 0
|
||||
4 0
|
||||
5 0
|
||||
6 0
|
||||
8 0
|
||||
9 0
|
||||
|
||||
0 0 2 0 1
|
||||
1 3 4 0 1
|
||||
2 0 3 0 2
|
||||
3 0 4 0 3
|
||||
4 0 5 0 4
|
||||
5 0 6 0 3
|
||||
6 0 8 0 2
|
||||
8 0 9 0 1
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
6
|
||||
1 3 4 0
|
||||
4 0 5 0
|
||||
0 0 9 0
|
||||
3 0 6 0
|
||||
7 1 8 0
|
||||
2 0 8 0
|
||||
|
||||
0
|
||||
|
||||
10
|
||||
9
|
||||
1
|
||||
|
||||
0 0
|
||||
1 3
|
||||
2 0
|
||||
3 0
|
||||
4 0
|
||||
5 0
|
||||
6 0
|
||||
7 1
|
||||
8 0
|
||||
9 0
|
||||
|
||||
0 0 2 0 1
|
||||
1 3 4 0 1
|
||||
2 0 3 0 2
|
||||
3 0 4 0 3
|
||||
4 0 5 0 4
|
||||
5 0 6 0 3
|
||||
6 0 8 0 2
|
||||
7 1 8 0 1
|
||||
8 0 9 0 1
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
4
|
||||
0 0 4 0
|
||||
1 0 3 0
|
||||
2 0 5 0
|
||||
2 0 3 0
|
||||
|
||||
0
|
||||
|
||||
6
|
||||
5
|
||||
1
|
||||
|
||||
0 0
|
||||
1 0
|
||||
2 0
|
||||
3 0
|
||||
4 0
|
||||
5 0
|
||||
|
||||
0 0 1 0 1
|
||||
1 0 2 0 2
|
||||
2 0 3 0 4
|
||||
3 0 4 0 2
|
||||
4 0 5 0 1
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
./data/test_construction/polylines/test01.txt
|
||||
./data/test_construction/polylines/test02.txt
|
||||
./data/test_construction/polylines/test03.txt
|
||||
./data/test_construction/polylines/test04.txt
|
||||
./data/test_construction/polylines/test05.txt
|
||||
./data/test_construction/polylines/test06.txt
|
||||
./data/test_construction/polylines/test07.txt
|
||||
./data/test_construction/polylines/test08.txt
|
||||
./data/test_construction/polylines/test09.txt
|
||||
|
|
@ -45,3 +45,6 @@
|
|||
./data/test_construction/segments/test45.txt
|
||||
./data/test_construction/segments/test46.txt
|
||||
./data/test_construction/segments/test47.txt
|
||||
./data/test_construction/segments/test48.txt
|
||||
./data/test_construction/segments/test49.txt
|
||||
./data/test_construction/segments/test50.txt
|
||||
|
|
|
|||
|
|
@ -31,10 +31,13 @@
|
|||
*/
|
||||
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
#include <CGAL/Object.h>
|
||||
#include <CGAL/Basic_sweep_line_2.h>
|
||||
#include <CGAL/Sweep_line_2/Sweep_line_curve_pair.h>
|
||||
#include <CGAL/Arrangement_2/Open_hash.h>
|
||||
#include <CGAL/algorithm.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
|
|
@ -155,6 +158,7 @@ public:
|
|||
virtual ~Sweep_line_2() {}
|
||||
|
||||
protected:
|
||||
typedef typename std::vector<Subcurve*> Subcurve_vector;
|
||||
|
||||
/*! Initialize the data structures for the sweep-line algorithm. */
|
||||
virtual void _init_structures();
|
||||
|
|
@ -171,22 +175,28 @@ protected:
|
|||
/*! Add a subcurve to the right of an event point.
|
||||
* \param event The event point.
|
||||
* \param curve The subcurve to add.
|
||||
* \return (true) if an overlap occured; (false) otherwise.
|
||||
*/
|
||||
virtual bool _add_curve_to_right(Event* event, Subcurve* curve,
|
||||
bool overlap_exist = false);
|
||||
virtual bool _add_curve_to_right(Event* event, Subcurve* curve);
|
||||
|
||||
/*! Fix overlapping subcurves before handling the current event. */
|
||||
void _fix_overlap_subcurves();
|
||||
|
||||
/*! Handle overlap at right insertion to event.
|
||||
* \param event The event point.
|
||||
* \param curve The subcurve representing the overlap.
|
||||
* \param iter An iterator for the curves.
|
||||
* \param overlap_exist
|
||||
/*! create an overlap subcurve from overlap_cv between c1 and c2.
|
||||
* \param overlap_cv the overlapping curve.
|
||||
* \param c1 first subcurve contributing to the overlap.
|
||||
* \param c2 second subcurve contributing to the overlap.
|
||||
* \param all_leaves_diff not empty in case c1 and c2 have common ancesters.
|
||||
* It contains the set of curves not contained in first_parent
|
||||
* that are in the other subcurve
|
||||
* \param first_parent only used when c1 and c2 have common ancesters.
|
||||
* It is either c1 or c2 (the one having the more leaves)
|
||||
*
|
||||
*/
|
||||
void _handle_overlap(Event* event, Subcurve* curve,
|
||||
Event_subcurve_iterator iter, bool overlap_exist);
|
||||
void _create_overlapping_curve(const X_monotone_curve_2& overlap_cv,
|
||||
Subcurve*& c1 , Subcurve*& c2,
|
||||
const Subcurve_vector& all_leaves_diff,
|
||||
Subcurve* first_parent,
|
||||
Event* event_on_overlap);
|
||||
|
||||
/*! Compute intersections between the two given curves.
|
||||
* If the two curves intersect, create a new event (or use the event that
|
||||
|
|
@ -195,7 +205,7 @@ protected:
|
|||
* \param curve1 The first curve.
|
||||
* \param curve2 The second curve.
|
||||
*/
|
||||
void _intersect(Subcurve* c1, Subcurve* c2);
|
||||
void _intersect(Subcurve* c1, Subcurve* c2, Event* event_for_overlap = NULL);
|
||||
|
||||
/*! When a curve is removed from the status line for good, its top and
|
||||
* bottom neighbors become neighbors. This method finds these cases and
|
||||
|
|
@ -211,13 +221,11 @@ protected:
|
|||
* \param mult Its multiplicity.
|
||||
* \param curve1 The first curve.
|
||||
* \param curve2 The second curve.
|
||||
* \param is_overlap Whether the two curves overlap at xp.
|
||||
*/
|
||||
void _create_intersection_point(const Point_2& xp,
|
||||
unsigned int mult,
|
||||
Subcurve*& c1,
|
||||
Subcurve*& c2,
|
||||
bool is_overlap = false);
|
||||
Subcurve*& c2);
|
||||
|
||||
/*! Fix a subcurve that represents an overlap.
|
||||
* \param sc The subcurve.
|
||||
|
|
|
|||
|
|
@ -553,7 +553,9 @@ add_subcurve(const X_monotone_curve_2& cv, Subcurve* sc)
|
|||
// In case the event has no more right subcurves associated with it, we can
|
||||
// deallocate it. Note that we inform the helper class before deallocating
|
||||
// the event.
|
||||
if (last_event->dec_right_curves_counter() == 0) {
|
||||
if (((Event*) sc->right_event())==this->current_event() &&
|
||||
last_event->dec_right_curves_counter() == 0)
|
||||
{
|
||||
m_helper.before_deallocate_event(last_event);
|
||||
this->deallocate_event(last_event);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -108,7 +108,8 @@ public:
|
|||
OutputIterator oi)
|
||||
{
|
||||
if(cv1.halfedge_handle() != invalid_he &&
|
||||
cv2.halfedge_handle() != invalid_he)
|
||||
cv2.halfedge_handle() != invalid_he &&
|
||||
cv1.halfedge_handle()!=cv2.halfedge_handle())
|
||||
{
|
||||
// The curves are interior-disjoint as both of them are already in
|
||||
// the arrangement.
|
||||
|
|
|
|||
|
|
@ -466,6 +466,7 @@ void Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_sort_left_curves()
|
|||
Subcurve* curve = *(m_currentEvent->left_curves_begin());
|
||||
Status_line_iterator sl_iter = curve->hint();
|
||||
|
||||
CGAL_assertion(sl_iter != m_statusLine.end());
|
||||
CGAL_assertion(*sl_iter == curve);
|
||||
// Look for the first curve in the vertical ordering that is also in the
|
||||
// left curve of the event
|
||||
|
|
@ -559,7 +560,7 @@ void Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_handle_right_curves()
|
|||
template <typename Tr, typename Vis, typename Subcv, typename Evnt,
|
||||
typename Alloc>
|
||||
bool Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::
|
||||
_add_curve_to_right(Event* event, Subcurve* curve, bool /* overlap_exist */)
|
||||
_add_curve_to_right(Event* event, Subcurve* curve)
|
||||
{
|
||||
#if defined(CGAL_NO_ASSERTIONS)
|
||||
(void) event->add_curve_to_right(curve, m_traits);
|
||||
|
|
@ -592,6 +593,7 @@ _remove_curve_from_status_line(Subcurve* sc)
|
|||
// The position of the next event can be right after the deleted subcurve.
|
||||
m_status_line_insert_hint = sl_iter;
|
||||
++m_status_line_insert_hint;
|
||||
sc->set_hint(m_statusLine.end());
|
||||
|
||||
// Erase the subcurve from the status line.
|
||||
CGAL_SL_PRINT_ERASE(*sl_iter);
|
||||
|
|
|
|||
|
|
@ -96,12 +96,16 @@ void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_handle_left_curves()
|
|||
CGAL_SL_PRINT_EOL();
|
||||
this->_handle_event_without_left_curves();
|
||||
|
||||
Status_line_iterator sl_pos = this->m_status_line_insert_hint;
|
||||
// Status_line_iterator sl_pos = this->m_status_line_insert_hint;
|
||||
|
||||
if (this->m_is_event_on_above) {
|
||||
CGAL_SL_PRINT_TEXT("The event is on a curve in the status line");
|
||||
CGAL_SL_PRINT_EOL();
|
||||
|
||||
|
||||
// Obtain the subcurve that contains the current event
|
||||
Subcurve* sc = static_cast<Subcurve*>(*(this->m_status_line_insert_hint));
|
||||
|
||||
// The current event point starts at the interior of a subcurve that
|
||||
// already exists in the status line (this may also indicate an overlap).
|
||||
if (! this->m_currentEvent->has_right_curves()) {
|
||||
|
|
@ -117,37 +121,26 @@ void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_handle_left_curves()
|
|||
// intersection.
|
||||
CGAL_assertion(this->m_currentEvent->is_action());
|
||||
this->m_currentEvent->set_weak_intersection();
|
||||
}
|
||||
|
||||
// Obtain the subcurve that contains the current event, and add it to
|
||||
// the left curves incident to the event.
|
||||
Subcurve* sc = static_cast<Subcurve*>(*(this->m_status_line_insert_hint));
|
||||
const X_monotone_curve_2& last_curve = sc->last_curve();
|
||||
|
||||
this->m_currentEvent->set_weak_intersection();
|
||||
this->m_visitor->update_event(this->m_currentEvent, sc);
|
||||
|
||||
this->m_currentEvent->add_curve_to_left(sc);
|
||||
|
||||
// If necessary, add the subcurves as a right incident curve as well.
|
||||
// We also check for overlaps.
|
||||
bool is_overlap = _add_curve_to_right(this->m_currentEvent, sc);
|
||||
|
||||
this->m_traits->split_2_object()(last_curve,
|
||||
this->m_currentEvent->point(),
|
||||
sub_cv1, sub_cv2);
|
||||
|
||||
++(this->m_status_line_insert_hint);
|
||||
|
||||
if (is_overlap) {
|
||||
// Handle overlaps.
|
||||
this->m_visitor->before_handle_event(this->m_currentEvent);
|
||||
this->m_visitor->add_subcurve(sub_cv1, sc);
|
||||
CGAL_SL_PRINT_ERASE(*sl_pos);
|
||||
this->m_statusLine.erase(sl_pos);
|
||||
CGAL_SL_PRINT_END_EOL("handling left curves");
|
||||
return;
|
||||
this->m_currentEvent->push_back_curve_to_right(sc);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->m_currentEvent->push_back_curve_to_left(sc);
|
||||
this->m_currentEvent->set_weak_intersection();
|
||||
this->m_visitor->update_event(this->m_currentEvent, sc);
|
||||
_add_curve_to_right(this->m_currentEvent, sc);
|
||||
}
|
||||
|
||||
// sc is now on the left
|
||||
CGAL_SL_PRINT_TEXT("Event after update:");
|
||||
CGAL_SL_PRINT_EOL();
|
||||
CGAL_SL_PRINT_EVENT_INFO(this->m_currentEvent);
|
||||
CGAL_SL_PRINT_EOL();
|
||||
CGAL_assertion(std::distance(this->m_currentEvent->left_curves_begin(),
|
||||
this->m_currentEvent->left_curves_end())==1);
|
||||
}
|
||||
else {
|
||||
// The event is not located on any subcurve.
|
||||
|
|
@ -189,7 +182,6 @@ void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_handle_left_curves()
|
|||
else {
|
||||
// curren event splits the subcurve.
|
||||
const X_monotone_curve_2& lastCurve = leftCurve->last_curve();
|
||||
|
||||
this->m_traits->split_2_object()(lastCurve, this->m_currentEvent->point(),
|
||||
sub_cv1, sub_cv2);
|
||||
this->m_visitor->add_subcurve(sub_cv1, leftCurve);
|
||||
|
|
@ -222,6 +214,34 @@ void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_handle_right_curves()
|
|||
return;
|
||||
}
|
||||
|
||||
// Some overlapping curves that are on the right might not be
|
||||
// on the left (in case of overlap with other curves having common
|
||||
// ancesters). Consequently, an overlapping curve on the right might
|
||||
// not have been split.
|
||||
// SL_SAYS: we should be able to do something better without geometric test
|
||||
// (like having an additional boolean in subcurve that we can set in
|
||||
// _handle_left_curves() after a split)
|
||||
for( Event_subcurve_iterator cit = this->m_currentEvent->right_curves_begin(),
|
||||
cit_end = this->m_currentEvent->right_curves_end();
|
||||
cit!=cit_end; ++cit)
|
||||
{
|
||||
if ( (*cit)->originating_subcurve1()!=NULL &&
|
||||
(Event*)(*cit)->left_event()!=this->m_currentEvent )
|
||||
{
|
||||
// split the subcurve.
|
||||
const X_monotone_curve_2& lastCurve = (*cit)->last_curve();
|
||||
|
||||
if (!this->m_traits->equal_2_object()(
|
||||
this->m_traits->construct_min_vertex_2_object()(lastCurve),
|
||||
this->m_currentEvent->point()))
|
||||
{
|
||||
this->m_traits->split_2_object()(lastCurve, this->m_currentEvent->point(),
|
||||
sub_cv1, sub_cv2);
|
||||
(*cit)->set_last_curve(sub_cv2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Loop over the curves to the right of the status line and handle them:
|
||||
// - If we are at the beginning of the curve, we insert it to the status
|
||||
// line, then we look if it intersects any of its neighbors.
|
||||
|
|
@ -290,7 +310,7 @@ void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_handle_right_curves()
|
|||
template <typename Tr, typename Vis, typename Subcv, typename Evnt,
|
||||
typename Alloc>
|
||||
bool Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::
|
||||
_add_curve_to_right(Event* event, Subcurve* curve, bool overlap_exist)
|
||||
_add_curve_to_right(Event* event, Subcurve* curve)
|
||||
{
|
||||
CGAL_SL_PRINT_START("adding a Curve to the right of (");
|
||||
CGAL_SL_DEBUG(this->PrintEvent(event));
|
||||
|
|
@ -304,49 +324,19 @@ _add_curve_to_right(Event* event, Subcurve* curve, bool overlap_exist)
|
|||
{
|
||||
CGAL_SL_PRINT_CURVE(*iter);
|
||||
CGAL_SL_PRINT_EOL();
|
||||
if ((curve == *iter) || (*iter)->is_inner_node(curve)) {
|
||||
if ((*iter)->are_all_leaves_contained(curve)) {
|
||||
CGAL_SL_PRINT_END_EOL("adding a Curve to the right (curve exists)");
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((curve)->is_inner_node(*iter)) {
|
||||
if ((curve)->are_all_leaves_contained(*iter)) {
|
||||
*iter = curve; // replace the current curve with the new one.
|
||||
CGAL_SL_PRINT_END_EOL
|
||||
("adding a Curve to the right (curve partially overlaps)");
|
||||
return false;
|
||||
}
|
||||
|
||||
/*! If the two curves have the exact same leaves, then use the new curve
|
||||
* as a right curve instead of the existing one.
|
||||
* \todo EF, this may not be a sufficient condition. It is possible that
|
||||
* we also need to check whether the event at the right endpoint has a
|
||||
* matching left curve, and only if it has, make the switch. If this is
|
||||
* the case, then other modifications are necessary. I hope it's not.
|
||||
*/
|
||||
if ((curve)->has_same_leaves(*iter)) {
|
||||
*iter = curve; // replace the current curve with the new one.
|
||||
CGAL_SL_PRINT_END_EOL
|
||||
("adding a Curve to the right (curve completely overlaps)");
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((curve)->has_common_leaf(*iter)) {
|
||||
/*! Collect all the distinct nodes of curves including the common nodes.
|
||||
* \todo EF, common nodes should be excluded. It is not incorrect to
|
||||
* include a common node, because in the recursive call it becomes
|
||||
* 'curve', which is an inner node of iter, and it is discarded; see 2
|
||||
* conditions above.
|
||||
*/
|
||||
std::list<Base_subcurve*> list_of_sc;
|
||||
curve->distinct_nodes(*iter, std::back_inserter(list_of_sc));
|
||||
|
||||
typename std::list<Base_subcurve*>::iterator sc_iter;
|
||||
for (sc_iter = list_of_sc.begin(); sc_iter != list_of_sc.end(); ++sc_iter)
|
||||
_add_curve_to_right(event, static_cast<Subcurve*>(*sc_iter));
|
||||
|
||||
CGAL_SL_PRINT_END_EOL("adding a Curve to the right (common leaf)");
|
||||
return true;
|
||||
}
|
||||
CGAL_assertion(!(curve)->has_same_leaves(*iter));
|
||||
}
|
||||
std::pair<bool, Event_subcurve_iterator> pair_res =
|
||||
event->add_curve_to_right(curve, this->m_traits);
|
||||
|
|
@ -357,9 +347,16 @@ _add_curve_to_right(Event* event, Subcurve* curve, bool overlap_exist)
|
|||
return false;
|
||||
}
|
||||
|
||||
_handle_overlap(event, curve, pair_res.second, overlap_exist);
|
||||
// a new overlap needs to be computed
|
||||
_intersect(static_cast<Subcurve*>(curve),
|
||||
static_cast<Subcurve*>(*(pair_res.second)),
|
||||
event);
|
||||
// SL_SAYS: we need to be sure that the overlapping curve generated by
|
||||
// `curve` and `*(pair_res.second)` has not yet been computed or
|
||||
// that the overlapping curve will be added to the right of
|
||||
// `event` because of an adjacency in the status line.
|
||||
|
||||
// Inidicate that an overlap has occured:
|
||||
// Indicate that an overlap has occured:
|
||||
CGAL_SL_PRINT_END_EOL("adding a Curve to the right (overlap)");
|
||||
return true;
|
||||
}
|
||||
|
|
@ -380,6 +377,7 @@ _remove_curve_from_status_line(Subcurve* leftCurve, bool remove_for_good)
|
|||
Status_line_iterator sliter = leftCurve->hint();
|
||||
this->m_status_line_insert_hint = sliter;
|
||||
++(this->m_status_line_insert_hint);
|
||||
leftCurve->set_hint(this->m_statusLine.end());
|
||||
|
||||
if (! remove_for_good) {
|
||||
// the subcurve is not removed for good, so we dont need to intersect
|
||||
|
|
@ -417,7 +415,8 @@ _remove_curve_from_status_line(Subcurve* leftCurve, bool remove_for_good)
|
|||
template <typename Tr, typename Vis, typename Subcv, typename Evnt,
|
||||
typename Alloc>
|
||||
void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_intersect(Subcurve* c1,
|
||||
Subcurve* c2)
|
||||
Subcurve* c2,
|
||||
Event* event_for_overlap)
|
||||
{
|
||||
CGAL_SL_PRINT_START("computing intersection of ");
|
||||
CGAL_SL_PRINT_CURVE(c1);
|
||||
|
|
@ -432,7 +431,10 @@ void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_intersect(Subcurve* c1,
|
|||
// look up for (c1,c2) in the table and insert if doesnt exist
|
||||
Curve_pair cv_pair(c1,c2);
|
||||
if (! (m_curves_pair_set.insert(cv_pair)).second)
|
||||
{
|
||||
CGAL_SL_PRINT_END_EOL("computing intersection (already computed)");
|
||||
return; //the curves have already been checked for intersection
|
||||
}
|
||||
|
||||
float load_factor = static_cast<float>(m_curves_pair_set.size()) /
|
||||
m_curves_pair_set.bucket_count();
|
||||
|
|
@ -440,8 +442,112 @@ void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_intersect(Subcurve* c1,
|
|||
if (load_factor > 6.0f)
|
||||
m_curves_pair_set.resize(m_curves_pair_set.size() * 6);
|
||||
|
||||
// handle overlapping curves with common ancesters
|
||||
Subcurve_vector all_leaves_diff;
|
||||
Subcurve* first_parent=NULL;
|
||||
if (c1->originating_subcurve1()!=NULL || c2->originating_subcurve2()!=NULL)
|
||||
{
|
||||
// get the subcurve leaves of c1 and of c2. Then extract from the smallest set
|
||||
// the subcurves leaves that are not in the other one. If empty, it means that
|
||||
// a subcurves is completely contained in another one.
|
||||
first_parent = c1;
|
||||
Subcurve* second_parent = c2;
|
||||
|
||||
Subcurve_vector all_leaves_first;
|
||||
Subcurve_vector all_leaves_second;
|
||||
first_parent->template all_leaves<Subcurve>(std::back_inserter(all_leaves_first));
|
||||
second_parent->template all_leaves<Subcurve>(std::back_inserter(all_leaves_second));
|
||||
if (all_leaves_second.size() > all_leaves_first.size())
|
||||
{
|
||||
std::swap(first_parent,second_parent);
|
||||
std::swap(all_leaves_first,all_leaves_second);
|
||||
}
|
||||
|
||||
CGAL_assertion(!all_leaves_first.empty() && !all_leaves_second.empty());
|
||||
|
||||
std::sort(all_leaves_first.begin(), all_leaves_first.end());
|
||||
std::sort(all_leaves_second.begin(), all_leaves_second.end());
|
||||
|
||||
std::set_difference(all_leaves_second.begin(), all_leaves_second.end(),
|
||||
all_leaves_first.begin(), all_leaves_first.end(),
|
||||
std::back_inserter(all_leaves_diff));
|
||||
|
||||
if (all_leaves_second.size()==all_leaves_diff.size())
|
||||
all_leaves_diff.clear(); // clear so that it is not used by _create_overlapping_curve()
|
||||
else
|
||||
if (all_leaves_diff.empty())
|
||||
{
|
||||
CGAL_SL_PRINT_TEXT("One overlapping curve entirely contains the other one");
|
||||
CGAL_SL_PRINT_EOL();
|
||||
|
||||
Event* left_event = (Event*) first_parent->left_event();
|
||||
Event* right_event = (Event*) first_parent->right_event();
|
||||
|
||||
if (!second_parent->is_start_point(left_event))
|
||||
left_event->add_curve_to_left(second_parent);
|
||||
else
|
||||
left_event->remove_curve_from_right(second_parent);
|
||||
|
||||
CGAL_SL_PRINT_CURVE(c1);
|
||||
CGAL_SL_PRINT_TEXT(" + ");
|
||||
CGAL_SL_PRINT_CURVE(c2);
|
||||
CGAL_SL_PRINT_TEXT(" => ");
|
||||
CGAL_SL_PRINT_EOL();
|
||||
CGAL_SL_PRINT_TEXT(" ");
|
||||
CGAL_SL_PRINT_CURVE(first_parent);
|
||||
CGAL_SL_PRINT_EOL();
|
||||
|
||||
// Remove second_parent from the left curves of the right end
|
||||
// and add it on the right otherwise
|
||||
if (second_parent->is_end_point(right_event))
|
||||
right_event->remove_curve_from_left(second_parent);
|
||||
else
|
||||
_add_curve_to_right(right_event, second_parent);
|
||||
|
||||
// add the overlapping curve kept of the right of the left end
|
||||
_add_curve_to_right(left_event, first_parent);
|
||||
right_event->add_curve_to_left(first_parent);
|
||||
|
||||
this->m_visitor->found_overlap(c1, c2, first_parent);
|
||||
|
||||
CGAL_SL_PRINT_END_EOL("computing intersection");
|
||||
return;
|
||||
}
|
||||
else{
|
||||
CGAL_SL_PRINT_TEXT("Overlap with common ancestors");
|
||||
CGAL_SL_PRINT_EOL();
|
||||
|
||||
// iteratively create the final overlapping (geometric) curve.
|
||||
// This is needed rather than simply computing the intersection of
|
||||
// the last curves of first_parent and second_parent as some traits
|
||||
// classes (such as Arr_curve_data_traits_2) override the Intersect_2
|
||||
// functor and expects the curve to have no common ancesters
|
||||
// (Arr_curve_data_traits_2 is used in the testsuite to sum up
|
||||
// the overlapping degree of a curve)
|
||||
X_monotone_curve_2 xc = first_parent->last_curve();
|
||||
for (typename Subcurve_vector::iterator sc_it=all_leaves_diff.begin();
|
||||
sc_it!=all_leaves_diff.end(); ++sc_it)
|
||||
{
|
||||
std::vector<CGAL::Object> inter_res;
|
||||
;
|
||||
|
||||
this->m_traits->intersect_2_object()(xc,
|
||||
(*sc_it)->last_curve(),
|
||||
vector_inserter(inter_res));
|
||||
CGAL_assertion(inter_res.size()==1);
|
||||
CGAL_assertion( CGAL::object_cast< X_monotone_curve_2 >(&inter_res.front())!=NULL );
|
||||
xc = *CGAL::object_cast< X_monotone_curve_2 >(&inter_res.front());
|
||||
}
|
||||
_create_overlapping_curve(xc, c1 , c2, all_leaves_diff, first_parent, event_for_overlap);
|
||||
CGAL_SL_PRINT_END_EOL("computing intersection (overlap with common ancestors)");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// do compute the intersection of the two curves
|
||||
vector_inserter vi(m_x_objects) ;
|
||||
vector_inserter vi_end(m_x_objects);
|
||||
|
||||
vi_end =
|
||||
this->m_traits->intersect_2_object()(c1->last_curve(), c2->last_curve(), vi);
|
||||
|
||||
|
|
@ -451,7 +557,7 @@ void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_intersect(Subcurve* c1,
|
|||
}
|
||||
|
||||
// The two subCurves may start at the same point, in that case we ignore the
|
||||
// first intersection point (if we got to that stage, they cannot overlap).
|
||||
// first intersection point.
|
||||
|
||||
const Arr_parameter_space ps_x1 =
|
||||
this->m_traits->parameter_space_in_x_2_object()(c1->last_curve(),
|
||||
|
|
@ -471,7 +577,8 @@ void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_intersect(Subcurve* c1,
|
|||
this->m_traits->is_closed_2_object()(c1->last_curve(), ARR_MIN_END) &&
|
||||
this->m_traits->is_closed_2_object()(c2->last_curve(), ARR_MIN_END))
|
||||
{
|
||||
if (this->m_traits->equal_2_object()
|
||||
if ( object_cast<std::pair<Point_2, Multiplicity> >(&(*vi)) != NULL
|
||||
&& this->m_traits->equal_2_object()
|
||||
(this->m_traits->construct_min_vertex_2_object()(c1->last_curve()),
|
||||
this->m_traits->construct_min_vertex_2_object()(c2->last_curve())))
|
||||
{
|
||||
|
|
@ -554,12 +661,11 @@ void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_intersect(Subcurve* c1,
|
|||
|
||||
for (; vi != vi_end; ++vi) {
|
||||
const X_monotone_curve_2* icv;
|
||||
Point_2 xp;
|
||||
unsigned int multiplicity = 0;
|
||||
|
||||
xp_point = object_cast<std::pair<Point_2, Multiplicity> >(&(*vi));
|
||||
if (xp_point != NULL) {
|
||||
xp = xp_point->first;
|
||||
Point_2 xp = xp_point->first;
|
||||
multiplicity = xp_point->second;
|
||||
CGAL_SL_PRINT_TEXT("Found an intersection point");
|
||||
CGAL_SL_PRINT_EOL();
|
||||
|
|
@ -570,14 +676,7 @@ void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_intersect(Subcurve* c1,
|
|||
CGAL_assertion(icv != NULL);
|
||||
CGAL_SL_PRINT_TEXT("Found an overlap");
|
||||
CGAL_SL_PRINT_EOL();
|
||||
|
||||
// TODO EBEB: This code does not work with overlaps that reach the boundary
|
||||
Point_2 left_xp = this->m_traits->construct_min_vertex_2_object()(*icv);
|
||||
xp = this->m_traits->construct_max_vertex_2_object()(*icv);
|
||||
|
||||
sub_cv1 = *icv;
|
||||
_create_intersection_point(xp, 0 , c1 , c2);
|
||||
_create_intersection_point(left_xp, 0 , c1 ,c2, true);
|
||||
_create_overlapping_curve(*icv, c1 , c2, all_leaves_diff, first_parent, event_for_overlap);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -592,10 +691,9 @@ template <typename Tr, typename Vis, typename Subcv, typename Evnt,
|
|||
void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::
|
||||
_create_intersection_point(const Point_2& xp,
|
||||
unsigned int multiplicity,
|
||||
Subcurve*& c1, Subcurve*& c2,
|
||||
bool is_overlap)
|
||||
Subcurve*& c1, Subcurve*& c2)
|
||||
{
|
||||
CGAL_SL_PRINT_START_EOL("createing an intersection point netween");
|
||||
CGAL_SL_PRINT_START_EOL("creating an intersection point between");
|
||||
CGAL_SL_PRINT_CURVE(c1);
|
||||
CGAL_SL_PRINT_EOL();
|
||||
CGAL_SL_PRINT_CURVE(c2);
|
||||
|
|
@ -607,7 +705,7 @@ _create_intersection_point(const Point_2& xp,
|
|||
|
||||
Event* e = pair_res.first;
|
||||
if (pair_res.second) {
|
||||
// a new event is creatd , which inidicates that the intersection point
|
||||
// a new event is created , which indicates that the intersection point
|
||||
// cannot be one of the end-points of two curves
|
||||
CGAL_SL_PRINT_TEXT("A new event is created .. (");
|
||||
CGAL_SL_PRINT(xp);
|
||||
|
|
@ -623,11 +721,9 @@ _create_intersection_point(const Point_2& xp,
|
|||
// Act according to the multiplicity:
|
||||
if (multiplicity == 0) {
|
||||
// The multiplicity of the intersection point is unkown or undefined:
|
||||
_add_curve_to_right(e, c1, is_overlap);
|
||||
_add_curve_to_right(e, c2, is_overlap);
|
||||
if (! is_overlap) {
|
||||
if (e->is_right_curve_bigger(c1, c2)) std::swap(c1, c2);
|
||||
}
|
||||
_add_curve_to_right(e, c1);
|
||||
_add_curve_to_right(e, c2);
|
||||
if (e->is_right_curve_bigger(c1, c2, this->m_traits)) std::swap(c1, c2);
|
||||
}
|
||||
else {
|
||||
if ((multiplicity % 2) == 1) {
|
||||
|
|
@ -650,42 +746,45 @@ _create_intersection_point(const Point_2& xp,
|
|||
CGAL_SL_PRINT(xp);
|
||||
CGAL_SL_PRINT_TEXT(")");
|
||||
CGAL_SL_PRINT_EOL();
|
||||
if (e == this->m_currentEvent) {
|
||||
// This can happen when c1 starts at the interior of c2 (or vice versa).
|
||||
return;
|
||||
}
|
||||
|
||||
e->add_curve_to_left(c1);
|
||||
e->add_curve_to_left(c2);
|
||||
if (!c1->is_start_point(e)) e->add_curve_to_left(c1);
|
||||
if (!c2->is_start_point(e)) e->add_curve_to_left(c2);
|
||||
|
||||
if (!c1->is_end_point(e) && !c2->is_end_point(e)) {
|
||||
_add_curve_to_right(e, c1, is_overlap);
|
||||
_add_curve_to_right(e, c2, is_overlap);
|
||||
_add_curve_to_right(e, c1);
|
||||
_add_curve_to_right(e, c2);
|
||||
e->set_intersection();
|
||||
this->m_visitor->update_event(e, c1, c2, false);
|
||||
|
||||
if (multiplicity==0)
|
||||
{
|
||||
if (e->is_right_curve_bigger(c1, c2, this->m_traits)) std::swap(c1, c2);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (multiplicity%2==1) std::swap(c1, c2);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!c1->is_end_point(e) && c2->is_end_point(e)) {
|
||||
_add_curve_to_right(e, c1, is_overlap);
|
||||
_add_curve_to_right(e, c1);
|
||||
e->set_weak_intersection();
|
||||
this->m_visitor->update_event(e, c1);
|
||||
}
|
||||
else {
|
||||
if (c1->is_end_point(e) && !c2->is_end_point(e)) {
|
||||
_add_curve_to_right(e, c2, is_overlap);
|
||||
_add_curve_to_right(e, c2);
|
||||
e->set_weak_intersection();
|
||||
this->m_visitor->update_event(e, c2);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (! is_overlap) {
|
||||
if (e->is_right_curve_bigger(c1, c2)) std::swap(c1, c2);
|
||||
}
|
||||
|
||||
|
||||
CGAL_SL_PRINT_EVENT_INFO(e);
|
||||
}
|
||||
|
||||
CGAL_SL_PRINT_END_EOL("Createing an intersection point");
|
||||
CGAL_SL_PRINT_END_EOL("Creating an intersection point");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -701,7 +800,7 @@ void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_fix_overlap_subcurves()
|
|||
|
||||
Event_subcurve_iterator iter = this->m_currentEvent->left_curves_begin();
|
||||
|
||||
//special treatment for Subcuves that store overlaps
|
||||
//special treatment for Subcurves that store overlaps
|
||||
while (iter != this->m_currentEvent->left_curves_end()) {
|
||||
Subcurve* leftCurve = *iter;
|
||||
|
||||
|
|
@ -722,160 +821,174 @@ void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_fix_overlap_subcurves()
|
|||
CGAL_SL_PRINT_END_EOL("Fixing overlap subcurves");
|
||||
}
|
||||
|
||||
/*! Handle overlap at right insertion to event.
|
||||
* \param event the event where that overlap starts (the left end point of the
|
||||
* overlap).
|
||||
* \param curve the subcurve that its insertion to the list of right subcurves of
|
||||
* 'event' causes the overlap (with *iter).
|
||||
* \param iter the existing subcurve at the right subcurves of 'event'
|
||||
* \param overlap_exist a flag indicates if the overlap X_monotone_curve_2 was
|
||||
* computed already (is true than its stored at sub_cv1 data member).
|
||||
*/
|
||||
template <typename Tr, typename Vis, typename Subcv, typename Evnt,
|
||||
typename Alloc>
|
||||
void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::
|
||||
_handle_overlap(Event* event, Subcurve* curve, Event_subcurve_iterator iter,
|
||||
bool overlap_exist)
|
||||
_create_overlapping_curve(const X_monotone_curve_2& overlap_cv,
|
||||
Subcurve*& c1 , Subcurve*& c2,
|
||||
const Subcurve_vector& all_leaves_diff,
|
||||
Subcurve* first_parent,
|
||||
Event* event_on_overlap)
|
||||
{
|
||||
// An overlap occurs:
|
||||
CGAL_SL_PRINT_START_EOL("handling overlap at right insertion");
|
||||
CGAL_SL_PRINT_START_EOL("creating an overlapping curve");
|
||||
|
||||
X_monotone_curve_2 overlap_cv;
|
||||
if (overlap_exist) overlap_cv = sub_cv1;
|
||||
else {
|
||||
// compute the overlap.
|
||||
std::vector<Object> obj_vec;
|
||||
vector_inserter vit(obj_vec);
|
||||
this->m_traits->intersect_2_object()(curve->last_curve(),
|
||||
(*iter)->last_curve(),
|
||||
vit);
|
||||
|
||||
if (obj_vec.empty()) {
|
||||
CGAL_SL_PRINT_END_EOL("handling overlap");
|
||||
return;
|
||||
}
|
||||
|
||||
overlap_cv = object_cast<X_monotone_curve_2>(obj_vec.front());
|
||||
}
|
||||
|
||||
// Get the right end of overlap_cv (if it is closed from the right).
|
||||
Event* right_end;
|
||||
Arr_parameter_space ps_x_r =
|
||||
this->m_traits->parameter_space_in_x_2_object()(overlap_cv, ARR_MAX_END);
|
||||
Arr_parameter_space ps_y_r =
|
||||
this->m_traits->parameter_space_in_y_2_object()(overlap_cv, ARR_MAX_END);
|
||||
|
||||
CGAL_assertion(ps_x_r != ARR_LEFT_BOUNDARY);
|
||||
if ((ps_x_r != ARR_INTERIOR) || (ps_y_r != ARR_INTERIOR)) {
|
||||
// The overlapping subcurve is either open from the right, or
|
||||
// touches the boundary of the surface. In either case, the curves that
|
||||
// are involved in the overlap must also be open or defined at the
|
||||
// boundary, so the event associated with their right ends already exists,
|
||||
// and we set it as the overlapping subcurve's right event.
|
||||
CGAL_assertion((*iter)->right_event() == curve->right_event());
|
||||
right_end = (Event*)(curve->right_event());
|
||||
}
|
||||
else {
|
||||
// The overlapping subcurve has a valid right endpoint.
|
||||
// Find the event associated with this point (or create a new event).
|
||||
Point_2 end_overlap =
|
||||
this->m_traits->construct_max_vertex_2_object()(overlap_cv);
|
||||
|
||||
const std::pair<Event*, bool>& pair_res =
|
||||
this->_push_event(end_overlap, Base_event::OVERLAP, ps_x_r, ps_y_r);
|
||||
|
||||
right_end = pair_res.first;
|
||||
}
|
||||
|
||||
// Get the left end of overlap_cv (if it is closed from the left).
|
||||
// Get the left end of overlap_cv.
|
||||
Event* left_event;
|
||||
Arr_parameter_space ps_x_l =
|
||||
this->m_traits->parameter_space_in_x_2_object()(overlap_cv, ARR_MIN_END);
|
||||
Arr_parameter_space ps_y_l =
|
||||
this->m_traits->parameter_space_in_y_2_object()(overlap_cv, ARR_MIN_END);
|
||||
|
||||
CGAL_assertion(ps_x_l != ARR_RIGHT_BOUNDARY);
|
||||
if ((ps_x_l == ARR_INTERIOR) && (ps_y_l == ARR_INTERIOR)) {
|
||||
// The left end of the overlapping subcurve is regular point, so in case
|
||||
// the event is also associated with a regular point (not incident to the
|
||||
// surface boundaries), we make sure that the overlapping subcurve does
|
||||
// not start to the left of this event.
|
||||
if (! event->is_on_boundary()) {
|
||||
// If the left endpoint of the overlapping curve is to the left of the
|
||||
// event, split the overlapping subcurve so its left endpoint equals
|
||||
// the event point.
|
||||
const Point_2& begin_overlap =
|
||||
this->m_traits->construct_min_vertex_2_object()(overlap_cv);
|
||||
Comparison_result res =
|
||||
this->m_traits->compare_xy_2_object()(event->point(), begin_overlap);
|
||||
|
||||
CGAL_assertion(res != SMALLER);
|
||||
if (res == LARGER) {
|
||||
this->m_traits->split_2_object()(overlap_cv, event->point(),
|
||||
sub_cv1, sub_cv2);
|
||||
overlap_cv = sub_cv2;
|
||||
}
|
||||
}
|
||||
if ((ps_x_l != ARR_INTERIOR) || (ps_y_l != ARR_INTERIOR)) {
|
||||
CGAL_assertion(c1->left_event() == c2->left_event());
|
||||
left_event=(Event*)(c1->left_event());
|
||||
}
|
||||
else{
|
||||
// The left end of the overlapping subcurve is either open, or
|
||||
// incident to the surface boundaries. In case the current event is
|
||||
// associated with a regular point, it must lie to the right of this
|
||||
// curve-end, so we clip the overlapping subcurve accordingly.
|
||||
if (! event->is_on_boundary()) {
|
||||
this->m_traits->split_2_object()(overlap_cv, event->point(),
|
||||
sub_cv1, sub_cv2);
|
||||
overlap_cv = sub_cv2;
|
||||
Point_2 left_end = this->m_traits->construct_min_vertex_2_object()(overlap_cv);
|
||||
left_event = this->_push_event(left_end, Base_event::DEFAULT, ARR_INTERIOR, ARR_INTERIOR).first;
|
||||
}
|
||||
|
||||
// Get the right end of overlap_cv.
|
||||
Event* right_event;
|
||||
Arr_parameter_space ps_x_r =
|
||||
this->m_traits->parameter_space_in_x_2_object()(overlap_cv, ARR_MAX_END);
|
||||
Arr_parameter_space ps_y_r =
|
||||
this->m_traits->parameter_space_in_y_2_object()(overlap_cv, ARR_MAX_END);
|
||||
if ((ps_x_r != ARR_INTERIOR) || (ps_y_r != ARR_INTERIOR)) {
|
||||
CGAL_assertion(c1->right_event() == c2->right_event());
|
||||
right_event = (Event*)(c1->right_event());
|
||||
}
|
||||
else {
|
||||
Point_2 right_end = this->m_traits->construct_max_vertex_2_object()(overlap_cv);
|
||||
right_event = this->_push_event(right_end, Base_event::DEFAULT, ARR_INTERIOR, ARR_INTERIOR).first;
|
||||
}
|
||||
|
||||
if (!c1->is_start_point(left_event))
|
||||
{
|
||||
// here we do not add a curve on the left if there wasn't a curve before
|
||||
// it might happen that a curve will be added on the left while
|
||||
// it should have been an overlapping curve (that will be detected
|
||||
// upon handling of an event with no left curve).
|
||||
// See for example data/test_construction/segments/test51.txt
|
||||
if (!c2->is_start_point(left_event) || left_event->has_left_curves())
|
||||
left_event->add_curve_to_left(c1);
|
||||
}
|
||||
else
|
||||
left_event->remove_curve_from_right(c1);
|
||||
if (!c2->is_start_point(left_event))
|
||||
{
|
||||
// same reason than just above
|
||||
if (!c1->is_start_point(left_event) || left_event->has_left_curves())
|
||||
left_event->add_curve_to_left(c2);
|
||||
}
|
||||
else
|
||||
left_event->remove_curve_from_right(c2);
|
||||
|
||||
// Allocate the new Subcurve for the overlap
|
||||
Subcurve* overlap_sc=NULL;
|
||||
if (all_leaves_diff.empty())
|
||||
{
|
||||
// first check that an equivalent curve is not already in left_event
|
||||
for (Subcurve_iterator iter = left_event->right_curves_begin(); iter != left_event->right_curves_end();
|
||||
++iter)
|
||||
{
|
||||
if ( (*iter)->has_same_leaves(c1, c2) )
|
||||
{
|
||||
CGAL_SL_PRINT_TEXT("Reuse overlapping curve ");
|
||||
CGAL_SL_PRINT_CURVE(*iter);
|
||||
CGAL_SL_PRINT_EOL();
|
||||
overlap_sc=*iter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Alocate a new Subcure for the overlap
|
||||
Subcurve* overlap_sc = this->m_subCurveAlloc.allocate(1);
|
||||
if (overlap_sc==NULL)
|
||||
{
|
||||
CGAL_SL_PRINT_TEXT("Allocate a new subcurve for the overlap (no common subcurves)");
|
||||
CGAL_SL_PRINT_EOL();
|
||||
// no duplicate only one curve is needed
|
||||
overlap_sc = this->m_subCurveAlloc.allocate(1);
|
||||
this->m_subCurveAlloc.construct(overlap_sc, this->m_masterSubcurve);
|
||||
overlap_sc->set_hint(this->m_statusLine.end());
|
||||
overlap_sc->init(overlap_cv);
|
||||
overlap_sc->set_left_event(event);
|
||||
overlap_sc->set_right_event(right_end);
|
||||
overlap_sc->set_left_event(left_event);
|
||||
overlap_sc->set_right_event(right_event);
|
||||
m_overlap_subCurves.push_back(overlap_sc);
|
||||
|
||||
// Set the two events' attribute to overlap.
|
||||
event->set_overlap();
|
||||
//right_end->set_overlap();
|
||||
|
||||
// sets the two originating subcurves of overlap_sc
|
||||
overlap_sc->set_originating_subcurve1(*iter);
|
||||
overlap_sc->set_originating_subcurve2(curve);
|
||||
overlap_sc->set_originating_subcurve1(c1);
|
||||
overlap_sc->set_originating_subcurve2(c2);
|
||||
}
|
||||
}
|
||||
else{
|
||||
CGAL_SL_PRINT_TEXT("Allocate new subcurves for the overlap (common subcurves)");
|
||||
CGAL_SL_PRINT_EOL();
|
||||
|
||||
CGAL_SL_PRINT_CURVE(curve);
|
||||
// create an overlapping curve per subcurve in second_parent that is not in first_parent
|
||||
for (typename std::vector<Subcurve*>::const_iterator sc_it=all_leaves_diff.begin();
|
||||
sc_it!=all_leaves_diff.end();
|
||||
++sc_it)
|
||||
{
|
||||
overlap_sc = this->m_subCurveAlloc.allocate(1);
|
||||
this->m_subCurveAlloc.construct(overlap_sc, this->m_masterSubcurve);
|
||||
overlap_sc->set_hint(this->m_statusLine.end());
|
||||
overlap_sc->init(overlap_cv);
|
||||
overlap_sc->set_left_event(left_event);
|
||||
overlap_sc->set_right_event(right_event);
|
||||
m_overlap_subCurves.push_back(overlap_sc);
|
||||
// sets the two originating subcurves of overlap_sc
|
||||
overlap_sc->set_originating_subcurve1(first_parent);
|
||||
overlap_sc->set_originating_subcurve2(*sc_it);
|
||||
first_parent=overlap_sc;
|
||||
}
|
||||
}
|
||||
left_event->set_overlap();
|
||||
|
||||
CGAL_SL_PRINT_CURVE(c1);
|
||||
CGAL_SL_PRINT_TEXT(" + ");
|
||||
CGAL_SL_PRINT_CURVE(*iter);
|
||||
CGAL_SL_PRINT_CURVE(c2);
|
||||
CGAL_SL_PRINT_TEXT(" => ");
|
||||
CGAL_SL_PRINT_EOL();
|
||||
CGAL_SL_PRINT_TEXT(" ");
|
||||
CGAL_SL_PRINT_CURVE(overlap_sc);
|
||||
CGAL_SL_PRINT_EOL();
|
||||
|
||||
// Remove curve, *iter from the left curves of end_overlap event
|
||||
right_end->remove_curve_from_left(curve);
|
||||
right_end->remove_curve_from_left(*iter);
|
||||
// Remove curves from the left curves of the right end
|
||||
// and add them on the right otherwise
|
||||
if (c1->is_end_point(right_event))
|
||||
right_event->remove_curve_from_left(c1);
|
||||
else
|
||||
_add_curve_to_right(right_event, c1);
|
||||
|
||||
// Add overlap_sc to the left curves
|
||||
right_end->add_curve_to_left(overlap_sc);
|
||||
if (c2->is_end_point(right_event))
|
||||
right_event->remove_curve_from_left(c2);
|
||||
else
|
||||
_add_curve_to_right(right_event, c2);
|
||||
|
||||
// If one of the originating subcurves (or both), does not end
|
||||
// at the right end of the overlap, add them to the right subcurves
|
||||
// of the event associated with the right end of the overlap.
|
||||
if ((Event*)curve->right_event() != right_end)
|
||||
_add_curve_to_right(right_end, curve);
|
||||
// add the overlapping curve of the right of the left end
|
||||
_add_curve_to_right(left_event, overlap_sc);
|
||||
right_event->add_curve_to_left(overlap_sc);
|
||||
|
||||
if ((Event*)(*iter)->right_event() != right_end)
|
||||
_add_curve_to_right(right_end, (*iter));
|
||||
this->m_visitor->found_overlap(c1, c2, overlap_sc);
|
||||
|
||||
this->m_visitor->found_overlap(curve, *iter, overlap_sc);
|
||||
if (!c1->is_end_point(right_event) && !c2->is_end_point(right_event))
|
||||
if (right_event->is_right_curve_bigger(c1, c2, this->m_traits))
|
||||
std::swap(c1, c2);
|
||||
|
||||
// Replace current sub-curve (*iter) with the new sub-curve
|
||||
(*iter) = overlap_sc;
|
||||
|
||||
CGAL_SL_PRINT_END_EOL("handling overlap");
|
||||
if (event_on_overlap != NULL && event_on_overlap!=left_event)
|
||||
{
|
||||
// first check that event_on_overlap is in that overlapping curve as it
|
||||
// can be on another overlapping part of the generating curves
|
||||
if ( this->m_queueEventLess(event_on_overlap, left_event) == LARGER &&
|
||||
this->m_queueEventLess(right_event, event_on_overlap) == LARGER )
|
||||
{
|
||||
CGAL_SL_PRINT_TEXT("An overlapping curve starts before the event inducing its creation");
|
||||
CGAL_SL_PRINT_EOL();
|
||||
// an overlapping curve is involved in an intersection
|
||||
_add_curve_to_right(event_on_overlap, overlap_sc);
|
||||
event_on_overlap->add_curve_to_left(overlap_sc);
|
||||
}
|
||||
}
|
||||
CGAL_SL_PRINT_END_EOL("creating an overlapping curve");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -149,6 +149,8 @@ public:
|
|||
//std::cout << "add_curve_to_left, curve: ";
|
||||
//curve->Print();
|
||||
|
||||
bool curve_added = false;
|
||||
std::vector<Subcurve_iterator> left_curves_to_remove;
|
||||
for (iter = m_leftCurves.begin(); iter != m_leftCurves.end(); ++iter) {
|
||||
//std::cout << "add_curve_to_left, iter: ";
|
||||
//(*iter)->Print();
|
||||
|
|
@ -159,15 +161,42 @@ public:
|
|||
return;
|
||||
}
|
||||
|
||||
// Replace the existing curve in case of overlap.
|
||||
// EBEB 2011-10-27: Fixed to detect overlaps correctly
|
||||
if ((curve != *iter) && (curve->has_common_leaf(*iter))) {
|
||||
// Replace the existing curve in case of overlap, only if the set of ancesters
|
||||
// of curve contains the set of ancesters of *iter
|
||||
if (curve->has_common_leaf(*iter))
|
||||
{
|
||||
//std::cout << "add_curve_to_left, curve overlaps" << std::endl;
|
||||
if ( curve->number_of_original_curves() > (*iter)->number_of_original_curves() )
|
||||
{
|
||||
if (curve->are_all_leaves_contained(*iter))
|
||||
{
|
||||
if (curve_added)
|
||||
{
|
||||
left_curves_to_remove.push_back(iter);
|
||||
continue;
|
||||
}
|
||||
|
||||
*iter = curve;
|
||||
curve_added=true;
|
||||
}
|
||||
}
|
||||
else{
|
||||
if ((*iter)->are_all_leaves_contained(curve))
|
||||
{
|
||||
CGAL_assertion(!curve_added);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (typename std::vector<Subcurve_iterator>::iterator itit =
|
||||
left_curves_to_remove.begin(); itit!=left_curves_to_remove.end(); ++itit)
|
||||
{
|
||||
m_leftCurves.erase(*itit);
|
||||
}
|
||||
|
||||
if (curve_added) return;
|
||||
// The curve does not exist - insert it to the container.
|
||||
m_leftCurves.push_back(curve);
|
||||
// std::cout << "add_curve_to_left, pushed back" << std::endl;
|
||||
|
|
@ -179,6 +208,10 @@ public:
|
|||
void push_back_curve_to_left(Subcurve* curve)
|
||||
{ m_leftCurves.push_back(curve); }
|
||||
|
||||
/*! Add a subcurve to the container of right curves (without checks). */
|
||||
void push_back_curve_to_right(Subcurve* curve)
|
||||
{ m_rightCurves.push_back(curve); }
|
||||
|
||||
/*! Add a subcurve to the container of right curves. */
|
||||
std::pair<bool, Subcurve_iterator>
|
||||
add_curve_to_right(Subcurve* curve, const Traits_2* tr)
|
||||
|
|
@ -237,13 +270,25 @@ public:
|
|||
{
|
||||
Subcurve_iterator iter;
|
||||
for (iter = m_leftCurves.begin(); iter!= m_leftCurves.end(); ++iter) {
|
||||
if (curve->has_common_leaf(*iter)) {
|
||||
if (curve == *iter || curve->are_all_leaves_contained(*iter)) {
|
||||
m_leftCurves.erase(iter);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*! Remove a curve from the set of right curves. */
|
||||
void remove_curve_from_right(Subcurve* curve)
|
||||
{
|
||||
Subcurve_iterator iter;
|
||||
for (iter = m_rightCurves.begin(); iter!= m_rightCurves.end(); ++iter) {
|
||||
if (curve == *iter || curve->are_all_leaves_contained(*iter)) {
|
||||
m_rightCurves.erase(iter);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*! Returns an iterator to the first curve to the left of the event. */
|
||||
Subcurve_iterator left_curves_begin() { return (m_leftCurves.begin()); }
|
||||
|
||||
|
|
@ -408,22 +453,33 @@ public:
|
|||
m_leftCurves.erase(left_iter, m_leftCurves.end());
|
||||
}
|
||||
|
||||
bool is_right_curve_bigger(Subcurve* c1, Subcurve* c2)
|
||||
bool is_right_curve_bigger(Subcurve* c1, Subcurve* c2, const Traits_2* tr)
|
||||
{
|
||||
bool found_c1=false, found_c2=false;
|
||||
Subcurve_iterator iter;
|
||||
for (iter = m_rightCurves.begin(); iter != m_rightCurves.end(); ++iter) {
|
||||
if ((*iter == c1) ||
|
||||
(static_cast<Subcurve*>((*iter)->originating_subcurve1()) == c1) ||
|
||||
(static_cast<Subcurve*>((*iter)->originating_subcurve2()) == c1))
|
||||
return false;
|
||||
|
||||
if ((*iter == c2) ||
|
||||
(static_cast<Subcurve*>((*iter)->originating_subcurve1()) == c2) ||
|
||||
(static_cast<Subcurve*>((*iter)->originating_subcurve2()) == c2))
|
||||
if (!found_c1 && ( (*iter == c1) ||
|
||||
(static_cast<Subcurve*>(*iter)->are_all_leaves_contained(c1))))
|
||||
{
|
||||
if (found_c2)
|
||||
return true;
|
||||
else
|
||||
found_c1=true;
|
||||
}
|
||||
|
||||
return true;
|
||||
if (!found_c2 && ( (*iter == c2) ||
|
||||
(static_cast<Subcurve*>(*iter)->are_all_leaves_contained(c2))))
|
||||
{
|
||||
if (found_c1)
|
||||
return false;
|
||||
else
|
||||
found_c2=true;
|
||||
}
|
||||
}
|
||||
CGAL_assertion(!found_c1 || !found_c2);
|
||||
|
||||
return tr->compare_y_at_x_right_2_object()
|
||||
(c1->last_curve(), c2->last_curve(), m_point) == LARGER;
|
||||
}
|
||||
|
||||
/*! Check if the two curves are negihbors to the left of the event. */
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
#include <CGAL/Sweep_line_2/Sweep_line_event.h>
|
||||
#include <CGAL/Multiset.h>
|
||||
#include <CGAL/assertions.h>
|
||||
#include <set>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
|
|
@ -115,6 +116,11 @@ public:
|
|||
/*! Set the last intersecing curve so far. */
|
||||
void set_last_curve(const X_monotone_curve_2& cv) { m_lastCurve = cv; }
|
||||
|
||||
/*! Check if the given event is the matches the left-end event. */
|
||||
template <typename SweepEvent>
|
||||
bool is_start_point(const SweepEvent* event) const
|
||||
{ return (m_left_event == (Event*)event); }
|
||||
|
||||
/*! Check if the given event is the matches the right-end event. */
|
||||
template <typename SweepEvent>
|
||||
bool is_end_point(const SweepEvent* event) const
|
||||
|
|
@ -153,16 +159,16 @@ public:
|
|||
{ m_orig_subcurve2 = orig_subcurve2; }
|
||||
|
||||
/*! Get all the leaf-nodes in the hierarchy of overlapping subcurves. */
|
||||
template <typename OutputIterator>
|
||||
template <typename Subcurve, typename OutputIterator>
|
||||
OutputIterator all_leaves(OutputIterator oi)
|
||||
{
|
||||
if (m_orig_subcurve1 == NULL) {
|
||||
*oi++ = this;
|
||||
*oi++ = static_cast<Subcurve*>(this);
|
||||
return oi;
|
||||
}
|
||||
|
||||
oi = m_orig_subcurve1->all_leaves(oi);
|
||||
oi = m_orig_subcurve2->all_leaves(oi);
|
||||
oi = m_orig_subcurve1->template all_leaves<Subcurve>(oi);
|
||||
oi = m_orig_subcurve2->template all_leaves<Subcurve>(oi);
|
||||
return oi;
|
||||
}
|
||||
|
||||
|
|
@ -182,14 +188,60 @@ public:
|
|||
return (m_orig_subcurve1->is_leaf(s) || m_orig_subcurve2->is_leaf(s));
|
||||
}
|
||||
|
||||
/*! Check if other is entirely contained in the hierarchy of subcurves of this*/
|
||||
bool are_all_leaves_contained(Self* other)
|
||||
{
|
||||
std::set<Self*> leaves_of_this;
|
||||
this->template all_leaves<Self>(std::inserter(leaves_of_this, leaves_of_this.begin()));
|
||||
std::vector<Self*> leaves_of_other;
|
||||
other->template all_leaves<Self>(std::back_inserter(leaves_of_other));
|
||||
if (leaves_of_other.size() > leaves_of_this.size())
|
||||
return false;
|
||||
for (typename std::vector<Self*>::iterator it=leaves_of_other.begin();
|
||||
it!=leaves_of_other.end();
|
||||
++it)
|
||||
{
|
||||
if (leaves_of_this.count(*it)==0)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*! Check if the two hierarchies contain the same leaf nodes. */
|
||||
bool has_same_leaves(Self* s)
|
||||
{
|
||||
std::list<Self*> my_leaves;
|
||||
std::list<Self*> other_leaves;
|
||||
|
||||
this->all_leaves(std::back_inserter(my_leaves));
|
||||
s->all_leaves(std::back_inserter(other_leaves));
|
||||
this->template all_leaves<Self>(std::back_inserter(my_leaves));
|
||||
s->template all_leaves<Self>(std::back_inserter(other_leaves));
|
||||
|
||||
typename std::list<Self*>::iterator iter;
|
||||
for (iter = my_leaves.begin(); iter != my_leaves.end(); ++iter) {
|
||||
if (std::find(other_leaves.begin(), other_leaves.end(), *iter) ==
|
||||
other_leaves.end())
|
||||
return false;
|
||||
}
|
||||
|
||||
for (iter = other_leaves.begin(); iter != other_leaves.end(); ++iter) {
|
||||
if (std::find(my_leaves.begin(), my_leaves.end(), *iter) ==
|
||||
my_leaves.end())
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*! Check if the two hierarchies (s1+s2 considered as an overlapping curve not already created) contain the same leaf nodes. */
|
||||
bool has_same_leaves(Self* s1, Self* s2)
|
||||
{
|
||||
std::list<Self*> my_leaves;
|
||||
std::list<Self*> other_leaves;
|
||||
|
||||
this->template all_leaves<Self>(std::back_inserter(my_leaves));
|
||||
s1->template all_leaves<Self>(std::back_inserter(other_leaves));
|
||||
s2->template all_leaves<Self>(std::back_inserter(other_leaves));
|
||||
|
||||
typename std::list<Self*>::iterator iter;
|
||||
for (iter = my_leaves.begin(); iter != my_leaves.end(); ++iter) {
|
||||
|
|
@ -213,8 +265,8 @@ public:
|
|||
std::list<Self*> my_leaves;
|
||||
std::list<Self*> other_leaves;
|
||||
|
||||
this->all_leaves(std::back_inserter(my_leaves));
|
||||
s->all_leaves(std::back_inserter(other_leaves));
|
||||
this->template all_leaves<Self>(std::back_inserter(my_leaves));
|
||||
s->template all_leaves<Self>(std::back_inserter(other_leaves));
|
||||
|
||||
typename std::list<Self*>::iterator iter;
|
||||
for (iter = my_leaves.begin(); iter != my_leaves.end(); ++iter) {
|
||||
|
|
@ -254,6 +306,15 @@ public:
|
|||
else return (depth2 + 1);
|
||||
}
|
||||
|
||||
/*! Get the number of input curves contributing to the subcurve */
|
||||
unsigned int number_of_original_curves() const
|
||||
{
|
||||
if (m_orig_subcurve1 == NULL) return 1;
|
||||
unsigned int d1 = m_orig_subcurve1->number_of_original_curves();
|
||||
unsigned int d2 = m_orig_subcurve2->number_of_original_curves();
|
||||
return d1+d2;
|
||||
}
|
||||
|
||||
#ifdef CGAL_SL_VERBOSE
|
||||
void Print() const;
|
||||
#endif
|
||||
|
|
@ -266,7 +327,7 @@ public:
|
|||
std::cout << "Curve " << this
|
||||
<< " (" << m_lastCurve << ") "
|
||||
<< " [sc1: " << m_orig_subcurve1
|
||||
<< ", sc2: " << m_orig_subcurve2 << "]";
|
||||
<< ", sc2: " << m_orig_subcurve2 << "]" << " " << number_of_original_curves() ;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue