Graphviz  2.29.20120524.0446
lib/neatogen/info.c
Go to the documentation of this file.
00001 /* $Id$ $Revision$ */
00002 /* vim:set shiftwidth=4 ts=8: */
00003 
00004 /*************************************************************************
00005  * Copyright (c) 2011 AT&T Intellectual Property 
00006  * All rights reserved. This program and the accompanying materials
00007  * are made available under the terms of the Eclipse Public License v1.0
00008  * which accompanies this distribution, and is available at
00009  * http://www.eclipse.org/legal/epl-v10.html
00010  *
00011  * Contributors: See CVS logs. Details at http://www.graphviz.org/
00012  *************************************************************************/
00013 
00014 #include "neato.h"
00015 #include <stdio.h>
00016 #include "mem.h"
00017 #include "info.h"
00018 
00019 
00020 Info_t *nodeInfo;               /* Array of node info */
00021 static Freelist pfl;
00022 
00023 void infoinit()
00024 {
00025     freeinit(&pfl, sizeof(PtItem));
00026 }
00027 
00028 /* compare:
00029  * returns -1 if p < q
00030  *          0 if p = q
00031  *          1 if p > q
00032  * if q if NULL, returns -1
00033  * Ordering is by angle from -pi/2 to 3pi/4.
00034  * For equal angles (which should not happen in our context)
00035  * ordering is by closeness to origin.
00036  */
00037 static int compare(Point * o, PtItem * p, PtItem * q)
00038 {
00039     double x0;
00040     double y0;
00041     double x1;
00042     double y1;
00043     double a, b;
00044 
00045     if (q == NULL)
00046         return -1;
00047     if ((p->p.x == q->p.x) && (p->p.y == q->p.y))
00048         return 0;
00049 
00050     x0 = ((double) (p->p.x)) - ((double) (o->x));
00051     y0 = ((double) (p->p.y)) - ((double) (o->y));
00052     x1 = ((double) (q->p.x)) - ((double) (o->x));
00053     y1 = ((double) (q->p.y)) - ((double) (o->y));
00054     if (x0 >= 0.0) {
00055         if (x1 < 0.0)
00056             return -1;
00057         else if (x0 > 0.0) {
00058             if (x1 > 0.0) {
00059                 a = y1 / x1;
00060                 b = y0 / x0;
00061                 if (b < a)
00062                     return -1;
00063                 else if (b > a)
00064                     return 1;
00065                 else if (x0 < x1)
00066                     return -1;
00067                 else
00068                     return 1;
00069             } else {            /* x1 == 0.0 */
00070                 if (y1 > 0.0)
00071                     return -1;
00072                 else
00073                     return 1;
00074             }
00075         } else {                /* x0 == 0.0 */
00076             if (x1 > 0.0) {
00077                 if (y0 <= 0.0)
00078                     return -1;
00079                 else
00080                     return 1;
00081             } else {            /* x1 == 0.0 */
00082                 if (y0 < y1) {
00083                     if (y1 <= 0.0)
00084                         return 1;
00085                     else
00086                         return -1;
00087                 } else {
00088                     if (y0 <= 0.0)
00089                         return -1;
00090                     else
00091                         return 1;
00092                 }
00093             }
00094         }
00095     } else {
00096         if (x1 >= 0.0)
00097             return 1;
00098         else {
00099             a = y1 / x1;
00100             b = y0 / x0;
00101             if (b < a)
00102                 return -1;
00103             else if (b > a)
00104                 return 1;
00105             else if (x0 > x1)
00106                 return -1;
00107             else
00108                 return 1;
00109         }
00110     }
00111 }
00112 
00113 #if 0                           /* not used */
00114 static void printV(PtItem * vp)
00115 {
00116     if (vp == NULL) {
00117         fprintf(stderr, "<empty>\n");
00118         return;
00119     }
00120 
00121     while (vp != NULL) {
00122         fprintf(stderr, "(%.16f,%.16f)\n", vp->p.x, vp->p.y);
00123         vp = vp->next;
00124     }
00125 }
00126 
00127 static void error(Info_t * ip, Site * s, double x, double y)
00128 {
00129     fprintf(stderr,
00130             "Unsorted vertex list for site %d (%.16f,%.16f), pt (%f,%f)\n",
00131             s->sitenbr, s->coord.x, s->coord.y, x, y);
00132     printV(ip->verts);
00133 }
00134 #endif
00135 
00136 #if 0                           /* not used */
00137 static int sorted(Point * origin, PtItem * vp)
00138 {
00139     PtItem *next;
00140 
00141     if (vp == NULL)
00142         return 1;
00143     next = vp->next;
00144 
00145     while (next != NULL) {
00146         if (compare(origin, vp, next) <= 0) {
00147             vp = next;
00148             next = next->next;
00149         } else {
00150             fprintf(stderr, "(%.16f,%.16f) > (%.16f,%.16f)\n",
00151                     vp->p.x, vp->p.y, next->p.x, next->p.y);
00152             return 0;
00153         }
00154     }
00155 
00156     return 1;
00157 
00158 }
00159 #endif
00160 
00161 void addVertex(Site * s, double x, double y)
00162 {
00163     Info_t *ip;
00164     PtItem *p;
00165     PtItem *curr;
00166     PtItem *prev;
00167     Point *origin = &(s->coord);
00168     PtItem tmp;
00169     int cmp;
00170 
00171     ip = nodeInfo + (s->sitenbr);
00172     curr = ip->verts;
00173 
00174     tmp.p.x = x;
00175     tmp.p.y = y;
00176 
00177     cmp = compare(origin, &tmp, curr);
00178     if (cmp == 0)
00179         return;
00180     else if (cmp < 0) {
00181         p = (PtItem *) getfree(&pfl);
00182         p->p.x = x;
00183         p->p.y = y;
00184         p->next = curr;
00185         ip->verts = p;
00186         return;
00187     }
00188 
00189     prev = curr;
00190     curr = curr->next;
00191     while ((cmp = compare(origin, &tmp, curr)) > 0) {
00192         prev = curr;
00193         curr = curr->next;
00194     }
00195     if (cmp == 0)
00196         return;
00197     p = (PtItem *) getfree(&pfl);
00198     p->p.x = x;
00199     p->p.y = y;
00200     prev->next = p;
00201     p->next = curr;
00202 
00203     /* This test should be unnecessary */
00204     /* if (!sorted(origin,ip->verts))  */
00205     /* error (ip,s,x,y); */
00206 
00207 }