~ubuntu-branches/ubuntu/lucid/graphviz/lucid-security

« back to all changes in this revision

Viewing changes to fdp/adjust.c

  • Committer: Bazaar Package Importer
  • Author(s): Stephen M Moraco
  • Date: 2002-02-05 18:52:12 UTC
  • Revision ID: james.westby@ubuntu.com-20020205185212-8i04c70te00rc40y
Tags: upstream-1.7.16
ImportĀ upstreamĀ versionĀ 1.7.16

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* adjust.c
 
2
 */
 
3
#include "adjust.h"
 
4
#include "grid.h"
 
5
#include "structs.h"
 
6
#include "exprval.h"
 
7
#include "options.h"
 
8
#include "component.h"
 
9
#include "macros.h"
 
10
#include <math.h>
 
11
#include <assert.h>
 
12
 
 
13
#ifdef DMALLOC
 
14
#include "dmalloc.h"
 
15
#endif
 
16
 
 
17
static void
 
18
doRep (fdp_data* p, fdp_data* q, double xdelta, double ydelta, double dist2)
 
19
{
 
20
    double    force;
 
21
 
 
22
    while (dist2 == 0.0) {
 
23
      xdelta = 5 - rand()%10;
 
24
      ydelta = 5 - rand()%10;
 
25
      dist2 = xdelta*xdelta + ydelta*ydelta;
 
26
    }
 
27
    force = K2/dist2;
 
28
    q->disp.x += xdelta * force;
 
29
    q->disp.y += ydelta * force;
 
30
    p->disp.x -= xdelta * force;
 
31
    p->disp.y -= ydelta * force;
 
32
}
 
33
 
 
34
static void 
 
35
applyRep (fdp_data* p, fdp_data* q)
 
36
{
 
37
    double    xdelta, ydelta;
 
38
 
 
39
    xdelta = q->pos.x - p->pos.x;
 
40
    ydelta = q->pos.y - p->pos.y;
 
41
    doRep (p, q, xdelta, ydelta, xdelta*xdelta + ydelta*ydelta);
 
42
}
 
43
 
 
44
static void 
 
45
applyAttr (fdp_data* p, fdp_data* q)
 
46
{
 
47
    double    xdelta, ydelta;
 
48
    double    force;
 
49
    double    dist;
 
50
    double    dist2;
 
51
 
 
52
    xdelta = q->pos.x - p->pos.x;
 
53
    ydelta = q->pos.y - p->pos.y;
 
54
    dist2 = xdelta*xdelta + ydelta*ydelta;
 
55
    dist = sqrt (dist2);
 
56
    force = dist/K;
 
57
    q->disp.x -= xdelta * force;
 
58
    q->disp.y -= ydelta * force;
 
59
    p->disp.x += xdelta * force;
 
60
    p->disp.y += ydelta * force;
 
61
}
 
62
 
 
63
static void
 
64
doNeighbor (Grid* grid, int i, int j, node_list* nodes)
 
65
{
 
66
    cell*         cellp = findGrid (grid, i, j);
 
67
    node_list*    p;
 
68
    node_list*    q;
 
69
    fdp_data*     datap;
 
70
    fdp_data*     dataq;
 
71
    double        xdelta, ydelta;
 
72
    double        dist2;
 
73
 
 
74
    if (cellp) {
 
75
      if (Verbose >= 3)
 
76
        fprintf (stderr, "  doNeighbor (%d,%d) : %d\n", i, j, length (cellp));
 
77
      for (p = nodes; p != 0; p = p->next) {
 
78
        datap = getData (p->node);
 
79
        for (q = cellp->nodes; q != 0; q = q->next) {
 
80
#ifndef CONN_COMP
 
81
          if (UseComp && !sameComponent (p->node,q->node)) continue;
 
82
#else
 
83
          if (!sameComponent (p->node,q->node)) continue;
 
84
#endif
 
85
          dataq = getData (q->node);
 
86
          xdelta = dataq->pos.x - datap->pos.x;
 
87
          ydelta = dataq->pos.y - datap->pos.y;
 
88
          dist2 = xdelta*xdelta + ydelta*ydelta;
 
89
          if (dist2 < Radius2)
 
90
            doRep (datap, dataq, xdelta, ydelta, dist2);
 
91
        }
 
92
      }
 
93
    }
 
94
}
 
95
 
 
96
static int
 
97
gridRepulse (Dt_t* dt, void* v, void* g)
 
98
{
 
99
    cell*         cellp = (cell*)v;
 
100
    Grid*         grid = (Grid*)g;
 
101
    node_list*    nodes = cellp->nodes;
 
102
    int           i = cellp->p.i;
 
103
    int           j = cellp->p.j;
 
104
    node_list*    p;
 
105
    node_list*    q;
 
106
    fdp_data*     data;
 
107
 
 
108
    NOTUSED (dt);
 
109
    if (Verbose >= 3) 
 
110
      fprintf (stderr, "gridRepulse (%d,%d) : %d\n", i, j, length (cellp));
 
111
    for (p = nodes; p != 0; p = p->next) {
 
112
      data = getData (p->node);
 
113
      for (q = nodes; q != 0; q = q->next)
 
114
#ifndef CONN_COMP
 
115
        if ((p != q) && (!UseComp || sameComponent (p->node,q->node)))
 
116
#else
 
117
        if ((p != q) && sameComponent (p->node,q->node))
 
118
#endif
 
119
          applyRep (data, getData (q->node));
 
120
    }
 
121
 
 
122
    doNeighbor(grid, i - 1, j - 1, nodes);
 
123
    doNeighbor(grid, i - 1, j    , nodes);
 
124
    doNeighbor(grid, i - 1, j + 1, nodes);
 
125
    doNeighbor(grid, i    , j - 1, nodes);
 
126
    doNeighbor(grid, i    , j + 1, nodes);
 
127
    doNeighbor(grid, i + 1, j - 1, nodes);
 
128
    doNeighbor(grid, i + 1, j    , nodes);
 
129
    doNeighbor(grid, i + 1, j + 1, nodes);
 
130
 
 
131
    return 0;
 
132
}
 
133
 
 
134
void 
 
135
adjust (Agraph_t* g, double temp)
 
136
{
 
137
    fdp_data*    data;
 
138
    Agnode_t*    n;
 
139
    Agnode_t*    n1;
 
140
    Agedge_t*    e;
 
141
    double       temp2;
 
142
    double       len;
 
143
    double       len2;
 
144
    pointf       disp;
 
145
    static Grid* grid = 0;
 
146
 
 
147
    if (temp <= 0.0) return;
 
148
 
 
149
    if (UseGrid) {
 
150
      int nnodes = agnnodes(g);
 
151
      grid = resetGrid (nnodes, nnodes, grid);
 
152
    }
 
153
 
 
154
    for (n = agfstnode(g); n; n = agnxtnode(n)) {
 
155
      data = getData (n);
 
156
      data->disp.x = data->disp.y = 0;
 
157
      if (UseGrid)
 
158
        addGrid (grid, (int)floor(data->pos.x/CellW), (int)floor(data->pos.y/CellH), n);
 
159
    }
 
160
 
 
161
    if (UseGrid) {
 
162
      for (n = agfstnode(g); n; n = agnxtnode(n)) {
 
163
        data = getData (n);
 
164
        for (e = agfstout(n); e; e = agnxtout(e)) 
 
165
          applyAttr (data, getData (aghead(e)));
 
166
      }
 
167
      walkGrid (grid, gridRepulse);
 
168
    }
 
169
    else {
 
170
      for (n = agfstnode(g); n; n = agnxtnode(n)) {
 
171
        data = getData (n);
 
172
        for (n1 = agnxtnode(n); n1; n1 = agnxtnode(n1)) {
 
173
#ifndef CONN_COMP
 
174
          if (!UseComp || sameComponent (n,n1))
 
175
#else
 
176
          if (sameComponent (n,n1))
 
177
#endif
 
178
            applyRep (data, getData(n1));
 
179
        }
 
180
        for (e = agfstout(n); e; e = agnxtout(e)) {
 
181
          applyAttr (data, getData(aghead(e)));
 
182
        }
 
183
      }
 
184
    }
 
185
 
 
186
    temp2 = temp * temp;
 
187
    for (n = agfstnode(g); n; n = agnxtnode(n)) {
 
188
      data = getData (n);
 
189
      if (data->fixed) continue;
 
190
      disp = data->disp;
 
191
      len2 = disp.x*disp.x + disp.y*disp.y;
 
192
 
 
193
      if (len2 < temp2) {
 
194
        data->pos.x += disp.x;
 
195
        data->pos.y += disp.y;
 
196
      }
 
197
      else {
 
198
        /* to avoid sqrt, consider abs(x) + abs(y) */
 
199
        len = sqrt (len2);
 
200
        data->pos.x += (disp.x * temp)/len;
 
201
        data->pos.y += (disp.y * temp)/len;
 
202
      }
 
203
 
 
204
      /* Keep withing box */
 
205
/*
 
206
      if (data->pos.x < 0) data->pos.x = 0;
 
207
      else if (data->pos.x > Width) data->pos.x = Width;
 
208
      if (data->pos.y < 0) data->pos.y = 0;
 
209
      else if (data->pos.y > Height) data->pos.y = Height;
 
210
*/
 
211
    }
 
212
    
 
213
}