21 #ifndef STRAIGHTENER_H 22 #define STRAIGHTENER_H 29 #include "libvpsc/rectangle.h" 30 #include "libcola/commondefs.h" 35 class SeparationConstraint;
40 Route(
unsigned n) : n(n), xs(new double[n]), ys(new double[n]) {}
46 std::cout <<
"double xs[]={";
47 std::copy(xs,xs+n-1,std::ostream_iterator<double>(std::cout,
","));
48 std::cout << xs[n-1] <<
"};" << std::endl <<
"double ys[]={";
49 std::copy(ys,ys+n-1,std::ostream_iterator<double>(std::cout,
","));
50 std::cout << ys[n-1] <<
"};" << std::endl;
52 void boundingBox(
double &xmin,
double &ymin,
double &xmax,
double &ymax) {
55 for(
unsigned i=0;i<n;i++) {
56 xmin=std::min(xmin,xs[i]);
57 xmax=std::max(xmax,xs[i]);
58 ymin=std::min(ymin,ys[i]);
59 ymax=std::max(ymax,ys[i]);
62 double routeLength ()
const {
64 for(
unsigned i=1;i<n;i++) {
65 double dx=xs[i-1]-xs[i];
66 double dy=ys[i-1]-ys[i];
67 length+=sqrt(dx*dx+dy*dy);
81 DebugLine(
double x0,
double y0,
double x1,
double y1,
unsigned colour)
82 : x0(x0),y0(y0),x1(x1),y1(y1),colour(colour) {}
95 ScanObject(
unsigned id) : id(id) {}
97 double min[2], max[2];
99 class Edge :
public ScanObject {
102 unsigned startNode, endNode;
104 std::vector<unsigned> dummyNodes;
105 std::vector<unsigned> path;
106 std::vector<unsigned> activePath;
107 std::vector<DebugPoint> debugPoints;
108 std::vector<DebugLine> debugLines;
110 printf(
"Edge[%d]=(%d,%d)\n",
id,startNode,endNode);
115 void rerouteAround(std::vector<vpsc::Rectangle*>
const &rects) {
117 for(std::vector<vpsc::Rectangle*>::const_iterator r=rects.begin();r!=rects.end();r++,rid++) {
118 if(rid!=startNode && rid!=endNode) {
119 route->rerouteAround(*r);
125 Edge(
unsigned id,
unsigned start,
unsigned end, Route* route)
126 : ScanObject(id), startNode(start), endNode(end), route(route)
131 Edge(
unsigned id,
unsigned start,
unsigned end,
132 double x1,
double y1,
double x2,
double y2)
133 : ScanObject(id), startNode(start), endNode(end) {
134 route =
new Route(2);
135 route->xs[0]=x1; route->ys[0]=y1;
136 route->xs[1]=x2; route->ys[1]=y2;
142 bool isEnd(
unsigned n)
const {
143 if(startNode==n||endNode==n)
return true;
146 void nodePath(std::vector<Node*>& nodes,
bool allActive);
147 void createRouteFromPath(std::vector<Node *>
const & nodes);
148 void xpos(
double y, std::vector<double>& xs)
const {
150 for(
unsigned i=1;i<route->n;i++) {
151 double ax=route->xs[i-1], bx=route->xs[i], ay=route->ys[i-1], by=route->ys[i];
152 double r=(y-ay)/(by-ay);
155 xs.push_back(ax+(bx-ax)*r);
159 void ypos(
double x, std::vector<double>& ys)
const {
161 for(
unsigned i=1;i<route->n;i++) {
162 double ax=route->xs[i-1], bx=route->xs[i], ay=route->ys[i-1], by=route->ys[i];
163 double r=(x-ax)/(bx-ax);
166 ys.push_back(ay+(by-ay)*r);
170 Route
const * getRoute()
const {
173 void setRoute(Route * r) {
179 void updateBoundingBox() {
180 route->boundingBox(min[0],min[1],max[0],max[1]);
187 const double strength,
189 std::vector<vpsc::Rectangle*>
const & rs,
190 cola::FixedList
const & fixed,
191 std::vector<Edge*>
const & edges,
195 std::valarray<double> & oldCoords,
196 std::valarray<double> & oldG);
198 void updateNodePositions();
199 void finalizeRoutes();
200 void computeForces(cola::SparseMap &H);
201 void computeForces2(cola::SparseMap &H);
202 double computeStress(std::valarray<double>
const &coords);
203 double computeStress2(std::valarray<double>
const &coords);
204 std::valarray<double> dummyNodesX;
205 std::valarray<double> dummyNodesY;
206 std::valarray<double> g;
207 std::valarray<double> coords;
212 cola::FixedList
const & fixed;
213 std::vector<Edge*>
const & edges;
216 std::vector<Node*> nodes;
217 double len(
const unsigned u,
const unsigned v,
218 double& dx,
double& dy,
219 double& dx2,
double& dy2);
220 double gRule1(
const unsigned a,
const unsigned b);
221 double gRule2(
const unsigned a,
const unsigned b,
const unsigned c);
222 double hRuleD1(
const unsigned u,
const unsigned v,
const double sqrtf);
223 double hRuleD2(
const unsigned u,
const unsigned v,
const unsigned w,
const double sqrtf);
224 double hRule2(
const unsigned u,
const unsigned v,
const unsigned w,
const double sqrtf);
225 double hRule3(
const unsigned u,
const unsigned v,
const unsigned w,
const double sqrtf);
226 double hRule4(
const unsigned a,
const unsigned b,
const unsigned c,
const unsigned d);
227 double hRule56(
const unsigned u,
const unsigned v,
228 const unsigned a,
const unsigned b,
const unsigned c);
229 double hRule7(
const unsigned a,
const unsigned b,
230 const unsigned c,
const unsigned d,
const double sqrtf);
231 double hRule8(
const unsigned u,
const unsigned v,
const unsigned w,
232 const unsigned a,
const unsigned b,
const unsigned c);
239 std::vector<Edge*> boundary;
240 void updateActualBoundary();
242 class Node :
public ScanObject {
258 ScanObject(id),cluster(nullptr),
259 edge(nullptr),dummy(false),scan(true),active(true),open(false) {
260 for(
unsigned i=0;i<2;i++) {
261 pos[i]=r->getCentreD(i);
262 min[i]=r->getMinD(i);
263 max[i]=r->getMaxD(i);
264 length[i]=r->length(i);
267 Node(
unsigned id,
const double x,
const double y) :
268 ScanObject(id),cluster(nullptr),
269 edge(nullptr),dummy(false),scan(false),active(true),open(false) {
272 for(
unsigned i=0;i<2;i++) {
274 min[i]=pos[i]-length[i]/2.0;
275 max[i]=pos[i]+length[i]/2.0;
278 double euclidean_distance(Node
const * v)
const {
279 double dx=pos[0]-v->pos[0];
280 double dy=pos[1]-v->pos[1];
281 return sqrt(dx*dx+dy*dy);
285 friend void sortNeighbours(
const vpsc::Dim dim, Node * v, Node * l, Node * r,
286 const double conjpos, std::vector<Edge*>
const & openEdges,
287 std::vector<Node *>& L, std::vector<Node *>& nodes);
288 Node(
const unsigned id,
const double x,
const double y, Edge* e) :
289 ScanObject(id),cluster(nullptr),
290 edge(e),dummy(true),scan(false),active(false) {
293 for(
unsigned i=0;i<2;i++) {
295 min[i]=pos[i]-length[i]/2.0;
296 max[i]=pos[i]+length[i]/2.0;
298 e->dummyNodes.push_back(
id);
302 bool operator() (
const Node* u,
const Node* v)
const {
303 double upos = u->scanpos;
304 double vpos = v->scanpos;
305 bool tiebreaker = u < v;
306 if (u->cluster != v->cluster) {
307 if(u->cluster!=
nullptr) {
308 upos = u->cluster->scanpos;
310 if(v->cluster!=
nullptr) {
311 vpos = v->cluster->scanpos;
313 tiebreaker = u->cluster < v->cluster;
324 typedef std::set<Node*,CmpNodePos> NodeSet;
328 struct LinearConstraint {
334 : u(u.id),v(v.id),b(b.id),w(w)
337 double uvx = v.pos[0] - u.pos[0],
338 uvy = v.pos[1] - u.pos[1],
339 ubx = b.pos[0] - u.pos[0],
340 uby = b.pos[1] - u.pos[1],
341 duv2 = uvx * uvx + uvy * uvy;
345 t = (uvx * ubx + uvy * uby)/duv2;
369 void setEdgeLengths(
double **D, std::vector<Edge*> & edges);
370 double pathLength(Edge
const * e, std::vector<Node*>
const & nodes);
371 double computeStressFromRoutes(
double strength, std::vector<Edge*> & edges);
372 typedef std::vector<LinearConstraint*> LinearConstraints;
373 void generateConstraints(
375 std::vector<Node*> & nodes,
376 std::vector<Edge*>
const & edges,
377 std::vector<cola::SeparationConstraint*>& cs,
379 void nodePath(Edge& e, std::vector<Node*>& nodes, std::vector<unsigned>& path);
380 void generateClusterBoundaries(
382 std::vector<Node*> & nodes,
383 std::vector<Edge*> & edges,
384 std::vector<vpsc::Rectangle*>
const & rs,
386 std::vector<straightener::Cluster*>& sclusters);
Definition: gradient_projection.h:40
std::pair< unsigned, unsigned > Edge
Edges are simply a pair of indices to entries in the Node vector.
Definition: cola.h:68
std::vector< Variable * > Variables
A vector of pointers to Variable objects.
Definition: constraint.h:38
std::vector< Constraint * > Constraints
A vector of pointers to Constraint objects.
Definition: constraint.h:125
A rectangle represents a fixed-size shape in the diagram that may be moved to prevent overlaps and sa...
Definition: rectangle.h:78
The y-dimension (1).
Definition: rectangle.h:47
A cluster defines a hierarchical partitioning over the nodes which should be kept disjoint by the lay...
Definition: cluster.h:50
libcola: Force-directed network layout subject to separation constraints library. ...
Definition: box.cpp:25
The x-dimension (0).
Definition: rectangle.h:43
Dim
Indicates the x- or y-dimension.
Definition: rectangle.h:41
Defines a cluster that will be treated as a convex boundary around the child nodes and clusters...
Definition: cluster.h:358