Start to work on path with rle, spurs removal.

This commit is contained in:
Guillaume Damiand 2018-11-08 16:42:13 +01:00
parent 4145ddeb0e
commit 919d4714ac
3 changed files with 309 additions and 30 deletions

View File

@ -1080,11 +1080,34 @@ namespace CGAL {
}
// Simplify the path by removing all spurs
// @return true iff at least one spur was removed
bool remove_spurs(Path_on_surface<Map>& path) const
{
/* TODO TEMPO POUR TEST */
Path_on_surface_with_rle<Map> prle(path);
prle.remove_spurs();
/* TODO FIN TEMPO POUR TEST */
bool res=false;
while(remove_spurs_one_step(path))
{ res=true; }
/* TODO TEMPO POUR TEST */
Path_on_surface<Map> p2(prle);
if (p2!=path)
{
std::cout<<"Error: p2!=path: "<<std::endl
<<"p2= "<<p2<<"; "<<std::endl
<<"path="<<path<<"; "<<std::endl
<<"prle="<<prle<<std::endl;
prle.display_pos_and_neg_turns();
}
else
{
std::cout<<"GOOD JOB for path "<<p2<<std::endl;
}
/* TODO FIN TEMPO POUR TEST */
return res;
}
@ -1341,7 +1364,7 @@ namespace CGAL {
bool modified=false;
// std::cout<<"RS ";
remove_spurs_one_step(path);
remove_spurs(path); // TODO BEFORE remove_spurs_one_step(path);
/* display(); display_pos_and_neg_turns();
std::cout<<std::endl; */
@ -1355,7 +1378,8 @@ namespace CGAL {
/* std::cout<<"BF "; display(); display_pos_and_neg_turns();
std::cout<<std::endl; */
modified=modified || remove_spurs_one_step(path);
modified=modified || remove_spurs(path); // TODO BEFORE remove_spurs_one_step(path);
/* std::cout<<"RS "; display(); display_pos_and_neg_turns();
std::cout<<std::endl; */

View File

@ -355,9 +355,7 @@ public:
{
assert(is_valid());
assert(i<m_path.size());
if (!is_closed() && i==length()-1)
{ return 0; }
assert (is_closed() || i<length()-1);
Dart_const_handle d1=get_ith_dart(i);
Dart_const_handle d2=get_next_dart(i);
@ -381,9 +379,7 @@ public:
{
assert(is_valid());
assert(i<m_path.size());
if (!is_closed() && i==length()-1)
{ return 0; }
assert (is_closed() || i<length()-1);
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));
@ -402,7 +398,6 @@ public:
return res;
}
std::vector<std::size_t> compute_positive_turns() const
{
std::vector<std::size_t> res;
@ -410,17 +405,9 @@ public:
std::size_t i;
for (i=0; i<m_path.size()-1; ++i)
{
if (m_path[i]==m_map.template beta<2>(m_path[i+1]))
{ res.push_back(0); }
else { res.push_back(next_positive_turn(i)); }
}
{ res.push_back(next_positive_turn(i)); }
if (is_closed())
{
if (m_path[i]==m_map.template beta<2>(m_path[0]))
{ res.push_back(0); }
else { res.push_back(next_positive_turn(i)); }
}
{ res.push_back(next_positive_turn(i)); }
return res;
}
@ -431,17 +418,9 @@ public:
std::size_t i;
for (i=0; i<m_path.size()-1; ++i)
{
if (m_path[i]==m_map.template beta<2>(m_path[i+1]))
{ res.push_back(0); }
else { res.push_back(next_negative_turn(i)); }
}
{ res.push_back(next_negative_turn(i)); }
if (is_closed())
{
if (m_path[i]==m_map.template beta<2>(m_path[0]))
{ res.push_back(0); }
else { res.push_back(next_negative_turn(i)); }
}
{ res.push_back(next_negative_turn(i)); }
return res;
}

View File

@ -25,6 +25,7 @@
#include <utility>
#include <iostream>
#include <iterator>
#include <vector>
namespace CGAL {
@ -40,6 +41,9 @@ public:
typedef Map_ Map;
typedef typename Map::Dart_handle Dart_handle;
typedef typename Map::Dart_const_handle Dart_const_handle;
typedef std::list<std::pair<Dart_const_handle, int> > List_of_dart_length;
typedef typename List_of_dart_length::iterator List_iterator;
typedef typename List_of_dart_length::const_iterator List_const_iterator;
typedef Path_on_surface_with_rle<Map> Self;
@ -52,6 +56,8 @@ public:
m_is_closed(apath.is_closed()),
m_length(apath.length())
{
if (apath.is_empty()) return;
std::size_t i=0, j=0, starti=0, length=0;
bool positive_flat=false;
bool negative_flat=false;
@ -160,6 +166,276 @@ public:
return true;
}
void advance_iterator(List_iterator& it)
{
assert(it!=m_path.end());
it=std::next(it);
if (is_closed() && it==m_path.end())
{ it=m_path.begin(); } // Here the path is closed, and it is the last element of the list
}
void advance_iterator(List_const_iterator& it) const
{
assert(it!=m_path.end());
it=std::next(it);
if (is_closed() && it==m_path.end())
{ it=m_path.begin(); } // Here the path is closed, and it is the last element of the list
}
void retreat_iterator(List_iterator& it)
{
assert(it!=m_path.end());
assert(it!=m_path.begin() || is_closed());
if (is_closed() && it==m_path.begin())
{ it=m_path.end(); }
it=std::prev(it);
}
void retreat_iterator(List_const_iterator& it) const
{
assert(it!=m_path.end());
assert(it!=m_path.begin() || is_closed());
if (is_closed() && it==m_path.begin())
{ it=m_path.end(); }
it=std::prev(it);
}
List_iterator next_iterator(const List_iterator& it)
{
List_iterator res=it;
advance_iterator(res);
return res;
}
List_const_iterator next_iterator(const List_const_iterator& it) const
{
List_const_iterator res=it;
advance_iterator(res);
return res;
}
List_iterator prev_iterator(const List_iterator& it) const
{
List_iterator res=it;
retreat_iterator(res);
return res;
}
List_const_iterator prev_iterator(const List_const_iterator& it) const
{
List_const_iterator res=it;
retreat_iterator(res);
return res;
}
// @return true iff there is a dart after it
bool next_dart_exist(const List_const_iterator& it) const
{
assert(it!=m_path.end());
return is_closed() || std::next(it)!=m_path.end();
}
// Return true if it is the beginning of a spur.
bool is_spur(const List_const_iterator& it) const
{
assert(it!=m_path.end());
return it->second==0 &&
next_dart_exist(it) &&
m_map.template beta<2>(it->first)==next_iterator(it)->first;
}
// Remove the spur given by it; move it to the element before it
// (m_path.end() if the path becomes empty).
void remove_spur(List_iterator& it)
{
assert(is_spur(it));
it=m_path.erase(it); // Erase the first dart of the spur
if (is_closed() && it==m_path.end())
{ it=m_path.begin(); }
if (it->second==0) // a flat part having only one dart
{
it=m_path.erase(it); // Erase the second dart of the spur
if (is_closed() && it==m_path.end())
{ it=m_path.begin(); }
}
else
{ // Here we need to reduce the length of the flat part
if (it->second>0)
{
--(it->second);
it->first=m_map.template beta<1, 2, 1>(it->first);
}
else
{
++(it->second);
it->first=m_map.template beta<2, 0, 2, 0, 2>(it->first);
}
}
// Now move it to the element before the removed spur
// except if the path has become empty, or if it is not closed
// and we are in its first element.
if (m_path.empty())
{
assert(it==m_path.end());
m_is_closed=false;
}
else if (is_closed() || it!=m_path.begin())
{
retreat_iterator(it); // go to the previous element
// TODO we need to test if the previous flat part should be merged with the next one
if (compute_positive_turns(it, next(it))==2 || compute_negative_turns(it, next(it))==2 )
{
}
}
}
// Move it to the next spur after it. Go to m_path.end() if there is no
// spur in the path.
void move_to_next_spur(List_iterator& it)
{
assert(it!=m_path.end());
List_iterator itend=(is_closed()?it:m_path.end());
do
{
advance_iterator(it);
if (is_spur(it)) { return; }
}
while(it!=itend);
it=m_path.end(); // Here there is no spur in the whole path
}
// Simplify the path by removing all spurs
// @return true iff at least one spur was removed
bool remove_spurs()
{
bool res=false;
List_iterator it=m_path.begin();
while(it!=m_path.end())
{
if (is_spur(it)) { remove_spur(it); res=true; }
else { move_to_next_spur(it); }
}
return res;
}
/// @return the turn between dart it and next dart.
/// (turn is position of the second edge in the cyclic ordering of
/// edges starting from the first edge around the second extremity
/// of the first dart)
std::size_t next_positive_turn(const List_const_iterator& it) const
{
assert(is_valid());
assert(it!=m_path.end());
assert(is_closed() || std::next(it)!=m_path.end());
Dart_const_handle d1=it->first;
if (it->second!=0)
{
if (it->second<0) { return -(it->second); }
else { return it->second; }
}
Dart_const_handle d2=next_iterator(it)->first;
assert(d1!=d2);
if (d2==m_map.template beta<2>(d1))
{ return 0; }
std::size_t res=1;
while (m_map.template beta<1>(d1)!=d2)
{
++res;
d1=m_map.template beta<1, 2>(d1);
}
// std::cout<<"next_positive_turn="<<res<<std::endl;
return res;
}
/// Same than next_positive_turn but turning in reverse orientation around vertex.
std::size_t next_negative_turn(const List_const_iterator& it) const
{
assert(is_valid());
assert(it!=m_path.end());
assert(is_closed() || std::next(it)!=m_path.end());
Dart_const_handle d1=m_map.template beta<2>(it->first);
if (it->second!=0)
{
if (it->second<0) { return -(it->second); }
else { return it->second; }
}
Dart_const_handle d2=m_map.template beta<2>(next_iterator(it)->first);
assert(d1!=d2);
if (d2==m_map.template beta<2>(d1))
{ return 0; }
std::size_t res=1;
while (m_map.template beta<0>(d1)!=d2)
{
++res;
d1=m_map.template beta<0, 2>(d1);
}
// std::cout<<"next_negative_turn="<<res<<std::endl;
return res;
}
std::vector<std::size_t> compute_positive_turns() const
{
std::vector<std::size_t> res;
if (is_empty()) return res;
for (auto it=m_path.begin(), itend=m_path.end(); it!=itend; ++it)
{
if (is_closed() || std::next(it)!=m_path.end())
{ res.push_back(next_positive_turn(it)); }
}
return res;
}
std::vector<std::size_t> compute_negative_turns() const
{
std::vector<std::size_t> res;
if (is_empty()) return res;
for (auto it=m_path.begin(), itend=m_path.end(); it!=itend; ++it)
{
if (is_closed() || std::next(it)!=m_path.end())
{ res.push_back(next_negative_turn(it)); }
}
return res;
}
std::vector<std::size_t> compute_turns(bool positive) const
{ return (positive?compute_positive_turns():compute_negative_turns()); }
void display_positive_turns() const
{
std::cout<<"+(";
std::vector<std::size_t> res=compute_positive_turns();
for (std::size_t i=0; i<res.size(); ++i)
{ std::cout<<res[i]<<(i<res.size()-1?" ":""); }
std::cout<<")";
}
void display_negative_turns() const
{
std::cout<<"-(";
std::vector<std::size_t> res=compute_negative_turns();
for (std::size_t i=0; i<res.size(); ++i)
{ std::cout<<res[i]<<(i<res.size()-1?" ":""); }
std::cout<<")";
}
void display_pos_and_neg_turns() const
{
display_positive_turns();
std::cout<<" ";
display_negative_turns();
}
void display() const
{
for (auto it=m_path.begin(), itend=m_path.end(); it!=itend; ++it)
@ -179,7 +455,7 @@ public:
protected:
const Map& m_map; // The underlying map
std::list<std::pair<Dart_const_handle, int> > m_path; // The sequence of turning darts, plus the length of the flat part after the dart (a flat part is a sequence of dart with positive turn == 2). If negative value k, -k is the length of the flat part, for negative turns (-2).
List_of_dart_length m_path; // The sequence of turning darts, plus the length of the flat part after the dart (a flat part is a sequence of dart with positive turn == 2). If negative value k, -k is the length of the flat part, for negative turns (-2).
bool m_is_closed; // True iff the path is a cycle
std::size_t m_length;
};