Definitely removed the "infinite vertex at position 0" constraint...

... and fixed the regular triangulation at the same time.
Even though this constraint had been dropped, the code was still
expecting the infinite vertex to be at position 0 in the cells.
Now, it's not the case anymore, the infinite vertex can be anywhere.
This is particularly useful for the 2D case, because the constraint made
the orientation of the "rightmost" infinite cell wrong.

(cherry picked from commit 48b8382de3)
This commit is contained in:
Clement Jamin 2015-07-06 19:04:29 +02:00
parent ef9b73ca2e
commit 5531f6f169
6 changed files with 94 additions and 128 deletions

View File

@ -363,24 +363,14 @@ Delaunay_triangulation<DCTraits, TDS>
return Full_cell_handle();
}
Full_cell_handle left = v->full_cell();
if( is_infinite(left) && left->neighbor(0)->index(left) == 0 ) // we are on the infinite right.
left = left->neighbor(0);
if( 0 == left->index(v) )
left = left->neighbor(1);
CGAL_assertion( 1 == left->index(v) );
Full_cell_handle right = left->neighbor(0);
if( ! is_infinite(right) )
{
tds().associate_vertex_with_full_cell(left, 1, right->vertex(1));
set_neighbors(left, 0, right->neighbor(0), right->mirror_index(0));
}
else
{
tds().associate_vertex_with_full_cell(left, 1, left->vertex(0));
tds().associate_vertex_with_full_cell(left, 0, infinite_vertex());
set_neighbors(left, 0, left->neighbor(1), left->mirror_index(1));
set_neighbors(left, 1, right->neighbor(1), right->mirror_index(1));
}
tds().associate_vertex_with_full_cell(left, 1, right->vertex(1));
set_neighbors(left, 0, right->neighbor(0), right->mirror_index(0));
tds().delete_vertex(v);
tds().delete_full_cell(right);
return left;
@ -469,24 +459,16 @@ Delaunay_triangulation<DCTraits, TDS>
{
int v_idx = (*it)->index(v);
tds().associate_vertex_with_full_cell(*it, v_idx, infinite_vertex());
if( v_idx != 0 )
{
// we must put the infinite vertex at index 0.
// OK, now with the new convention that the infinite vertex
// does not have to be at index 0, this is not necessary,
// but still, I prefer to keep this piece of code here. [-- Samuel Hornus]
(*it)->swap_vertices(0, v_idx);
// Now, we preserve the positive orientation of the full_cell
(*it)->swap_vertices(current_dimension() - 1, current_dimension());
}
}
// Make the handles to infinite full cells searchable
infinite_simps.make_searchable();
// Then, modify the neighboring relation
for( typename Simplices::iterator it = simps.begin(); it != simps.end(); ++it )
{
for( int i = 1; i <= current_dimension(); ++i )
for( int i = 0; i <= current_dimension(); ++i )
{
if (is_infinite((*it)->vertex(i)))
continue;
(*it)->vertex(i)->set_full_cell(*it);
Full_cell_handle n = (*it)->neighbor(i);
// Was |n| a finite full cell prior to removing |v| ?
@ -730,6 +712,35 @@ Delaunay_triangulation<DCTraits, TDS>
CGAL_assertion( ZERO != o );
if( NEGATIVE == o )
reorient_full_cells();
// We just inserted the second finite point and the right infinite
// cell is like : (inf_v, v), but we want it to be (v, inf_v) to be
// consistent with the rest of the cells
if (current_dimension() == 1)
{
// Is "inf_v_cell" the right infinite cell?
// Then inf_v_index should be 1
if (inf_v_cell->neighbor(inf_v_index)->index(inf_v_cell) == 0
&& inf_v_index == 0)
{
inf_v_cell->swap_vertices(
current_dimension() - 1, current_dimension());
}
// Otherwise, let's find the right infinite cell
else
{
inf_v_cell = inf_v_cell->neighbor((inf_v_index + 1) % 2);
inf_v_index = inf_v_cell->index(infinite_vertex());
// Is "inf_v_cell" the right infinite cell?
// Then inf_v_index should be 1
if (inf_v_cell->neighbor(inf_v_index)->index(inf_v_cell) == 0
&& inf_v_index == 0)
{
inf_v_cell->swap_vertices(
current_dimension() - 1, current_dimension());
}
}
}
}
return v;
}

View File

@ -241,7 +241,7 @@ public:
Facet ft;
Full_cell_handle c = locate (*p, lt, f, ft, hint);
Vertex_handle v = insert (*p, lt, f, ft, c);
hint = v == Vertex_handle() ? c : v->full_cell();
}
return number_of_vertices() - n;
@ -268,9 +268,7 @@ public:
CGAL_assertion( Vertex_handle() != hint );
return insert(p, hint->full_cell());
}
Vertex_handle insert_outside_convex_hull_1(
const Weighted_point & p, Full_cell_handle s);
Vertex_handle insert_outside_affine_hull(const Weighted_point &);
Vertex_handle insert_in_conflicting_cell(
const Weighted_point &, const Full_cell_handle,
@ -493,24 +491,12 @@ Regular_triangulation<RTTraits, TDS>
return Full_cell_handle();
}
Full_cell_handle left = v->full_cell();
if( is_infinite(left) && left->neighbor(0)->index(left) == 0 ) // we are on the infinite right.
left = left->neighbor(0);
if( 0 == left->index(v) )
left = left->neighbor(1);
CGAL_assertion( 1 == left->index(v) );
Full_cell_handle right = left->neighbor(0);
if( ! is_infinite(right) )
{
tds().associate_vertex_with_full_cell(left, 1, right->vertex(1));
set_neighbors(left, 0, right->neighbor(0), right->mirror_index(0));
}
else
{
tds().associate_vertex_with_full_cell(left, 1, left->vertex(0));
tds().associate_vertex_with_full_cell(left, 0, infinite_vertex());
set_neighbors(left, 0, left->neighbor(1), left->mirror_index(1));
set_neighbors(left, 1, right->neighbor(1), right->mirror_index(1));
}
tds().associate_vertex_with_full_cell(left, 1, right->vertex(1));
set_neighbors(left, 0, right->neighbor(0), right->mirror_index(0));
tds().delete_vertex(v);
tds().delete_full_cell(right);
return left;
@ -603,24 +589,16 @@ Regular_triangulation<RTTraits, TDS>
{
int v_idx = (*it)->index(v);
tds().associate_vertex_with_full_cell(*it, v_idx, infinite_vertex());
if( v_idx != 0 )
{
// we must put the infinite vertex at index 0.
// OK, now with the new convention that the infinite vertex
// does not have to be at index 0, this is not necessary,
// but still, I prefer to keep this piece of code here. [-- Samuel Hornus]
(*it)->swap_vertices(0, v_idx);
// Now, we preserve the positive orientation of the full_cell
(*it)->swap_vertices(current_dimension() - 1, current_dimension());
}
}
// Make the handles to infinite full cells searchable
infinite_simps.make_searchable();
// Then, modify the neighboring relation
for( typename Simplices::iterator it = simps.begin(); it != simps.end(); ++it )
{
for( int i = 1; i <= current_dimension(); ++i )
for( int i = 0 ; i <= current_dimension(); ++i )
{
if (is_infinite((*it)->vertex(i)))
continue;
(*it)->vertex(i)->set_full_cell(*it);
Full_cell_handle n = (*it)->neighbor(i);
// Was |n| a finite full cell prior to removing |v| ?
@ -843,46 +821,7 @@ Regular_triangulation<RTTraits, TDS>
// !NO break here!
}
default:
if( 1 == current_dimension() && Base::OUTSIDE_CONVEX_HULL == lt)
return insert_outside_convex_hull_1(p, s);
else
return insert_in_conflicting_cell(p, s);
break;
}
}
// NOT DOCUMENTED...
template < class RTTraits, class TDS >
typename Regular_triangulation<RTTraits, TDS>::Vertex_handle
Regular_triangulation<RTTraits, TDS>
::insert_outside_convex_hull_1(const Weighted_point & p, Full_cell_handle s)
{
// This is a special case for dimension 1, because in that case, the right
// infinite full_cell is not correctly oriented... (sice its first vertex is the
// infinite one...
bool in_conflict = is_in_conflict(p, s);
// If p is not in conflict with s, then p is hidden
// => we don't insert it
if (!in_conflict)
{
m_hidden_points.push_back(p);
return Vertex_handle();
}
else
{
CGAL_precondition( is_infinite(s) );
CGAL_precondition( 1 == current_dimension() );
int inf_v_index = s->index(infinite_vertex());
bool swap = (0 == s->neighbor(inf_v_index)->index(s));
Vertex_handle v = tds().insert_in_full_cell(s);
v->set_point(p);
if( swap )
{
s->swap_vertices(0, 1);
}
return v;
return insert_in_conflicting_cell(p, s);
}
}
@ -907,6 +846,30 @@ Regular_triangulation<RTTraits, TDS>
CGAL_assertion( ZERO != o );
if( NEGATIVE == o )
reorient_full_cells();
// We just inserted the second finite point and the right infinite
// cell is like : (inf_v, v), but we want it to be (v, inf_v) to be
// consistent with the rest of the cells
if (current_dimension() == 1)
{
// Is "inf_v_cell" the right infinite cell? Then inf_v_index should be 1
if (inf_v_cell->neighbor(inf_v_index)->index(inf_v_cell) == 0
&& inf_v_index == 0)
{
inf_v_cell->swap_vertices(current_dimension() - 1, current_dimension());
}
else
{
inf_v_cell = inf_v_cell->neighbor((inf_v_index + 1) % 2);
inf_v_index = inf_v_cell->index(infinite_vertex());
// Is "inf_v_cell" the right infinite cell? Then inf_v_index should be 1
if (inf_v_cell->neighbor(inf_v_index)->index(inf_v_cell) == 0
&& inf_v_index == 0)
{
inf_v_cell->swap_vertices(current_dimension() - 1, current_dimension());
}
}
}
}
return v;
}
@ -945,18 +908,7 @@ Regular_triangulation<RTTraits, TDS>
// !NO break here!
}
default:
{
if( 1 == current_dimension() && Base::OUTSIDE_CONVEX_HULL == lt)
{
if (s->has_vertex(star_center))
return insert_outside_convex_hull_1(p, s);
}
else
{
return insert_in_conflicting_cell(p, s, star_center);
}
break;
}
return insert_in_conflicting_cell(p, s, star_center);
}
return Vertex_handle();

View File

@ -756,6 +756,21 @@ protected:
}
};
void display_all_full_cells__debugging()
{
std::cerr << "ALL FULL CELLS:" << std::endl;
for (Full_cell_const_iterator cit = full_cells_begin() ;
cit != full_cells_end() ; ++cit )
{
std::cerr << std::hex << &*cit << ": ";
for (int jj = 0 ; jj <= current_dimension() ; ++jj)
std::cerr << (is_infinite(cit->vertex(jj)) ? 0xFFFFFFFF : (unsigned int)&*cit->vertex(jj)) << " - ";
std::cerr << std::dec << std::endl;
}
std::cerr << std::endl;
}
}; // Triangulation<...>
// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
@ -769,17 +784,15 @@ Triangulation<TT, TDS>
{
if( current_dimension() < 1 )
return;
Full_cell_iterator sit = full_cells_begin();
Full_cell_iterator send = full_cells_end();
while( sit != send )
for ( ; sit != send ; ++sit)
{
if( is_infinite(sit) && (1 == current_dimension()) )
if( ! (is_infinite(sit) && (1 == current_dimension())) )
{
++sit;
continue;
sit->swap_vertices(current_dimension() - 1, current_dimension());
}
sit->swap_vertices(current_dimension() - 1, current_dimension());
++sit;
}
}
@ -901,13 +914,8 @@ Triangulation<TT, TDS>
CGAL_precondition( is_infinite(s) );
CGAL_precondition( 1 == current_dimension() );
int inf_v_index = s->index(infinite_vertex());
bool swap = (0 == s->neighbor(inf_v_index)->index(s));
Vertex_handle v = tds().insert_in_full_cell(s);
v->set_point(p);
if( swap )
{
s->swap_vertices(0, 1);
}
return v;
}

View File

@ -888,8 +888,7 @@ Triangulation_data_structure<Dim, Vb, Fcb>
if( v_idx != current_dimension() )
{
(*it)->swap_vertices(v_idx, current_dimension());
if( ( ! (*it)->has_vertex(star) ) || (current_dimension() > 2) )
(*it)->swap_vertices(current_dimension() - 2, current_dimension() - 1);
(*it)->swap_vertices(current_dimension() - 2, current_dimension() - 1);
}
(*it)->set_vertex(current_dimension(), Vertex_handle());
(*it)->set_neighbor(current_dimension(), Full_cell_handle());
@ -1138,11 +1137,6 @@ void Triangulation_data_structure<Dim, Vb, Fcb>
for( int k = 1; k <= cur_dim; ++k )
associate_vertex_with_full_cell(S_new, k, vertex(S, k - 1));
}
else if( cur_dim == 2 )
{ // if cur. dim. is 2, we must take care of the 'rightmost' infinite vertex.
if( S->mirror_index(S->index(star)) == 0 )
swap_me = S;
}
}
// now we setup the neighbors
set_visited(start, false);

View File

@ -117,10 +117,10 @@ int main(int argc, char **argv)
if( argc > 1 )
N = atoi(argv[1]);
//go<5>(N);
//go<4>(N);
//go<3>(N);
go<4>(N);
go<3>(N);
go<2>(N);
//go<1>(N);
go<1>(N);
cerr << endl;
return 0;

View File

@ -123,9 +123,10 @@ int main(int argc, char **argv)
if( argc > 1 )
N = atoi(argv[1]);
//go<5>(N);
//go<4>(N);
go<4>(N);
go<3>(N);
go<2>(N);
go<1>(N);
cerr << endl;
return 0;