27#if ((defined(HAVE_GTS) || defined(HAVE_TRIANGLE)) && defined(SFDP))
44static const double incr = 0.05;
69 for (
size_t i = 0; i <
nsites; i++) {
89 double x_min = DBL_MAX;
90 double y_min = DBL_MAX;
91 double x_max = -DBL_MAX;
92 double y_max = -DBL_MAX;
94 for (
size_t i = 0; i <
nsites; ++i) {
99 x_min = fmin(x_min, pp->
origin.
x + x);
100 y_min = fmin(y_min, pp->
origin.
y + y);
101 x_max = fmax(x_max, pp->
corner.
x + x);
102 y_max = fmax(y_max, pp->
corner.
y + y);
108 const double margin = (marg && *marg !=
'\0') ? atof(marg) : 0.05;
109 double ydelta = margin * (y_max - y_min);
110 double xdelta = margin * (x_max - x_min);
111 ll.
x = x_min - xdelta;
112 ll.
y = y_min - ydelta;
113 ur.
x = x_max + xdelta;
114 ur.
y = y_max + ydelta;
142 for (
size_t i = 0; i <
nsites; i++) {
147 if (polyf(&ip->
poly,
node, pmargin.
x, pmargin.
y)) {
164static int scomp(
const void *S1,
const void *S2)
167 const Site *s2 = *(
Site *
const *)S2;
186 for (
size_t i = 0; i <
nsites; i++) {
209 for (
size_t i = 0; i <
nsites; ++i) {
234 (*jp)->
coord.
x != (*ip)->coord.x ||
235 (*jp)->coord.y != (*ip)->coord.y) {
243 while (kp < st->endSite &&
244 (*kp)->coord.x == (*ip)->coord.x &&
245 (*kp)->coord.y == (*ip)->coord.y) {
252 if (kp < st->endSite && (*kp)->coord.y == (*ip)->coord.y) {
253 const double xdel = ((*kp)->coord.x - (*ip)->coord.x) /
cnt;
255 for (jp = ip + 1; jp < kp; jp++) {
256 (*jp)->
coord.
x += i * xdel;
261 for (jp = ip + 1; jp < kp; ip++, jp++) {
263 double xdel =
info->poly.corner.x -
info->poly.origin.x;
265 xdel +=
info->poly.corner.x -
info->poly.origin.x;
266 (*jp)->coord.x = (*ip)->coord.x + xdel / 2;
277 for (
size_t i = 0; i <
nsites; i++)
280 for (
size_t i = 0; i <
nsites - 1; i++) {
282 for (
size_t j = i + 1; j <
nsites; j++) {
293 fprintf(stderr,
"overlap [%u] : %u\n", iter, count);
301 const double ydelta =
incr * (ur.
y - ll.
y);
302 const double xdelta =
incr * (ur.
x - ll.
x);
315 return fabs(a.
x * (b.
y - c.
y) + b.
x * (c.
y - a.
y) + c.
x * (a.
y - b.
y)) / 2;
323 *x = (a.
x + b.
x + c.
x) / 3;
324 *y = (a.
y + b.
y + c.
y) / 3;
333 double totalArea = 0.0;
339 for (
size_t i = 1; i + 1 < ip->
n_verts; ++i) {
342 const double area =
areaOf(anchor, p, q);
367 for (
size_t i = 1; i <
nsites; i++) {
409 for (
size_t i = 0; i <
nsites; i++) {
430 unsigned iterCnt = 0;
431 unsigned badLevel = 0;
432 unsigned increaseCnt = 0;
442 for (
bool doAll =
false;;) {
449 if (
cnt >= overlapCnt)
471 fprintf(stderr,
"Number of iterations = %u\n", iterCnt);
472 fprintf(stderr,
"Number of increases = %u\n", increaseCnt);
480 double f = 1.0 +
incr;
482 for (
size_t i = 0; i <
nsites; i++) {
490 unsigned iterCnt = 0;
508 fprintf(stderr,
"Number of iterations = %u\n", iterCnt);
517 for (
size_t i = 0; i <
nsites; i++) {
524#define ELS "|edgelabel|"
526#define IS_LNODE(n) startswith(agnameof(n), ELS)
535 if (elabels &&
IS_LNODE(n)) nedge_nodes++;
537 const int i =
ND_id(n);
542 if (elabels && nedge_nodes) {
543 int* elabs =
gv_calloc(nedge_nodes,
sizeof(
int));
547 elabs[nedge_nodes++] =
ND_id(n);
550 *n_elabels = nedge_nodes;
583 if (!sym || sscanf(
agxget(e, sym),
"%lf", &v) != 1)
603#if ((defined(HAVE_GTS) || defined(HAVE_TRIANGLE)) && defined(SFDP))
622 for (
int i = 0; i <
Ndim; i++) {
639 for (
int i = 0; i <
Ndim; i++) {
661 float *f_storage =
gv_calloc(
dim * nnodes,
sizeof(
float));
663 for (
size_t i = 0; i <
dim; i++) {
664 coords[i] = f_storage + i * nnodes;
669 for (
size_t i = 0; i <
dim; i++) {
670 coords[i][j] = (float)
ND_pos(v)[i];
680 opt.clusters = (cluster_data){0};
683 if (exp_margin.
doAdd) {
684 opt.gap.x = 2.0*
PS2INCH(exp_margin.
x);
685 opt.gap.y = 2.0*
PS2INCH(exp_margin.
y);
692 removeoverlaps(nnodes, coords, &opt);
696 for (
size_t i = 0; i <
dim; i++) {
697 ND_pos(v)[i] = coords[i][j];
716 char* a =
agget(g,
"normalize");
718 if (!a || *a ==
'\0')
720 double ang = strtod (a, &p);
727 while (ang > 180) ang -= 360;
728 while (ang <= -180) ang += 360;
753 if (p.
x || p.
y) ret = 1;
770 const double cosv = cos(phi);
771 const double sinv = sin(phi);
775 ND_pos(v)[0] = p.
x * cosv - p.
y * sinv + orig.
x;
776 ND_pos(v)[1] = p.
x * sinv + p.
y * cosv + orig.
y;
795#if ((defined(HAVE_GTS) || defined(HAVE_TRIANGLE)) && defined(SFDP))
798 {
AM_VOR,
"voronoi",
"Voronoi"},
803 {
AM_SCALE,
"oscale",
"old scaling"},
805 {
AM_ORTHO,
"ortho",
"orthogonal constraints"},
806 {
AM_ORTHO_YX,
"ortho_yx",
"orthogonal constraints"},
807 {
AM_ORTHOXY,
"orthoxy",
"xy orthogonal constraints"},
808 {
AM_ORTHOYX,
"orthoyx",
"yx orthogonal constraints"},
809 {
AM_PORTHO,
"portho",
"pseudo-orthogonal constraints"},
810 {
AM_PORTHO_YX,
"portho_yx",
"pseudo-orthogonal constraints"},
811 {
AM_PORTHOXY,
"porthoxy",
"xy pseudo-orthogonal constraints"},
812 {
AM_PORTHOYX,
"porthoyx",
"yx pseudo-orthogonal constraints"},
813#if !((defined(HAVE_GTS) || defined(HAVE_TRIANGLE)) && defined(SFDP))
823 if (sscanf (
s,
"%d", &v) > 0 && v >= 0)
833 if (
s ==
NULL || *
s ==
'\0') {
839 bool matches = strcasecmp(
s, ap->
attrib) == 0;
858 bool unmappable = v !=
mapBool(
s,
true);
860 agwarningf(
"Unrecognized overlap value \"%s\" - using false\n",
s);
876 fprintf(stderr,
"overlap: %s value %d scaling %.04f\n", dp->
print, dp->
value, dp->
scaling);
881 char* am =
agget(
G,
"overlap");
885#define ISZERO(d) (fabs(d) < 0.000000001)
893 if ((p =
agget(g,
"scale"))) {
894 if ((i = sscanf(p,
"%lf,%lf", &sc.
x, &sc.
y))) {
896 if (i == 1) sc.
y = sc.
x;
897 else if (
ISZERO(sc.
y))
return 0;
898 if (sc.
y == 1 && sc.
x == 1)
return 0;
900 fprintf (stderr,
"scale = (%.03f,%.03f)\n", sc.
x, sc.
y);
930 fprintf(stderr,
"Adjusting %s using %s\n",
agnameof(
G), am->
print);
960#if ((defined(HAVE_GTS) || defined(HAVE_TRIANGLE)) && defined(SFDP))
1040 else pp->
doAdd =
false;
1043 if ((i = sscanf(
s,
"%lf,%lf", &x, &y))) {
1047 pp->
x = fmin(dflt, x / sepfact);
1048 pp->
y = fmin(dflt, y / sepfact);
1050 else if (sepfact < 1) {
1051 pp->
x = fmax(dflt, x / sepfact);
1052 pp->
y = fmax(dflt, y / sepfact);
1060 pp->
x = 1.0 + x / sepfact;
1061 pp->
y = 1.0 + y / sepfact;
1080 pmargin.
doAdd =
true;
1083 fprintf (stderr,
"Node separation: add=%d (%f,%f)\n",
1084 pmargin.
doAdd, pmargin.
x, pmargin.
y);
1101 else if ((marg =
agget(g,
"sep")) &&
1106 pmargin.
doAdd =
true;
1109 fprintf (stderr,
"Edge separation: add=%d (%f,%f)\n",
1110 pmargin.
doAdd, pmargin.
x, pmargin.
y);
bool SparseMatrix_is_symmetric(SparseMatrix A, bool test_pattern_symmetry_only)
SparseMatrix SparseMatrix_from_coordinate_arrays(int nz, int m, int n, int *irn, int *jcn, void *val0, int type, size_t sz)
void SparseMatrix_delete(SparseMatrix A)
SparseMatrix SparseMatrix_get_real_adjacency_matrix_symmetrized(SparseMatrix A)
SparseMatrix SparseMatrix_remove_diagonal(SparseMatrix A)
static unsigned countOverlap(unsigned iter)
Count number of node-node overlaps at iteration iter.
static void newpos(Info_t *ip)
static int sAdjust(state_t *st)
static void sortSites(state_t *st)
Fill array of pointer to sites and sort the sites using scomp.
static void newPos(const state_t *st, bool doAll)
static void updateGraph(void)
Enter new node positions into the graph.
expand_t esepFactor(graph_t *g)
static void centroidOf(Point a, Point b, Point c, double *x, double *y)
static void chkBoundBox(state_t *st, Agraph_t *graph)
static void freeNodes(void)
Free node resources.
SparseMatrix makeMatrix(Agraph_t *g)
static void setBoundBox(state_t *st, Point *ll, Point *ur)
expand_t sepFactor(graph_t *g)
static void getAdjustMode(Agraph_t *g, const char *s, adjust_data *dp)
Convert string value to internal value of adjustment mode.
static const lookup_t adjustMode[]
int removeOverlapAs(graph_t *G, char *flag)
Use flag value to determine if and how to remove node overlaps.
double * getSizes(Agraph_t *g, pointf pad, int *n_elabels, int **elabels)
Set up array of half sizes in inches.
static void cleanup(void)
static int parseFactor(char *s, expand_t *pp, double sepfact, double dflt)
static int scomp(const void *S1, const void *S2)
static double areaOf(Point a, Point b, Point c)
Area of triangle whose vertices are a,b,c.
static Site * nextOne(void *state)
static void rmEquality(state_t *st)
Check for nodes with identical positions and tweak the positions.
static int makeInfo(Agraph_t *graph)
For each node in the graph, create a Info data structure.
static int vAdjust(state_t *st)
static void geomUpdate(state_t *st, int doSort)
int adjustNodes(graph_t *G)
int normalize(graph_t *g)
static void increaseBoundBox(state_t *st)
static void addCorners(const state_t *st)
static int angleSet(graph_t *g, double *phi)
static int simpleScale(graph_t *g)
static void setPrismValues(Agraph_t *g, const char *s, adjust_data *dp)
Initialize and set prism values.
void graphAdjustMode(graph_t *G, adjust_data *dp, char *dflt)
int removeOverlapWith(graph_t *G, adjust_data *am)
int cAdjust(graph_t *, int)
int scAdjust(graph_t *, int)
Memory allocation wrappers that exit on failure.
static void * gv_calloc(size_t nmemb, size_t size)
bool mapbool(const char *p)
double late_double(void *obj, attrsym_t *attr, double defaultValue, double minimum)
bool mapBool(const char *p, bool defaultValue)
static int overlaps(nitem *p, int cnt)
#define PS2INCH(a_points)
double dist_2(Point pp, Point qp)
distance squared between two points
static int cnt(Dict_t *d, Dtlink_t **set)
int agnedges(Agraph_t *g)
int agnnodes(Agraph_t *g)
char * agget(void *obj, char *name)
char * agxget(void *obj, Agsym_t *sym)
#define agfindedgeattr(g, a)
Agedge_t * agfstout(Agraph_t *g, Agnode_t *n)
Agedge_t * agnxtout(Agraph_t *g, Agedge_t *e)
void agwarningf(const char *fmt,...)
#define agfindgraphattr(g, a)
Agnode_t * agnxtnode(Agraph_t *g, Agnode_t *n)
Agnode_t * agfstnode(Agraph_t *g)
char * agnameof(void *)
returns a string descriptor for the object.
Agraph_t * graph(char *name)
replacements for ctype.h functions
static bool gv_isspace(int c)
Info_t * nodeInfo
array of node info
void addVertex(Site *s, double x, double y)
insert vertex into sorted list
NEATOPROCS_API void s1(graph_t *, node_t *)
void remove_overlap(int dim, SparseMatrix A, double *x, double *label_sizes, int ntry, double initial_scaling, int edge_labeling_scheme, int n_constr_nodes, int *constr_nodes, SparseMatrix A_constr, bool do_shrinking)
int polyOverlap(Point p, Poly *pp, Point q, Poly *qp)
int makePoly(Poly *pp, Agnode_t *n, double xmargin, double ymargin)
int makeAddPoly(Poly *pp, Agnode_t *n, double xmargin, double ymargin)
static int nedges
total no. of edges used in routing
int fdpAdjust(graph_t *g)
platform abstraction for case-insensitive string functions
size_t n_verts
number of elements in verts
Point * verts
sorted list of vertices of voronoi polygon
bool overlaps
true if node overlaps other nodes
Agnode_t * node
libgraph node
Site site
site used by voronoi code
information the ID allocator needs to do its job
Site ** sites
array of pointers to sites; used in qsort
Site ** endSite
sentinel on sites array
Point se
corners of clipping window
void voronoi(Site *(*nextsite)(void *context), void *context)