|
Graphviz
2.29.20120524.0446
|
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 }
1.7.5