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