diff options
| author | Tim Dwyer <tgdwyer@gmail.com> | 2006-07-16 13:48:42 +0000 |
|---|---|---|
| committer | tgdwyer <tgdwyer@users.sourceforge.net> | 2006-07-16 13:48:42 +0000 |
| commit | 07c4a573fb37123709d30ee7a6cc15c9bb15925c (patch) | |
| tree | 95bba7018c2fe57f83a266c408738d1e33ee838b /src/libcola/connected_components.cpp | |
| parent | added inkscape_get_all_desktops() after speaking with Dale about his plans fo... (diff) | |
| download | inkscape-07c4a573fb37123709d30ee7a6cc15c9bb15925c.tar.gz inkscape-07c4a573fb37123709d30ee7a6cc15c9bb15925c.zip | |
Layout algorithm is now applied to each connected component in the
selection separately. Previously, behaviour of layout on disconnected
graphs was... undefined!
(bzr r1421)
Diffstat (limited to 'src/libcola/connected_components.cpp')
| -rw-r--r-- | src/libcola/connected_components.cpp | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/src/libcola/connected_components.cpp b/src/libcola/connected_components.cpp new file mode 100644 index 000000000..8450e4874 --- /dev/null +++ b/src/libcola/connected_components.cpp @@ -0,0 +1,67 @@ +#include <map> +#include "cola.h" +using namespace std; + +namespace cola { + namespace ccomponents { + struct Node { + unsigned id; + bool visited; + vector<Node*> neighbours; + Rectangle* r; + }; + // Depth first search traversal of graph to find connected component + void dfs(Node* v, + set<Node*>& remaining, + Component* component, + map<unsigned,pair<Component*,unsigned> > &cmap) { + v->visited=true; + remaining.erase(v); + cmap[v->id]=make_pair(component,component->node_ids.size()); + component->node_ids.push_back(v->id); + component->rects.push_back(v->r); + for(unsigned i=0;i<v->neighbours.size();i++) { + Node* u=v->neighbours[i]; + if(!u->visited) { + dfs(u,remaining,component,cmap); + } + } + } + } + + using namespace ccomponents; + + // for a graph of n nodes, return connected components + void connectedComponents( + vector<Rectangle*> &rs, + vector<Edge> &es, + vector<Component*> &components) { + unsigned n=rs.size(); + vector<Node> vs(n); + set<Node*> remaining; + for(unsigned i=0;i<n;i++) { + vs[i].id=i; + vs[i].visited=false; + vs[i].r=rs[i]; + remaining.insert(&vs[i]); + } + for(vector<Edge>::iterator e=es.begin();e!=es.end();e++) { + vs[e->first].neighbours.push_back(&vs[e->second]); + vs[e->second].neighbours.push_back(&vs[e->first]); + } + map<unsigned,pair<Component*,unsigned> > cmap; + while(!remaining.empty()) { + Component* component=new Component; + Node* v=*remaining.begin(); + dfs(v,remaining,component,cmap); + components.push_back(component); + } + for(vector<Edge>::iterator e=es.begin();e!=es.end();e++) { + pair<Component*,unsigned> u=cmap[e->first], + v=cmap[e->second]; + assert(u.first==v.first); + u.first->edges.push_back(make_pair(u.second,v.second)); + } + } +} +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 |
