Update path generators; start a test with long random paths deformed.

This commit is contained in:
Guillaume Damiand 2018-07-06 16:42:23 +02:00
parent 492a2ffb54
commit 30d5118740
3 changed files with 231 additions and 78 deletions

View File

@ -26,21 +26,37 @@
namespace CGAL {
template<typename Path>
void generate_random_path(Path& p, std::size_t length, CGAL::Random& random)
void generate_random_path(Path& p, std::size_t length, CGAL::Random& random,
bool update_isclosed=true)
{
for (unsigned int i=0; i<length; ++i)
{ extend_path_randomly(p, random); }
{ extend_path_randomly(p, random, true, false); }
if (update_isclosed) { p.update_is_closed(); }
}
template<typename Path>
void generate_random_path(Path& p, std::size_t length)
void generate_random_path(Path& p, CGAL::Random& random,
bool update_isclosed=true)
{ generate_random_path(p, random.get_int(0, 10000), random, update_isclosed); }
template<typename Path>
void generate_random_path(Path& p, std::size_t length,
bool update_isclosed=true)
{
CGAL::Random random;
generate_random_path(p, length, random);
generate_random_path(p, length, random, update_isclosed);
}
template<typename Path>
bool initialize_path_random_starting_dart(Path& p, CGAL::Random& random)
void generate_random_path(Path& p, bool update_isclosed=true)
{
CGAL::Random random;
generate_random_path(p, random, update_isclosed);
}
template<typename Path>
bool initialize_path_random_starting_dart(Path& p, CGAL::Random& random,
bool update_isclosed=true)
{
p.clear();
@ -50,29 +66,32 @@ bool initialize_path_random_starting_dart(Path& p, CGAL::Random& random)
++index;
if (index==p.get_map().darts().capacity()) index=0;
}
p.push_back(p.get_map().darts().iterator_to(p.get_map().darts()[index]));
p.push_back(p.get_map().darts().iterator_to(p.get_map().darts()[index]),
update_isclosed);
return true;
}
template<typename Path>
bool initialize_path_random_starting_dart(Path& p)
bool initialize_path_random_starting_dart(Path& p, bool update_isclosed=true)
{
CGAL::Random random;
return initialize_path_random_starting_dart(p, random);
return initialize_path_random_starting_dart(p, random, update_isclosed);
}
template<typename Path>
bool extend_path_randomly(Path& p, CGAL::Random& random, bool allow_half_turn=false)
bool extend_path_randomly(Path& p, CGAL::Random& random,
bool allow_half_turn=true,
bool update_isclosed=true)
{
if (p.is_empty())
{ return initialize_path_random_starting_dart(p, random); }
{ return initialize_path_random_starting_dart(p, random, update_isclosed); }
typename Path::Dart_const_handle pend=p.get_map().opposite(p.back());
if (pend==Path::Map::null_handle)
{
if (!p.get_map().template is_free<1>(p.back()))
{
p.push_back(p.get_map().template beta<1>(p.back()));
p.push_back(p.get_map().template beta<1>(p.back()), update_isclosed);
return true;
}
else { return false; }
@ -82,25 +101,28 @@ bool extend_path_randomly(Path& p, CGAL::Random& random, bool allow_half_turn=fa
it=p.get_map().template darts_of_cell<0>(pend).begin();
unsigned int index=random.get_int
((allow_half_turn?0:1), p.get_map().template darts_of_cell<0>(pend).size());
((allow_half_turn?0:1),
p.get_map().template darts_of_cell<0>(pend).size());
for(unsigned int i=0; i<index; ++i)
{ ++it; }
assert(allow_half_turn || it!=pend);
p.push_back(it);
p.push_back(it, update_isclosed);
return true;
}
template<typename Path>
bool extend_path_randomly(Path& p, bool allow_half_turn=false)
bool extend_path_randomly(Path& p, bool allow_half_turn=false,
bool update_isclosed=true)
{
CGAL::Random random;
extend_path_randomly(p, random, allow_half_turn);
extend_path_randomly(p, random, allow_half_turn, update_isclosed);
}
template<typename Path>
void extend_straight_positive(Path& p, std::size_t nb=1)
void extend_straight_positive(Path& p, std::size_t nb=1,
bool update_isclosed=true)
{
if (p.is_empty() || nb==0)
{ return; }
@ -110,12 +132,14 @@ void extend_straight_positive(Path& p, std::size_t nb=1)
{
d2=p.get_map().template beta<1,2,1>(p.back());
if (d2!=p.get_map().null_dart_handle)
{ p.push_back(d2); }
{ p.push_back(d2, false); }
}
if (update_isclosed) { p.update_is_closed(); }
}
template<typename Path>
void extend_straight_negative(Path& p, std::size_t nb=1)
void extend_straight_negative(Path& p, std::size_t nb=1,
bool update_isclosed=true)
{
if (p.is_empty() || nb==0)
{ return; }
@ -125,13 +149,15 @@ void extend_straight_negative(Path& p, std::size_t nb=1)
{
d2=p.get_map().template beta<2,0,2,0,2>(p.back());
if (d2!=p.get_map().null_dart_handle)
{ p.push_back(d2); }
{ p.push_back(d2, false); }
}
if (update_isclosed) { p.update_is_closed(); }
}
template<typename Path>
void extend_straight_positive_until(Path& p,
typename Path::Dart_const_handle dend)
typename Path::Dart_const_handle dend,
bool update_isclosed=true)
{
if (p.is_empty() || p.back()==dend)
{ return; }
@ -140,14 +166,16 @@ void extend_straight_positive_until(Path& p,
d2=p.get_map().template beta<1,2,1>(p.back());
while(d2!=dend)
{
p.push_back(d2);
p.push_back(d2, false);
d2=p.get_map().template beta<1,2,1>(d2);
}
if (update_isclosed) { p.update_is_closed(); }
}
template<typename Path>
void extend_straight_negative_until(Path& p,
typename Path::Dart_const_handle dend)
typename Path::Dart_const_handle dend,
bool update_isclosed=true)
{
if (p.is_empty() || p.back()==dend)
{ return; }
@ -156,13 +184,15 @@ void extend_straight_negative_until(Path& p,
d2=p.get_map().template beta<2,0,2,0,2>(p.back());
while(d2!=dend)
{
p.push_back(d2);
p.push_back(d2, false);
d2=p.get_map().template beta<2,0,2,0,2>(d2);
}
if (update_isclosed) { p.update_is_closed(); }
}
template<typename Path>
void extend_uturn_positive(Path& p, std::size_t nb=1)
void extend_uturn_positive(Path& p, std::size_t nb=1,
bool update_isclosed=true)
{
if (p.is_empty() || nb==0)
{ return; }
@ -172,11 +202,11 @@ void extend_uturn_positive(Path& p, std::size_t nb=1)
{ d2=p.get_map().template beta<2, 1>(d2); }
if (d2!=p.get_map().null_dart_handle)
{ p.push_back(d2); }
{ p.push_back(d2, update_isclosed); }
}
template<typename Path>
void extend_uturn_negative(Path& p, std::size_t nb=1)
void extend_uturn_negative(Path& p, std::size_t nb=1, bool update_isclosed=true)
{
if (p.is_empty())
{ return; }
@ -186,58 +216,130 @@ void extend_uturn_negative(Path& p, std::size_t nb=1)
{ d2=p.get_map().template beta<0, 2>(d2); }
if (d2!=p.get_map().null_dart_handle)
{ p.push_back(d2); }
{ p.push_back(d2, update_isclosed); }
}
template<typename Path>
void extend_uturn_half_turn(Path& p)
void extend_uturn_half_turn(Path& p, bool update_isclosed=true)
{
if (p.is_empty())
{ return; }
typename Path::Dart_const_handle d2=p.get_map().template beta<2>(p.back());
if (d2!=p.get_map().null_dart_handle)
{ p.push_back(d2); }
{ p.push_back(d2, update_isclosed); }
}
template<typename Path>
void create_braket_positive(Path& p, std::size_t length, CGAL::Random& random)
void create_braket_positive(Path& p, std::size_t length, CGAL::Random& random,
bool update_isclosed=true)
{
if (p.is_empty())
{ initialize_path_random_starting_dart(p, random); }
{ initialize_path_random_starting_dart(p, random, false); }
extend_uturn_positive(p);
for (std::size_t i=0; i<length; ++i)
{ extend_straight_positive(p); }
extend_uturn_positive(p);
extend_uturn_positive(p, 1, false);
extend_straight_positive(p, length, false);
extend_uturn_positive(p, 1, false);
if (update_isclosed) { p.update_is_closed(); }
}
template<typename Path>
void create_braket_positive(Path& p, std::size_t length)
void create_braket_positive(Path& p, std::size_t length,
bool update_isclosed=true)
{
CGAL::Random random;
create_braket_positive(p, length, random);
create_braket_positive(p, length, random, update_isclosed);
}
template<typename Path>
void create_braket_negative(Path& p, std::size_t length, CGAL::Random& random)
void create_braket_negative(Path& p, std::size_t length, CGAL::Random& random,
bool update_isclosed=true)
{
if (p.is_empty())
{ initialize_path_random_starting_dart(p, random); }
{ initialize_path_random_starting_dart(p, random, false); }
extend_uturn_negative(p);
for (std::size_t i=0; i<length; ++i)
{ extend_straight_negative(p); }
extend_uturn_negative(p);
extend_uturn_negative(p, 1, false);
extend_straight_negative(p, length, false);
extend_uturn_negative(p, 1, false);
if (update_isclosed) { p.update_is_closed(); }
}
template<typename Path>
void create_braket_negative(Path& p, std::size_t length)
void create_braket_negative(Path& p, std::size_t length,
bool update_isclosed=true)
{
CGAL::Random random;
create_braket_negative(p, length, random);
create_braket_negative(p, length, random, update_isclosed);
}
template<typename Path>
void push_around_face(Path& p, std::size_t i, bool update_isclosed=true)
{
std::size_t begin=i, end=i;
while (p.get_map().template beta<1>(p.get_prev_dart(begin))==
p.get_ith_dart(begin))
{
begin=p.prev_index(begin);
if (begin==i)
{ return; } // Case of a path that is equal to a face
}
while (p.get_map().template beta<1>(p.get_ith_dart(end))==
p.get_next_dart(end))
{
end=p.next_index(end);
assert(end!=i);
}
Path p2(p.get_map());
typename Path::Dart_const_handle
dh=p.get_map().template beta<0>(p.get_ith_dart(begin));
do
{
p2.push_back(p.get_map().template beta<2>(dh));
dh=p.get_map().template beta<0>(dh);
}
while(dh!=p.get_ith_dart(end));
for (std::size_t i=end+1; i<p.length(); ++i)
{ p2.push_back(p.get_ith_dart(i), false); }
p.cut(begin, false);
for (std::size_t i=0; i<p2.length(); ++i)
{ p.push_back(p2[i], false); }
if (update_isclosed) { p.update_is_closed(); }
}
template<typename Path>
void update_path_randomly(Path& p, std::size_t nb, CGAL::Random& random,
bool update_isclosed=true)
{
for (unsigned int i=0; i<nb; ++i)
{
push_around_face(p, random.get_int(0, p.length()), false);
}
if (update_isclosed) { p.update_is_closed(); }
}
template<typename Path>
void update_path_randomly(Path& p, CGAL::Random& random,
bool update_isclosed=true)
{ update_path_randomly(p, random.get_int(0, 10000), random, update_isclosed); }
template<typename Path>
void update_path_randomly(Path& p, std::size_t nb, bool update_isclosed=true)
{
CGAL::Random random;
update_path_randomly(p, nb, random, update_isclosed);
}
template<typename Path>
void update_path_randomly(Path& p, bool update_isclosed=true)
{
CGAL::Random random;
update_path_randomly(p, random, update_isclosed);
}
} // namespace CGAL
#endif // CGAL_PATH_GENERATORS_H //

View File

@ -150,8 +150,18 @@ public:
{ return m_map; }
void clear()
{ m_path.clear(); }
{
m_path.clear();
m_is_closed=false;
}
void cut(std::size_t n, bool update_isclosed=true)
{
if (n>=length()) return;
m_path.resize(n);
if (update_isclosed) { update_is_closed(); }
}
std::size_t next_index(std::size_t i) const
{ return (is_closed() && i==m_path.size()-1?0:i+1); }
@ -160,14 +170,25 @@ public:
Dart_const_handle get_ith_dart(std::size_t i) const
{
assert(i<=m_path.size());
return m_path[(i==m_path.size()?0:i)];
assert(i<m_path.size());
return m_path[i];
}
Dart_const_handle operator[] (std::size_t i) const
{ return get_ith_dart(i); }
Dart_const_handle get_prev_dart(std::size_t i) const
{
assert(i<=m_path.size());
return m_path[((is_closed() && i==m_path.size())?0:i)];
assert(i<m_path.size());
if (i==0 && !is_closed()) return NULL;
return m_path[prev_index(i)];
}
Dart_const_handle get_next_dart(std::size_t i) const
{
assert(i<m_path.size());
if (i==m_path.size()-1 && !is_closed()) return NULL;
return m_path[next_index(i)];
}
Dart_const_handle back() const
@ -176,15 +197,16 @@ public:
return m_path.back();
}
void push_back(Dart_const_handle dh)
void push_back(Dart_const_handle dh, bool update_isclosed=true)
{
assert(dh!=NULL && dh!=m_map.null_dart_handle);
assert((is_empty() ||
/* This assert is too long...
assert((is_empty() ||
CGAL::template belong_to_same_cell<Map, 0>
(m_map, m_map.other_extremity(back()), dh)));
(m_map, m_map.other_extremity(back()), dh))); */
m_path.push_back(dh);
update_is_closed();
if (update_isclosed) { update_is_closed(); }
}
// @return true iff the path is valid; i.e. a sequence of edges two by
@ -282,7 +304,7 @@ public:
if (!is_closed())
{
for (int i=m_path.size()-1; i>=0; --i)
{ m_path.push_back(=m_map.template beta<2>(get_ith_dart(i))); }
{ m_path.push_back(m_map.template beta<2>(get_ith_dart(i))); }
m_is_closed=true;
}
}
@ -299,8 +321,8 @@ public:
if (!is_closed() && i==length()-1)
{ return 0; }
Dart_const_handle d1=m_path[i];
Dart_const_handle d2=get_ith_dart(i+1); // Work also for the last dart for cycles
Dart_const_handle d1=get_ith_dart(i);
Dart_const_handle d2=get_next_dart(i);
assert(d1!=d2);
std::size_t res=1;
@ -322,8 +344,8 @@ public:
if (!is_closed() && i==length()-1)
{ return 0; }
Dart_const_handle d1=m_map.template beta<2>(m_path[i]);
Dart_const_handle d2=m_map.template beta<2>(get_ith_dart(i+1)); // Work also for the last dart for cycles
Dart_const_handle d1=m_map.template beta<2>(get_ith_dart(i));
Dart_const_handle d2=m_map.template beta<2>(get_next_dart(i));
assert(d1!=d2);
std::size_t res=1;
@ -721,8 +743,8 @@ public:
while(right_push_one_step())
{ res=true;
std::cout<<"RP "; display(); display_pos_and_neg_turns();
std::cout<<std::endl;
/*std::cout<<"RP "; display(); display_pos_and_neg_turns();
std::cout<<std::endl;*/
}
return res;
}
@ -733,28 +755,29 @@ public:
if (!is_closed())
{ return; }
std::cout<<"##########################################"<<std::endl;
/* std::cout<<"##########################################"<<std::endl;
std::cout<<"Init "; display();
std::cout<<std::endl;
display_pos_and_neg_turns();
display_pos_and_neg_turns(); */
bool modified=false;
std::cout<<"RS "; remove_spurs_one_step();
// std::cout<<"RS ";
remove_spurs_one_step();
display();
std::cout<<std::endl;
/* display();
std::cout<<std::endl; */
do
{
modified=bracket_flattening_one_step();
std::cout<<"BF "; display();
std::cout<<std::endl;
/* std::cout<<"BF "; display();
std::cout<<std::endl; */
modified=modified || remove_spurs_one_step();
std::cout<<"RS "; display();
std::cout<<std::endl;
/* std::cout<<"RS "; display();
std::cout<<std::endl; */
}
while(modified);

View File

@ -149,7 +149,7 @@ bool unit_test_canonize(std::vector<CGAL::Path_on_surface<LCC_3_cmap> >& paths,
const char* msg,
bool draw, int testtorun)
{
assert(paths.size()==transformed_paths.size());
// Wrong assert !! assert(paths.size()==transformed_paths.size());
std::vector<const CGAL::Path_on_surface<LCC_3_cmap>*> v;
bool res=true;
@ -388,22 +388,22 @@ bool test_some_random_paths_on_cube(bool draw, int testtorun)
generate_random_bracket(path, 2, 6, 3, random); // Test 17
if (!unit_test(path, FULL_SIMPLIFICATION, 0, "(2^1 1 2^6 1 2^3 ... )",
"2 2 2 1", draw, testtorun))
"2 2", draw, testtorun))
{ res=false; }
generate_random_bracket(path, 3, 8, 4, random); // Test 18
if (!unit_test(path, FULL_SIMPLIFICATION, 0, "(2^2 1 2^8 1 2^4 ... )",
"2 2", draw, testtorun))
"", draw, testtorun))
{ res=false; }
generate_random_bracket(path, 5, 12, 8, random); // Test 19
if (!unit_test(path, FULL_SIMPLIFICATION, 0, "(2^4 1 2^12 1 2^8 ...)",
"2 2 2 2 2 2 2 2 2", draw, testtorun))
"1", draw, testtorun))
{ res=false; }
generate_random_bracket(path, 5, 12, 8, random); // Test 20
if (!unit_test(path, PUSH, 0, "(2^4 1 2^12 1 2^8 ...)",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 0 2 2 2 2 0 2 2 2 2 1 2 1", draw, testtorun))
if (!unit_test(path, FULL_SIMPLIFICATION, 0, "(2^4 1 2^12 1 2^8 ...)",
"2", draw, testtorun))
{ res=false; }
return true;
@ -501,6 +501,34 @@ bool test_double_torus_quad(bool draw, int testtorun)
"canonize paths on double torus gen1",
draw, testtorun))
{ res=false; }
// Test 22 (one random path, deformed randomly)
paths.clear();
transformed_paths.clear();
if (testtorun==-1 || nbtests==testtorun)
{
CGAL::Random random(1); // fix seed
CGAL::Path_on_surface<LCC_3_cmap> p(lcc);
generate_random_path(p, random.get_int(30, 500), random); // random path, length between 30 and 500
p.close();
paths.push_back(p);
update_path_randomly(p, random);
paths.push_back(p);
update_path_randomly(p, random);
paths.push_back(p);
for (int i=0; i<3; ++i)
{
transformed_paths.push_back
(cmt.transform_original_path_into_quad_surface(paths[i]));
}
}
if (!unit_test_canonize(paths, transformed_paths,
"random canonize paths on double torus",
draw, testtorun))
{ res=false; }
return res;
}
///////////////////////////////////////////////////////////////////////////////
bool test_elephant(bool draw, int testtorun) // TODO LATER