Graphviz 15.1.0~dev.20260613.0511
Loading...
Searching...
No Matches
tlayout.c
Go to the documentation of this file.
1/*************************************************************************
2 * Copyright (c) 2011 AT&T Intellectual Property
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v2.0
5 * which accompanies this distribution, and is available at
6 * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
7 *
8 * Contributors: Details at https://graphviz.org
9 *************************************************************************/
10
11/* tlayout.c:
12 * Written by Emden R. Gansner
13 *
14 * Module for initial layout, using point nodes and ports.
15 *
16 * Note: If interior nodes are not connected, they tend to fly apart,
17 * despite being tied to port nodes. This occurs because, as initially
18 * coded, as the nodes tend to straighten into a line, the radius
19 * grows causing more expansion. Is the problem really here and not
20 * with disconnected nodes in xlayout? If here, we can either forbid
21 * expansion or eliminate repulsion between nodes only connected
22 * via port nodes.
23 */
24
25#include "config.h"
26
27/* uses PRIVATE interface */
28#define FDP_PRIVATE 1
29
30#include <fdpgen/dbg.h>
31#include <fdpgen/grid.h>
32#include <math.h>
33#include <neatogen/neato.h>
34#include <stdbool.h>
35#include <stdlib.h>
36#include <sys/types.h>
37#include <time.h>
38
39#ifndef HAVE_SRAND48
40#define srand48 srand
41#endif
42
43#include <common/globals.h>
44#include <fdpgen/tlayout.h>
45
46#define D_useGrid (fdp_parms->useGrid)
47#define D_useNew (fdp_parms->useNew)
48#define D_numIters (fdp_parms->numIters)
49#define D_unscaled (fdp_parms->unscaled)
50#define D_C (fdp_parms->C)
51#define D_Tfact (fdp_parms->Tfact)
52#define D_K (fdp_parms->K)
53#define D_T0 (fdp_parms->T0)
54
55/* Actual parameters used; initialized using fdp_parms, then possibly
56 * updated with graph-specific values.
57 */
58typedef struct {
59 int useGrid; /* use grid for speed up */
60 int useNew; /* encode x-K into attractive force */
61 long seed; /* seed for position RNG */
62 int numIters; /* actual iterations in layout */
63 int maxIters; /* max iterations in layout */
64 int unscaled; /* % of iterations used in pass 1 */
65 double C; /* Repulsion factor in xLayout */
66 double Tfact; /* scale temp from default expression */
67 double K; /* spring constant; ideal distance */
68 double T0; /* initial temperature */
69 int smode; /* seed mode */
70 double Cell; /* grid cell size */
71 double Wd; /* half-width of boundary */
72 double Ht; /* half-height of boundary */
73 int pass1; /* iterations used in pass 1 */
74 int loopcnt; /* actual iterations in this pass */
75} parms_t;
76
78
79#define T_useGrid (parms.useGrid)
80#define T_useNew (parms.useNew)
81#define T_seed (parms.seed)
82#define T_numIters (parms.numIters)
83#define T_maxIters (parms.maxIters)
84#define T_unscaled (parms.unscaled)
85#define T_C (parms.C)
86#define T_Tfact (parms.Tfact)
87#define T_K (parms.K)
88#define T_T0 (parms.T0)
89#define T_smode (parms.smode)
90#define T_Cell (parms.Cell)
91#define T_Wd (parms.Wd)
92#define T_Ht (parms.Ht)
93#define T_pass1 (parms.pass1)
94#define T_loopcnt (parms.loopcnt)
95
96#define EXPFACTOR 1.2
97#define DFLT_maxIters 600
98#define DFLT_K 0.3
99#define DFLT_Cell 0.0
100#define DFLT_seed 1
101#define DFLT_smode INIT_RANDOM
102
103static double cool(int t) { return T_T0 * (T_maxIters - t) / T_maxIters; }
104
105static void reset_params(void) { T_T0 = -1.0; }
106
107/* Set parameters for expansion phase based on initial
108 * layout parameters. If T0 is not set, we set it here
109 * based on the size of the graph. In this case, we
110 * return true, so that fdp_tLayout can unset T0, to be
111 * reset by a recursive call to fdp_tLayout.
112 *
113 * @return Does `reset` need to be called later?
114 */
115static bool init_params(graph_t *g, xparams *xpms) {
116 bool ret = false;
117
118 if (T_T0 == -1.0) {
119 int nnodes = agnnodes(g);
120
121 T_T0 = T_Tfact * T_K * sqrt(nnodes) / 5;
122#ifdef DEBUG
123 if (Verbose) {
124 prIndent();
125 fprintf(stderr, "tlayout %s", agnameof(g));
126 fprintf(stderr, "(%s) : T0 %f\n", agnameof(GORIG(g->root)), T_T0);
127 }
128#endif
129 ret = true;
130 }
131
132 xpms->T0 = cool(T_pass1);
133 xpms->K = T_K;
134 xpms->C = T_C;
135 xpms->numIters = T_maxIters - T_pass1;
136
137 if (T_numIters >= 0) {
138 if (T_numIters <= T_pass1) {
140 xpms->loopcnt = 0;
141 } else if (T_numIters <= T_maxIters) {
143 xpms->loopcnt = T_numIters - T_pass1;
144 }
145 } else {
147 xpms->loopcnt = xpms->numIters;
148 }
149 return ret;
150}
151
159 T_C = D_C;
161 T_maxIters =
162 late_int(g, agattr_text(g, AGRAPH, "maxiter", NULL), DFLT_maxIters, 0);
163 D_K = T_K = late_double(g, agattr_text(g, AGRAPH, "K", NULL), DFLT_K, 0.0);
164 if (D_T0 == -1.0) {
165 T_T0 = late_double(g, agattr_text(g, AGRAPH, "T0", NULL), -1.0, 0.0);
166 } else
167 T_T0 = D_T0;
170 if (T_smode == INIT_SELF) {
171 agwarningf("fdp does not support start=self - ignoring\n");
173 }
174
175 T_pass1 = T_unscaled * T_maxIters / 100;
176
177 if (T_useGrid) {
178 if (T_Cell <= 0.0)
179 T_Cell = 3 * T_K;
180 }
181#ifdef DEBUG
182 if (Verbose) {
183 prIndent();
184 fprintf(stderr, "Params %s : K %f T0 %f Tfact %f maxIters %d unscaled %d\n",
186 }
187#endif
188}
189
190static void doRep(node_t *p, node_t *q, double xdelta, double ydelta,
191 double dist) {
192 double force;
193
194 while (!(dist > 0)) {
195 xdelta = 5 - rand() % 10;
196 ydelta = 5 - rand() % 10;
197 dist = hypot(xdelta, ydelta);
198 }
199 if (dist > fdp_parms->Mlimit) {
200 force = 0;
201 } else if (T_useNew) {
202 force = T_K * T_K / (dist * dist * dist);
203 } else
204 force = T_K * T_K / (dist * dist);
205 if (IS_PORT(p) && IS_PORT(q))
206 force *= 10.0;
207 DISP(q)[0] += xdelta * force;
208 DISP(q)[1] += ydelta * force;
209 DISP(p)[0] -= xdelta * force;
210 DISP(p)[1] -= ydelta * force;
211}
212
214static void applyRep(Agnode_t *p, Agnode_t *q) {
215 double xdelta, ydelta;
216
217 xdelta = ND_pos(q)[0] - ND_pos(p)[0];
218 ydelta = ND_pos(q)[1] - ND_pos(p)[1];
219 doRep(p, q, xdelta, ydelta, hypot(xdelta, ydelta));
220}
221
222static void doNeighbor(Grid *grid, int i, int j, node_list *nodes) {
223 cell *cellp = findGrid(grid, i, j);
224 node_list *qs;
225 Agnode_t *p;
226 Agnode_t *q;
227 double xdelta, ydelta;
228
229 if (cellp) {
230#ifdef DEBUG
231 if (Verbose >= 3) {
232 prIndent();
233 fprintf(stderr, " doNeighbor (%d,%d) : %d\n", i, j, gLength(cellp));
234 }
235#endif
236 for (; nodes != 0; nodes = nodes->next) {
237 p = nodes->node;
238 for (qs = cellp->nodes; qs != 0; qs = qs->next) {
239 q = qs->node;
240 xdelta = (ND_pos(q))[0] - (ND_pos(p))[0];
241 ydelta = (ND_pos(q))[1] - (ND_pos(p))[1];
242 const double dist = hypot(xdelta, ydelta);
243 if (dist < T_Cell)
244 doRep(p, q, xdelta, ydelta, dist);
245 }
246 }
247 }
248}
249
250static int gridRepulse(void *c, void *g) {
251 cell *const cellp = c;
252 Grid *const grid = g;
253 node_list *nodes = cellp->nodes;
254 int i = cellp->p.i;
255 int j = cellp->p.j;
256 node_list *p;
257 node_list *q;
258
259#ifdef DEBUG
260 if (Verbose >= 3) {
261 prIndent();
262 fprintf(stderr, "gridRepulse (%d,%d) : %d\n", i, j, gLength(cellp));
263 }
264#endif
265 for (p = nodes; p != 0; p = p->next) {
266 for (q = nodes; q != 0; q = q->next)
267 if (p != q)
268 applyRep(p->node, q->node);
269 }
270
271 doNeighbor(grid, i - 1, j - 1, nodes);
272 doNeighbor(grid, i - 1, j, nodes);
273 doNeighbor(grid, i - 1, j + 1, nodes);
274 doNeighbor(grid, i, j - 1, nodes);
275 doNeighbor(grid, i, j + 1, nodes);
276 doNeighbor(grid, i + 1, j - 1, nodes);
277 doNeighbor(grid, i + 1, j, nodes);
278 doNeighbor(grid, i + 1, j + 1, nodes);
279
280 return 0;
281}
282
283/* Attractive force = weight × (d × d) ÷ K
284 * or force = (d - L(e)) × weight(e)
285 */
286static void applyAttr(Agnode_t *p, Agnode_t *q, Agedge_t *e) {
287 double xdelta, ydelta;
288 double force;
289 double dist;
290 double dist2;
291
292 xdelta = ND_pos(q)[0] - ND_pos(p)[0];
293 ydelta = ND_pos(q)[1] - ND_pos(p)[1];
294 dist2 = xdelta * xdelta + ydelta * ydelta;
295 while (dist2 == 0.0) {
296 xdelta = 5 - rand() % 10;
297 ydelta = 5 - rand() % 10;
298 dist2 = xdelta * xdelta + ydelta * ydelta;
299 }
300 dist = sqrt(dist2);
301 if (T_useNew)
302 force = ED_factor(e) * (dist - ED_dist(e)) / dist;
303 else
304 force = ED_factor(e) * dist / ED_dist(e);
305 DISP(q)[0] -= xdelta * force;
306 DISP(q)[1] -= ydelta * force;
307 DISP(p)[0] += xdelta * force;
308 DISP(p)[1] += ydelta * force;
309}
310
311static void updatePos(Agraph_t *g, double temp, bport_t *pp) {
312 Agnode_t *n;
313 double temp2;
314 double len2;
315 double x, y, d;
316 double dx, dy;
317
318 temp2 = temp * temp;
319 for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
320 if (ND_pinned(n) & P_FIX)
321 continue;
322 dx = DISP(n)[0];
323 dy = DISP(n)[1];
324 len2 = dx * dx + dy * dy;
325
326 /* limit by temperature */
327 if (len2 < temp2) {
328 x = ND_pos(n)[0] + dx;
329 y = ND_pos(n)[1] + dy;
330 } else {
331 double fact = temp / sqrt(len2);
332 x = ND_pos(n)[0] + dx * fact;
333 y = ND_pos(n)[1] + dy * fact;
334 }
335
336 /* if ports, limit by boundary */
337 if (pp) {
338 d = sqrt(x * x / (T_Wd * T_Wd) + y * y / (T_Ht * T_Ht));
339 if (IS_PORT(n)) {
340 ND_pos(n)[0] = x / d;
341 ND_pos(n)[1] = y / d;
342 } else if (d >= 1.0) {
343 ND_pos(n)[0] = 0.95 * x / d;
344 ND_pos(n)[1] = 0.95 * y / d;
345 } else {
346 ND_pos(n)[0] = x;
347 ND_pos(n)[1] = y;
348 }
349 } else {
350 ND_pos(n)[0] = x;
351 ND_pos(n)[1] = y;
352 }
353 }
354}
355
356#define FLOOR(d) ((int)floor(d))
357
358static void gAdjust(Agraph_t *g, double temp, bport_t *pp, Grid *grid) {
359 Agnode_t *n;
360 Agedge_t *e;
361
362 if (temp <= 0.0)
363 return;
364
366
367 for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
368 DISP(n)[0] = DISP(n)[1] = 0;
369 addGrid(grid, FLOOR((ND_pos(n))[0] / T_Cell),
370 FLOOR((ND_pos(n))[1] / T_Cell), n);
371 }
372
373 for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
374 for (e = agfstout(g, n); e; e = agnxtout(g, e))
375 if (n != aghead(e))
376 applyAttr(n, aghead(e), e);
377 }
379
380 updatePos(g, temp, pp);
381}
382
383static void adjust(Agraph_t *g, double temp, bport_t *pp) {
384 Agnode_t *n;
385 Agnode_t *n1;
386 Agedge_t *e;
387
388 if (temp <= 0.0)
389 return;
390
391 for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
392 DISP(n)[0] = DISP(n)[1] = 0;
393 }
394
395 for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
396 for (n1 = agnxtnode(g, n); n1; n1 = agnxtnode(g, n1)) {
397 applyRep(n, n1);
398 }
399 for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
400 if (n != aghead(e))
401 applyAttr(n, aghead(e), e);
402 }
403 }
404
405 updatePos(g, temp, pp);
406}
407
408/* Create initial layout of nodes
409 * TODO :
410 * Position nodes near neighbors with positions.
411 * Use bbox to reset K.
412 */
413static pointf initPositions(graph_t *g, bport_t *pp) {
414 int nG = agnnodes(g) - NPORTS(g);
415 double size;
416 Agnode_t *np;
417 int n_pos = 0; /* no. of nodes with position info */
418 boxf bb = {{0, 0}, {0, 0}};
419 pointf ctr; /* center of boundary ellipse */
420 long local_seed;
421 double PItimes2 = M_PI * 2.0;
422
423 for (np = agfstnode(g); np; np = agnxtnode(g, np)) {
424 if (ND_pinned(np)) {
425 if (n_pos) {
426 bb.LL.x = MIN(ND_pos(np)[0], bb.LL.x);
427 bb.LL.y = MIN(ND_pos(np)[1], bb.LL.y);
428 bb.UR.x = MAX(ND_pos(np)[0], bb.UR.x);
429 bb.UR.y = MAX(ND_pos(np)[1], bb.UR.y);
430 } else {
431 bb.UR.x = bb.LL.x = ND_pos(np)[0];
432 bb.UR.y = bb.LL.y = ND_pos(np)[1];
433 }
434 n_pos++;
435 }
436 }
437
438 size = T_K * (sqrt(nG) + 1.0);
439 T_Wd = T_Ht = EXPFACTOR * (size / 2.0);
440 if (n_pos == 1) {
441 ctr.x = bb.LL.x;
442 ctr.y = bb.LL.y;
443 } else if (n_pos > 1) {
444 double alpha, area, width, height, quot;
445 ctr.x = (bb.LL.x + bb.UR.x) / 2.0;
446 ctr.y = (bb.LL.y + bb.UR.y) / 2.0;
447 width = EXPFACTOR * (bb.UR.x - bb.LL.x);
448 height = EXPFACTOR * (bb.UR.y - bb.LL.y);
449 area = 4.0 * T_Wd * T_Ht;
450 quot = width * height / area;
451 if (quot >= 1.0) { /* If bbox has large enough area, use it */
452 T_Wd = width / 2.0;
453 T_Ht = height / 2.0;
454 } else if (quot > 0.0) { /* else scale up to have enough area */
455 quot = 2.0 * sqrt(quot);
456 T_Wd = width / quot;
457 T_Ht = height / quot;
458 } else { /* either width or height is 0 */
459 if (width > 0) {
460 height = area / width;
461 T_Wd = width / 2.0;
462 T_Ht = height / 2.0;
463 } else if (height > 0) {
464 width = area / height;
465 T_Wd = width / 2.0;
466 T_Ht = height / 2.0;
467 }
468 /* If width = height = 0, use Wd and Ht as defined above for
469 * the case the n_pos == 0.
470 */
471 }
472
473 /* Construct enclosing ellipse */
474 alpha = atan2(T_Ht, T_Wd);
475 T_Wd = T_Wd / cos(alpha);
476 T_Ht = T_Ht / sin(alpha);
477 } else {
478 ctr.x = ctr.y = 0;
479 }
480
481 /* Set seed value */
482 if (T_smode == INIT_RANDOM)
483 local_seed = T_seed;
484 else {
485 local_seed = (long)time(NULL);
486 }
487 srand48(local_seed);
488
489 /* If ports, place ports on and nodes within an ellipse centered at origin
490 * with halfwidth Wd and halfheight Ht.
491 * If no ports, place nodes within a rectangle centered at origin
492 * with halfwidth Wd and halfheight Ht. Nodes with a given position
493 * are translated. Wd and Ht are set to contain all positioned points.
494 * The reverse translation will be applied to all
495 * nodes at the end of the layout.
496 * TODO: place unfixed points using adjacent ports or fixed pts.
497 */
498 if (pp) {
499 while (pp->e) { /* position ports on ellipse */
500 np = pp->n;
501 ND_pos(np)[0] = T_Wd * cos(pp->alpha) + ctr.x;
502 ND_pos(np)[1] = T_Ht * sin(pp->alpha) + ctr.y;
503 ND_pinned(np) = P_SET;
504 pp++;
505 }
506 for (np = agfstnode(g); np; np = agnxtnode(g, np)) {
507 if (IS_PORT(np))
508 continue;
509 if (ND_pinned(np)) {
510 ND_pos(np)[0] -= ctr.x;
511 ND_pos(np)[1] -= ctr.y;
512 } else {
513 pointf p = {0.0, 0.0};
514 int cnt = 0;
515 node_t *op;
516 edge_t *ep;
517 for (ep = agfstedge(g, np); ep; ep = agnxtedge(g, ep, np)) {
518 if (aghead(ep) == agtail(ep))
519 continue;
520 op = aghead(ep) == np ? agtail(ep) : aghead(ep);
521 if (!hasPos(op))
522 continue;
523 if (cnt) {
524 p.x = (p.x * cnt + ND_pos(op)[0]) / (cnt + 1);
525 p.y = (p.y * cnt + ND_pos(op)[1]) / (cnt + 1);
526 } else {
527 p.x = ND_pos(op)[0];
528 p.y = ND_pos(op)[1];
529 }
530 cnt++;
531 }
532 if (cnt > 1) {
533 ND_pos(np)[0] = p.x;
534 ND_pos(np)[1] = p.y;
535 } else if (cnt == 1) {
536 ND_pos(np)[0] = 0.98 * p.x + 0.1 * ctr.x;
537 ND_pos(np)[1] = 0.9 * p.y + 0.1 * ctr.y;
538 } else {
539 double angle = PItimes2 * drand48();
540 double radius = 0.9 * drand48();
541 ND_pos(np)[0] = radius * T_Wd * cos(angle);
542 ND_pos(np)[1] = radius * T_Ht * sin(angle);
543 }
544 ND_pinned(np) = P_SET;
545 }
546 }
547 } else {
548 if (n_pos) { /* If positioned nodes */
549 for (np = agfstnode(g); np; np = agnxtnode(g, np)) {
550 if (ND_pinned(np)) {
551 ND_pos(np)[0] -= ctr.x;
552 ND_pos(np)[1] -= ctr.y;
553 } else {
554 ND_pos(np)[0] = T_Wd * (2.0 * drand48() - 1.0);
555 ND_pos(np)[1] = T_Ht * (2.0 * drand48() - 1.0);
556 }
557 }
558 } else { /* No ports or positions; place randomly */
559 for (np = agfstnode(g); np; np = agnxtnode(g, np)) {
560 ND_pos(np)[0] = T_Wd * (2.0 * drand48() - 1.0);
561 ND_pos(np)[1] = T_Ht * (2.0 * drand48() - 1.0);
562 }
563 }
564 }
565
566 return ctr;
567}
568
569/* Given graph g with ports nodes, layout g respecting ports.
570 * If some node have position information, it may be useful to
571 * reset temperature and other parameters to reflect this.
572 */
573void fdp_tLayout(graph_t *g, xparams *xpms) {
574 bport_t *const pp = PORTS(g);
575 const bool reset = init_params(g, xpms);
576 const pointf ctr = initPositions(g, pp);
577
578 if (T_useGrid) {
579 Grid *const grid = mkGrid(agnnodes(g));
581 for (int i = 0; i < T_loopcnt; i++) {
582 const double temp = cool(i);
583 gAdjust(g, temp, pp, grid);
584 }
585 delGrid(grid);
586 } else {
587 for (int i = 0; i < T_loopcnt; i++) {
588 const double temp = cool(i);
589 adjust(g, temp, pp);
590 }
591 }
592
593 if (ctr.x != 0.0 || ctr.y != 0.0) {
594 for (Agnode_t *n = agfstnode(g); n; n = agnxtnode(g, n)) {
595 ND_pos(n)[0] += ctr.x;
596 ND_pos(n)[1] += ctr.y;
597 }
598 }
599 if (reset)
600 reset_params();
601}
#define MIN(a, b)
Definition arith.h:28
#define M_PI
Definition arith.h:41
#define MAX(a, b)
Definition arith.h:33
int late_int(void *obj, attrsym_t *attr, int defaultValue, int minimum)
Definition utils.c:40
double late_double(void *obj, attrsym_t *attr, double defaultValue, double minimum)
Definition utils.c:55
double drand48(void)
Definition utils.c:1550
#define P_SET
Definition const.h:247
#define P_FIX
Definition const.h:248
static float dy
Definition draw.c:43
static float dx
Definition draw.c:42
static const char adjust[]
Definition emit.c:3078
static double dist(int dim, double *x, double *y)
struct fdpParms_s * fdp_parms
Definition globals.c:38
static bool Verbose
Definition gml2gv.c:26
node NULL
Definition grammar.y:181
static int cnt(Dict_t *d, Dtlink_t **set)
Definition graph.c:200
void adjustGrid(Grid *g, int nnodes)
Definition grid.c:170
int gLength(cell *p)
return the number of nodes in a cell
Definition grid.c:238
void delGrid(Grid *g)
close and free all grid resources
Definition grid.c:195
void walkGrid(Grid *g, int(*walkf)(void *, void *))
Definition grid.c:221
void addGrid(Grid *g, int i, int j, Agnode_t *n)
add node n to cell (i,j) in grid g
Definition grid.c:203
cell * findGrid(Grid *g, int i, int j)
Definition grid.c:228
Grid * mkGrid(int cellHint)
Definition grid.c:156
int agnnodes(Agraph_t *g)
Definition graph.c:159
Agsym_t * agattr_text(Agraph_t *g, int kind, char *name, const char *value)
creates or looks up text attributes of a graph
Definition attr.c:333
#define ED_dist(e)
Definition types.h:602
Agedge_t * agfstout(Agraph_t *g, Agnode_t *n)
Definition edge.c:28
#define agtail(e)
Definition cgraph.h:977
Agedge_t * agnxtedge(Agraph_t *g, Agedge_t *e, Agnode_t *n)
Definition edge.c:98
#define ED_factor(e)
Definition types.h:585
#define aghead(e)
Definition cgraph.h:978
Agedge_t * agnxtout(Agraph_t *g, Agedge_t *e)
Definition edge.c:43
Agedge_t * agfstedge(Agraph_t *g, Agnode_t *n)
Definition edge.c:89
void agwarningf(const char *fmt,...)
Definition agerror.c:175
Agnode_t * agnxtnode(Agraph_t *g, Agnode_t *n)
Definition node.c:50
Agnode_t * agfstnode(Agraph_t *g)
Definition node.c:43
#define ND_pinned(n)
Definition types.h:519
#define ND_pos(n)
Definition types.h:520
char * agnameof(void *)
returns a string descriptor for the object.
Definition id.c:145
@ AGRAPH
Definition cgraph.h:207
@ grid
Definition gvgen.c:34
#define hasPos(n)
Definition macros.h:18
#define INIT_SELF
Definition neato.h:28
#define INIT_RANDOM
Definition neato.h:30
int setSeed(graph_t *G, int dflt, long *seedp)
Definition neatoinit.c:921
PATHUTIL_API COORD dist2(Ppoint_t, Ppoint_t)
Definition visibility.c:122
void reset(sgraph *G)
Definition sgraph.c:29
#define alpha
Definition shapes.c:4034
static const double cool
graph or subgraph
Definition cgraph.h:424
Agraph_t * root
subgraphs - ancestors
Definition cgraph.h:433
Definition grid.c:65
Agnode_t * node
Definition grid.h:25
struct _node_list * next
Definition grid.h:26
Definition geom.h:41
pointf UR
Definition geom.h:41
pointf LL
Definition geom.h:41
result of partitioning available space, part of maze
Definition grid.h:33
node_list * nodes
Definition grid.h:35
gridpt p
Definition grid.h:34
double Mlimit
distance beyond which repulsive force is 0
Definition fdp.h:104
int j
Definition grid.h:30
int i
Definition grid.h:30
double Tfact
Definition tlayout.c:66
int numIters
Definition tlayout.c:62
int useGrid
Definition tlayout.c:59
double T0
Definition tlayout.c:68
double Ht
Definition tlayout.c:72
int unscaled
Definition tlayout.c:64
double Cell
Definition tlayout.c:70
int pass1
Definition tlayout.c:73
int loopcnt
Definition tlayout.c:74
double C
Definition tlayout.c:65
double K
Definition tlayout.c:67
long seed
Definition tlayout.c:61
int smode
Definition tlayout.c:69
int useNew
Definition tlayout.c:60
int maxIters
Definition tlayout.c:63
double Wd
Definition tlayout.c:71
double x
Definition geom.h:29
double y
Definition geom.h:29
int loopcnt
Definition xlayout.h:24
int numIters
Definition xlayout.h:20
double T0
Definition xlayout.h:21
double C
Definition xlayout.h:23
double K
Definition xlayout.h:22
static bool init_params(graph_t *g, xparams *xpms)
Definition tlayout.c:115
#define D_unscaled
Definition tlayout.c:49
#define DFLT_maxIters
Definition tlayout.c:97
#define D_C
Definition tlayout.c:50
#define T_C
Definition tlayout.c:85
#define srand48
Definition tlayout.c:40
#define FLOOR(d)
Definition tlayout.c:356
#define T_Wd
Definition tlayout.c:91
static int gridRepulse(void *c, void *g)
Definition tlayout.c:250
#define T_unscaled
Definition tlayout.c:84
#define T_seed
Definition tlayout.c:81
#define T_smode
Definition tlayout.c:89
#define DFLT_smode
Definition tlayout.c:101
void fdp_initParams(graph_t *g)
initialize parameters based on root graph attributes
Definition tlayout.c:153
static void applyAttr(Agnode_t *p, Agnode_t *q, Agedge_t *e)
Definition tlayout.c:286
#define T_maxIters
Definition tlayout.c:83
#define T_pass1
Definition tlayout.c:93
static pointf initPositions(graph_t *g, bport_t *pp)
Definition tlayout.c:413
static void applyRep(Agnode_t *p, Agnode_t *q)
repulsive force = K × K ÷ d or K × K ÷ d × d
Definition tlayout.c:214
#define DFLT_K
Definition tlayout.c:98
static void updatePos(Agraph_t *g, double temp, bport_t *pp)
Definition tlayout.c:311
#define D_useGrid
Definition tlayout.c:46
#define D_K
Definition tlayout.c:52
#define T_Tfact
Definition tlayout.c:86
#define D_T0
Definition tlayout.c:53
#define EXPFACTOR
Definition tlayout.c:96
#define D_numIters
Definition tlayout.c:48
static void doNeighbor(Grid *grid, int i, int j, node_list *nodes)
Definition tlayout.c:222
static void doRep(node_t *p, node_t *q, double xdelta, double ydelta, double dist)
Definition tlayout.c:190
#define DFLT_seed
Definition tlayout.c:100
#define DFLT_Cell
Definition tlayout.c:99
#define T_Cell
Definition tlayout.c:90
#define T_K
Definition tlayout.c:87
#define T_Ht
Definition tlayout.c:92
#define T_useGrid
Definition tlayout.c:79
#define D_Tfact
Definition tlayout.c:51
void fdp_tLayout(graph_t *g, xparams *xpms)
Definition tlayout.c:573
static parms_t parms
Definition tlayout.c:77
#define T_numIters
Definition tlayout.c:82
#define T_T0
Definition tlayout.c:88
#define T_useNew
Definition tlayout.c:80
#define T_loopcnt
Definition tlayout.c:94
#define D_useNew
Definition tlayout.c:47
static void reset_params(void)
Definition tlayout.c:105
static void gAdjust(Agraph_t *g, double temp, bport_t *pp, Grid *grid)
Definition tlayout.c:358
static void clearGrid(grid_t *g)
Definition tvnodes.c:311