30 #if ((defined(HAVE_GTS) || defined(HAVE_TRIANGLE)) && defined(SFDP))
34 #include "csolve_VPSC.h"
40 static double margin = 0.05;
44 static double incr = 0.05;
47 static int iterations = -1;
48 static int useIter = 0;
52 static Site **endSite;
53 static Point nw, ne, sw, se;
55 static Site **nextSite;
57 static void setBoundBox(
Point * ll,
Point * ur)
72 static void freeNodes(
void)
77 for (i = 0; i <
nsites; i++) {
101 double xmn, xmx, ymn, ymx;
102 double ydelta, xdelta;
115 for (i = 1; i <
nsites; i++) {
134 marg =
agget(graph,
"voro_margin");
135 if (marg && (*marg !=
'\0')) {
138 ydelta = margin * (ymax -
ymin);
139 xdelta = margin * (xmax -
xmin);
140 ll.
x = xmin - xdelta;
141 ll.
y = ymin - ydelta;
142 ur.
x = xmax + xdelta;
143 ur.
y = ymax + ydelta;
145 setBoundBox(&ll, &ur);
151 static int makeInfo(
Agraph_t * graph)
177 for (i = 0; i <
nsites; i++) {
181 if (polyf(&ip->
poly, node, pmargin.
x, pmargin.
y)) {
198 static int scomp(
const void *S1,
const void *S2)
218 static void sortSites(
void)
232 for (i = 0; i <
nsites; i++) {
239 qsort(sites, nsites,
sizeof(
Site *), scomp);
246 static void geomUpdate(
int doSort)
256 for (i = 1; i <
nsites; i++) {
257 if (sites[i]->
coord.
x < xmin)
259 if (sites[i]->
coord.
x > xmax)
263 ymax = sites[nsites - 1]->
coord.
y;
269 static Site *nextOne(
void)
273 if (nextSite < endSite) {
284 static void rmEquality(
void)
295 while (ip < endSite) {
297 if ((jp >= endSite) ||
298 ((*jp)->coord.x != (*ip)->coord.x) ||
299 ((*jp)->coord.y != (*ip)->coord.y)) {
307 while ((kp < endSite) &&
308 ((*kp)->coord.x == (*ip)->coord.x) &&
309 ((*kp)->coord.y == (*ip)->coord.y)) {
316 if ((kp < endSite) && ((*kp)->coord.y == (*ip)->coord.y)) {
317 xdel = ((*kp)->coord.x - (*ip)->coord.x) / cnt;
319 for (jp = ip + 1; jp < kp; jp++) {
320 (*jp)->
coord.
x += i * xdel;
325 for (jp = ip + 1; jp < kp; ip++, jp++) {
330 (*jp)->coord.x = (*ip)->coord.x + xdel / 2;
340 static int countOverlap(
int iter)
347 for (i = 0; i <
nsites; i++)
350 for (i = 0; i < nsites - 1; i++) {
352 for (j = i + 1; j <
nsites; j++) {
365 fprintf(stderr,
"overlap [%d] : %d\n", iter, count);
369 static void increaseBoundBox(
void)
371 double ydelta, xdelta;
379 ydelta = incr * (ur.
y - ll.
y);
380 xdelta = incr * (ur.
x - ll.
x);
387 setBoundBox(&ll, &ur);
399 (a.
x * (b.
y - c.
y) + b.
x * (c.
y - a.
y) +
400 c.
x * (a.
y - b.
y)) / 2);
408 static void centroidOf(
Point a,
Point b,
Point c,
double *x,
double *y)
410 *x = (a.
x + b.
x + c.
x) / 3;
411 *y = (a.
y + b.
y + c.
y) / 3;
420 static void newpos(
Info_t * ip)
424 double totalArea = 0.0;
434 area = areaOf(anchor->
p, p->
p, q->
p);
435 centroidOf(anchor->
p, p->
p, q->
p, &x, &y);
438 totalArea = totalArea + area;
451 static void addCorners(
void)
466 for (i = 1; i <
nsites; i++) {
504 static void newPos(
void)
510 for (i = 0; i <
nsites; i++) {
524 static void cleanup(
void)
532 static int vAdjust(
void)
540 if (!useIter || (iterations > 0))
541 overlapCnt = countOverlap(iterCnt);
543 if ((overlapCnt == 0) || (iterations == 0))
553 if (useIter && (iterCnt == iterations))
555 cnt = countOverlap(iterCnt);
558 if (cnt >= overlapCnt)
585 fprintf(stderr,
"Number of iterations = %d\n", iterCnt);
586 fprintf(stderr,
"Number of increases = %d\n", increaseCnt);
593 static double rePos(
Point c)
597 double f = 1.0 + incr;
599 for (i = 0; i <
nsites; i++) {
609 static int sAdjust(
void)
617 if (!useIter || (iterations > 0))
618 overlapCnt = countOverlap(iterCnt);
620 if ((overlapCnt == 0) || (iterations == 0))
630 if (useIter && (iterCnt == iterations))
632 cnt = countOverlap(iterCnt);
638 fprintf(stderr,
"Number of iterations = %d\n", iterCnt);
647 static void updateGraph(
Agraph_t * graph)
655 for (i = 0; i <
nsites; i++) {
662 #define ELS "|edgelabel|"
663 #define ELSN (sizeof(ELS)-1)
665 #define IS_LNODE(n) (!strncmp(agnameof(n),ELS,ELSN))
674 int i, nedge_nodes = 0;
678 if (elabels &&
IS_LNODE(n)) nedge_nodes++;
685 if (elabels && nedge_nodes) {
686 elabs =
N_GNEW(nedge_nodes,
int);
690 elabs[nedge_nodes++] =
ND_id(n);
693 *n_elabels = nedge_nodes;
746 if (!sym || (sscanf(
agxget(e, sym),
"%lf", &v) != 1))
751 if (sscanf (
agxget (e, symD),
"%lf", &v) != 1) v = 1;
759 val, type,
sizeof(
real));
766 if (valD) free (valD);
771 #if ((defined(HAVE_GTS) || defined(HAVE_TRIANGLE)) && defined(SFDP))
795 for (i = 0; i <
Ndim; i++) {
812 for (i = 0; i <
Ndim; i++) {
835 float** coords =
N_GNEW(dim,
float*);
836 float* f_storage =
N_GNEW(dim * nnodes,
float);
841 for (i = 0; i < dim; i++) {
842 coords[i] = f_storage + i * nnodes;
847 for (i = 0; i < dim; i++) {
848 coords[i][j] = (float) (
ND_pos(v)[i]);
858 opt.clusters =
NEW(cluster_data);
870 removeoverlaps(nnodes, coords, &opt);
874 for (i = 0; i < dim; i++) {
875 ND_pos(v)[i] = coords[i][j];
894 angleSet (
graph_t* g,
double* phi)
898 char* a =
agget(g,
"normalize");
900 if (!a || (*a ==
'\0'))
902 ang = strtod (a, &p);
909 while (ang > 180) ang -= 360;
910 while (ang <= -180) ang += 360;
931 if (!angleSet(g, &phi))
941 if (p.
x || p.
y) ret = 1;
963 ND_pos(v)[0] = p.
x * cosv - p.
y * sinv + orig.
x;
964 ND_pos(v)[1] = p.
x * sinv + p.
y * cosv + orig.
y;
978 #define STRLEN(s) ((sizeof(s)-1)/sizeof(char))
979 #define ITEM(i,s,v) {i, s, STRLEN(s), v}
987 #if ((defined(HAVE_GTS) || defined(HAVE_TRIANGLE)) && defined(SFDP))
1005 #if !((defined(HAVE_GTS) || defined(HAVE_TRIANGLE)) && defined(SFDP))
1020 if ((sscanf (s,
"%d", &v) > 0) && (v >= 0))
1034 if ((s ==
NULL) || (*s ==
'\0')) {
1043 ap = &adjustMode[1];
1048 setPrismValues (g, s + ap->
len, dp);
1056 agerr (
AGWARN,
"Unrecognized overlap value \"%s\" - using false\n", s);
1068 setPrismValues (g,
"", dp);
1072 fprintf(stderr,
"overlap: %s value %d scaling %.04f\n", dp->
print, dp->
value, dp->
scaling);
1079 char* am =
agget(G,
"overlap");
1080 return (getAdjustMode (G, am ? am : (dflt ? dflt :
""), dp));
1083 #define ISZERO(d) ((fabs(d) < 0.000000001))
1087 static int simpleScale (
graph_t* g)
1094 if ((p =
agget(g,
"scale"))) {
1095 if ((i = sscanf(p,
"%lf,%lf", &sc.
x, &sc.
y))) {
1097 if (i == 1) sc.
y = sc.
x;
1098 else if (
ISZERO(sc.
y))
return 0;
1099 if ((sc.
y == 1) && (sc.
x == 1))
return 0;
1101 fprintf (stderr,
"scale = (%.03f,%.03f)\n", sc.
x, sc.
y);
1126 nret += simpleScale (G);
1132 fprintf(stderr,
"Adjusting %s using %s\n",
agnameof(G), am->
print);
1165 #if ((defined(HAVE_GTS) || defined(HAVE_TRIANGLE)) && defined(SFDP))
1175 ret = vpscAdjust(G);
1227 getAdjustMode(G, flag, &am);
1247 parseFactor (
char* s,
expand_t* pp,
float sepfact,
float dflt)
1252 while (isspace(*s)) s++;
1259 if ((i = sscanf(s,
"%f,%f", &x, &y))) {
1263 pp->
x =
MIN(dflt,x/sepfact);
1264 pp->
y =
MIN(dflt,y/sepfact);
1266 else if (sepfact < 1) {
1267 pp->
x =
MAX(dflt,x/sepfact);
1268 pp->
y =
MAX(dflt,y/sepfact);
1276 pp->
x = 1.0 + x/sepfact;
1277 pp->
y = 1.0 + y/sepfact;
1292 if ((marg =
agget(g,
"sep")) && parseFactor(marg, &pmargin, 1.0, 0)) {
1301 fprintf (stderr,
"Node separation: add=%d (%f,%f)\n",
1302 pmargin.
doAdd, pmargin.
x, pmargin.
y);
1318 if ((marg =
agget(g,
"esep")) && parseFactor(marg, &pmargin, 1.0, 0)) {
1327 fprintf (stderr,
"Edge separation: add=%d (%f,%f)\n",
1328 pmargin.
doAdd, pmargin.
x, pmargin.
y);
void s1(graph_t *, node_t *)
int fdpAdjust(graph_t *g)
expand_t sepFactor(graph_t *g)
SparseMatrix makeMatrix(Agraph_t *g, int dim, SparseMatrix *D)
void voronoi(int triangulate, Site *(*nextsite)(void))
int makeAddPoly(Poly *pp, Agnode_t *n, float xmargin, float ymargin)
int cAdjust(graph_t *, int)
SparseMatrix SparseMatrix_remove_diagonal(SparseMatrix A)
int agerr(agerrlevel_t level, const char *fmt,...)
CGRAPH_API Agedge_t * agfstout(Agraph_t *g, Agnode_t *n)
int scAdjust(graph_t *, int)
void addVertex(Site *s, double x, double y)
int SparseMatrix_is_symmetric(SparseMatrix A, int test_pattern_symmetry_only)
#define PS2INCH(a_points)
char * agget(void *obj, char *name)
CGRAPH_API Agnode_t * agtail(Agedge_t *e)
int removeOverlapAs(graph_t *G, char *flag)
int normalize(graph_t *g)
CGRAPH_API Agnode_t * agnxtnode(Agraph_t *g, Agnode_t *n)
adjust_data * graphAdjustMode(graph_t *G, adjust_data *dp, char *dflt)
CGRAPH_API Agnode_t * aghead(Agedge_t *e)
int strncasecmp(const char *s1, const char *s2, unsigned int n)
CGRAPH_API char * agnameof(void *)
SparseMatrix SparseMatrix_get_real_adjacency_matrix_symmetrized(SparseMatrix A)
#define agfindedgeattr(g, a)
int makePoly(Poly *pp, Agnode_t *n, float xmargin, float ymargin)
int adjustNodes(graph_t *G)
int removeOverlapWith(graph_t *G, adjust_data *am)
expand_t esepFactor(graph_t *g)
boolean mapBool(char *p, boolean dflt)
CGRAPH_API Agnode_t * agfstnode(Agraph_t *g)
double dist_2(Point *pp, Point *qp)
void SparseMatrix_delete(SparseMatrix A)
Agraph_t * graph(char *name)
#define agfindgraphattr(g, a)
SparseMatrix SparseMatrix_from_coordinate_arrays(int nz, int m, int n, int *irn, int *jcn, void *val0, int type, size_t sz)
double late_double(void *obj, attrsym_t *attr, double def, double low)
EXTERN unsigned char Verbose
CGRAPH_API int agnnodes(Agraph_t *g)
Agnode_t * node(Agraph_t *g, char *name)
int polyOverlap(Point p, Poly *pp, Point q, Poly *qp)
CGRAPH_API int agnedges(Agraph_t *g)
double * getSizes(Agraph_t *g, pointf pad, int *n_elabels, int **elabels)
char * agxget(void *obj, Agsym_t *sym)
CGRAPH_API Agedge_t * agnxtout(Agraph_t *g, Agedge_t *e)
void remove_overlap(int dim, SparseMatrix A, int m, real *x, real *label_sizes, int ntry, real initial_scaling, int do_shrinking, int *flag)