43 bool cleanupRoutes=
false;
46 routes =
new vector<straightener::Route*>(E);
47 for(
unsigned i=0;i<E;i++) {
49 r->
xs[0]=
rs[
es[i].first]->getCentreX();
50 r->
ys[0]=
rs[
es[i].first]->getCentreY();
51 r->
xs[1]=
rs[
es[i].second]->getCentreX();
52 r->
ys[1]=
rs[
es[i].second]->getCentreY();
57#if defined (CAIRO_HAS_SVG_SURFACE) && defined (CAIRO_HAS_PDF_SURFACE)
60 double xmin=DBL_MAX, ymin=xmin;
61 double xmax=-DBL_MAX, ymax=xmax;
62 for (
unsigned i=0;i<
rs.size();i++) {
63 double x=
rs[i]->getCentreX(), y=
rs[i]->getCentreY();
76 Cairo::RefPtr<Cairo::Context> cr;
86 cr->set_line_width(1.);
96 Cairo::TextExtents te;
97 for (
unsigned i=0;i<
rs.size();i++) {
99 double x=
rs[i]->getCentreX()-xmin, y=
rs[i]->getCentreY()-ymin;
100 cr->arc(x,y,r, 0.0, 2.0 * M_PI);
103 double x=
rs[i]->getMinX()-xmin+0.5, y=
rs[i]->getMinY()-ymin+0.5;
108 std::stringstream s; s<<i;
111 cr->get_text_extents(str,te);
119 cr->stroke_preserve();
121 cr->set_source_rgba(245./255., 233./255., 177./255., 0.6);
125 cr->move_to(x-te.x_bearing+te.width/2.,y-te.y_bearing+te.height/2.);
134 std::cout <<
"Wrote file \"" <<
fname <<
"\"" << std::endl;
138 "WARNING: cola::OutputFile::generate(): No SVG file produced." <<
140 " You must have cairomm (and cairo with SVG support) " <<
141 "this to work." << std::endl;
145 for(
unsigned i=0;i<E;i++) {
157 c.computeBoundary(
rs);
160 cr->set_source_rgb(0.7, 0.7, 224./255.);
161 cr->move_to(
c.hullX[0]-xmin,
c.hullY[0]-ymin);
162 for(
unsigned i=1;i<
c.hullX.size();i++) {
163 cr->line_to(
c.hullX[i]-xmin,
c.hullY[i]-ymin);
165 cr->line_to(
c.hullX[0]-xmin,
c.hullY[0]-ymin);
169 cr->move_to(
c.hullX[0]-xmin,
c.hullY[0]-ymin);
170 for(
unsigned i=1;i<
c.hullX.size();i++) {
171 cr->line_to(
c.hullX[i]-xmin,
c.hullY[i]-ymin);
173 cr->line_to(
c.hullX[0]-xmin,
c.hullY[0]-ymin);
178 vector<straightener::Route*>
const &
es,
double const xmin,
double const ymin) {
181 cr->set_source_rgba(0,0,1,0.5);
182 for (
unsigned i=0;i<
es.size();i++) {
184 cr->move_to(r->
xs[0]-xmin,r->
ys[0]-ymin);
185 for (
unsigned j=1;j<r->
n;j++) {
186 cr->line_to(r->
xs[j]-xmin,r->
ys[j]-ymin);
195 unsigned startID, endID;
196 double x0,y0,x1,y1,x2,y2,x3,y3;
201 vector<CEdge*>
edges;
204double vangle(
double ax,
double ay,
double bx,
double by) {
205 double ab=ax*bx+ay*by;
206 double len=sqrt(ax*ax+ay*ay)*sqrt(bx*bx+by*by);
207 double angle=acos(ab/
len);
215 vector<CEdge*>
edges;
216 CBundle(CNode
const &u) :
w(u.
edges.
size()), x0(u.x), y0(u.y), sx(
w*u.x), sy(
w*u.y) { }
217 void addEdge(CEdge *e) {
218 if(x0==e->x0 && y0==e->y0) {
219 sx+=e->x3; sy+=e->y3;
221 sx+=e->x0; sy+=e->y0;
226 return sx/(
w+
edges.size());
229 return sy/(
w+
edges.size());
231 double angle(CBundle*
const &b)
const {
234 double bx=b->x1()-b->x0;
235 double by=b->y1()-b->y0;
236 return vangle(ax,ay,bx,by);
238 double yangle()
const {
242 return vangle(0,1,x,y)*o+M_PI;
244 void merge(CBundle* b) {
245 for(
unsigned i=0;i<b->edges.size();i++) {
246 addEdge(b->edges[i]);
251 for(
unsigned i=0;i<
edges.size();i++) {
252 printf(
"(%d,%d) ",edges[i]->startID,edges[i]->endID);
257 bool operator() (CBundle*
const &a, CBundle*
const &b) {
258 return a->yangle()<b->yangle();
269 vector<cola::Edge>
const &
es,
273 vector<CNode> nodes(
rs.size());
274 vector<CEdge>
edges(
es.size());
275 for (
unsigned i=0;i<
es.size();i++) {
278 unsigned end=
es[i].second;
283 nodes[
end].x=
rs[
end]->getCentreX()-xmin;
284 nodes[
end].y=
rs[
end]->getCentreY()-ymin;
285 e->x0=nodes[
start].x;
286 e->x1=nodes[
start].x;
289 e->y0=nodes[
start].y;
290 e->y1=nodes[
start].y;
293 nodes[
end].edges.push_back(e);
294 nodes[
start].edges.push_back(e);
297 for (
unsigned i=0;i<nodes.size();i++) {
299 if(u.edges.size()<2)
continue;
300 for (
unsigned j=0;j<u.edges.size();j++) {
301 CBundle* b=
new CBundle(u);
302 b->addEdge(u.edges[j]);
303 u.bundles.push_back(b);
305 u.bundles.sort(clockwise());
317 double minAngle=DBL_MAX;
318 list<CBundle*>::iterator mini,minj,i,j;
319 for(i=u.bundles.begin();i!=u.bundles.end();i++) {
321 if(++j==u.bundles.end()) {
326 double angle=b->yangle()-a->yangle();
327 if(angle<0) angle+=2*M_PI;
337 if(minAngle>cos(M_PI/8.))
break;
346 u.bundles.erase(mini);
347 if(u.bundles.size() < 2)
break;
349 for(list<CBundle*>::iterator i=u.bundles.begin();i!=u.bundles.end();i++) {
351 for(
unsigned i=0;i<b->edges.size();i++) {
352 CEdge* e=b->edges[i];
353 if(e->x0==u.x&&e->y0==u.y) {
366 cr->set_source_rgba(0,0,1,0.2);
367 for (
unsigned i=0;i<
edges.size();i++) {
369 cr->move_to(e.x0,e.y0);
370 cr->curve_to(e.x1,e.y1,e.x2,e.y2,e.x3,e.y3);
376 if(
fname.rfind(
"pdf") == (
fname.length()-3) ) {
377 printf(
"writing pdf file: %s\n",
fname.c_str());
378 Cairo::RefPtr<Cairo::PdfSurface> pdfsurface =
380 cr = Cairo::Context::create(pdfsurface);
382 printf(
"writing svg file: %s\n",
fname.c_str());
383 Cairo::RefPtr<Cairo::SvgSurface> svgsurface =
385 cr = Cairo::Context::create(svgsurface);
constexpr Coord x() const noexcept
void draw_curved_edges(Cairo::RefPtr< Cairo::Context > &cr, std::vector< cola::Edge > const &es, const double xmin, const double ymin)
std::vector< std::string > labels
std::vector< straightener::Route * > * routes
std::vector< cola::Edge > const & es
void openCairo(Cairo::RefPtr< Cairo::Context > &cr, double width, double height)
void draw_cluster_boundary(Cairo::RefPtr< Cairo::Context > const &cr, cola::Cluster &c, const double xmin, const double ymin)
std::vector< vpsc::Rectangle * > const & rs
cola::RootCluster const * rc
void draw_edges(Cairo::RefPtr< Cairo::Context > &cr, std::vector< straightener::Route * > const &es, double const xmin, double const ymin)
A cluster defines a hierarchical partitioning over the nodes which should be kept disjoint by the lay...
std::vector< Cluster * > clusters
A rectangle represents a fixed-size shape in the diagram that may be moved to prevent overlaps and sa...
double angle(std::vector< Point > const &A)
ConvexHull merge(ConvexHull a, ConvexHull b)
double vangle(double ax, double ay, double bx, double by)
libcola: Force-directed network layout subject to separation constraints library.
Edges edges(Path const &p, Crossings const &cr, unsigned ix)