summaryrefslogtreecommitdiffstats
path: root/src/libcola/connected_components.cpp
diff options
context:
space:
mode:
authorTim Dwyer <tgdwyer@gmail.com>2006-07-16 13:48:42 +0000
committertgdwyer <tgdwyer@users.sourceforge.net>2006-07-16 13:48:42 +0000
commit07c4a573fb37123709d30ee7a6cc15c9bb15925c (patch)
tree95bba7018c2fe57f83a266c408738d1e33ee838b /src/libcola/connected_components.cpp
parentadded inkscape_get_all_desktops() after speaking with Dale about his plans fo... (diff)
downloadinkscape-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.cpp67
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