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