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