#include #include #include #include "cola.h" using namespace std; namespace cola { Component::~Component() { for(unsigned i=0;imoveCentreX(rects[i]->getCentreX()+x); rects[i]->moveCentreY(rects[i]->getCentreY()+y); } } Rectangle* Component::getBoundingBox() { double llx=DBL_MAX, lly=DBL_MAX, urx=-DBL_MAX, ury=-DBL_MAX; for(unsigned i=0;igetMinX()); lly=min(lly,rects[i]->getMinY()); urx=max(urx,rects[i]->getMaxX()); ury=max(ury,rects[i]->getMaxY()); } return new Rectangle(llx,urx,lly,ury); } namespace ccomponents { struct Node { unsigned id; bool visited; vector neighbours; list::iterator listPos; Rectangle* r; }; // Depth first search traversal of graph to find connected component static void dfs(Node* v, list& remaining, Component* component, map > &cmap) { v->visited=true; remaining.erase(v->listPos); 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;ineighbours.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( const vector &rs, const vector &es, const SimpleConstraints &scx, const SimpleConstraints &scy, vector &components) { unsigned n=rs.size(); vector vs(n); list remaining; for(unsigned i=0;i::const_iterator ei; SimpleConstraints::const_iterator ci; for(ei=es.begin();ei!=es.end();++ei) { vs[ei->first].neighbours.push_back(&vs[ei->second]); vs[ei->second].neighbours.push_back(&vs[ei->first]); } map > cmap; while(!remaining.empty()) { Component* component=new Component; Node* v=*remaining.begin(); dfs(v,remaining,component,cmap); components.push_back(component); } for(ei=es.begin();ei!=es.end();++ei) { pair u=cmap[ei->first], v=cmap[ei->second]; assert(u.first==v.first); u.first->edges.push_back(make_pair(u.second,v.second)); } for(ci=scx.begin();ci!=scx.end();++ci) { SimpleConstraint *c=*ci; pair u=cmap[c->left], v=cmap[c->right]; assert(u.first==v.first); u.first->scx.push_back( new SimpleConstraint(u.second,v.second,c->gap)); } for(ci=scy.begin();ci!=scy.end();++ci) { SimpleConstraint *c=*ci; pair u=cmap[c->left], v=cmap[c->right]; assert(u.first==v.first); u.first->scy.push_back( new SimpleConstraint(u.second,v.second,c->gap)); } } void separateComponents(const vector &components) { unsigned n=components.size(); Rectangle* bbs[n]; double origX[n], origY[n]; for(unsigned i=0;igetBoundingBox(); origX[i]=bbs[i]->getCentreX(); origY[i]=bbs[i]->getCentreY(); } removeRectangleOverlap(n,bbs,0,0); for(unsigned i=0;imoveRectangles( bbs[i]->getCentreX()-origX[i], bbs[i]->getCentreY()-origY[i]); delete bbs[i]; } } } // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4