|
Graphviz
2.29.20120523.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 "mem.h" 00016 #include "info.h" 00017 #include "edges.h" 00018 #include <math.h> 00019 00020 00021 double pxmin, pxmax, pymin, pymax; /* clipping window */ 00022 00023 static int nedges; 00024 static Freelist efl; 00025 00026 void edgeinit() 00027 { 00028 freeinit(&efl, sizeof(Edge)); 00029 nedges = 0; 00030 } 00031 00032 Edge *bisect(Site * s1, Site * s2) 00033 { 00034 double dx, dy, adx, ady; 00035 Edge *newedge; 00036 00037 newedge = (Edge *) getfree(&efl); 00038 00039 newedge->reg[0] = s1; 00040 newedge->reg[1] = s2; 00041 ref(s1); 00042 ref(s2); 00043 newedge->ep[0] = (Site *) NULL; 00044 newedge->ep[1] = (Site *) NULL; 00045 00046 dx = s2->coord.x - s1->coord.x; 00047 dy = s2->coord.y - s1->coord.y; 00048 adx = dx > 0 ? dx : -dx; 00049 ady = dy > 0 ? dy : -dy; 00050 newedge->c = 00051 s1->coord.x * dx + s1->coord.y * dy + (dx * dx + dy * dy) * 0.5; 00052 if (adx > ady) { 00053 newedge->a = 1.0; 00054 newedge->b = dy / dx; 00055 newedge->c /= dx; 00056 } else { 00057 newedge->b = 1.0; 00058 newedge->a = dx / dy; 00059 newedge->c /= dy; 00060 }; 00061 00062 newedge->edgenbr = nedges; 00063 #ifdef STANDALONE 00064 out_bisector(newedge); 00065 #endif 00066 nedges += 1; 00067 return (newedge); 00068 } 00069 00070 00071 static void doSeg(Edge * e, double x1, double y1, double x2, double y2) 00072 { 00073 addVertex(e->reg[0], x1, y1); 00074 addVertex(e->reg[0], x2, y2); 00075 addVertex(e->reg[1], x1, y1); 00076 addVertex(e->reg[1], x2, y2); 00077 } 00078 00079 void clip_line(Edge * e) 00080 { 00081 Site *s1, *s2; 00082 double x1, x2, y1, y2; 00083 00084 if (e->a == 1.0 && e->b >= 0.0) { 00085 s1 = e->ep[1]; 00086 s2 = e->ep[0]; 00087 } else { 00088 s1 = e->ep[0]; 00089 s2 = e->ep[1]; 00090 } 00091 00092 if (e->a == 1.0) { 00093 if (s1 != (Site *) NULL) { 00094 y1 = s1->coord.y; 00095 if (y1 > pymax) 00096 return; 00097 else if (y1 >= pymin) 00098 x1 = s1->coord.x; 00099 else { 00100 y1 = pymin; 00101 x1 = e->c - e->b * y1; 00102 } 00103 } else { 00104 y1 = pymin; 00105 x1 = e->c - e->b * y1; 00106 } 00107 00108 if (s2 != (Site *) NULL) { 00109 y2 = s2->coord.y; 00110 if (y2 < pymin) 00111 return; 00112 else if (y2 <= pymax) 00113 x2 = s2->coord.x; 00114 else { 00115 y2 = pymax; 00116 x2 = e->c - e->b * y2; 00117 } 00118 } else { 00119 y2 = pymax; 00120 x2 = e->c - e->b * y2; 00121 } 00122 00123 if (((x1 > pxmax) & (x2 > pxmax)) | ((x1 < pxmin) & (x2 < pxmin))) 00124 return; 00125 if (x1 > pxmax) { 00126 x1 = pxmax; 00127 y1 = (e->c - x1) / e->b; 00128 }; 00129 if (x1 < pxmin) { 00130 x1 = pxmin; 00131 y1 = (e->c - x1) / e->b; 00132 }; 00133 if (x2 > pxmax) { 00134 x2 = pxmax; 00135 y2 = (e->c - x2) / e->b; 00136 }; 00137 if (x2 < pxmin) { 00138 x2 = pxmin; 00139 y2 = (e->c - x2) / e->b; 00140 }; 00141 } else { 00142 if (s1 != (Site *) NULL) { 00143 x1 = s1->coord.x; 00144 if (x1 > pxmax) 00145 return; 00146 else if (x1 >= pxmin) 00147 y1 = s1->coord.y; 00148 else { 00149 x1 = pxmin; 00150 y1 = e->c - e->a * x1; 00151 } 00152 } else { 00153 x1 = pxmin; 00154 y1 = e->c - e->a * x1; 00155 } 00156 00157 if (s2 != (Site *) NULL) { 00158 x2 = s2->coord.x; 00159 if (x2 < pxmin) 00160 return; 00161 else if (x2 <= pxmax) 00162 y2 = s2->coord.y; 00163 else { 00164 x2 = pxmax; 00165 y2 = e->c - e->a * x2; 00166 } 00167 } else { 00168 x2 = pxmax; 00169 y2 = e->c - e->a * x2; 00170 } 00171 00172 if (((y1 > pymax) & (y2 > pymax)) | ((y1 < pymin) & (y2 < pymin))) 00173 return; 00174 if (y1 > pymax) { 00175 y1 = pymax; 00176 x1 = (e->c - y1) / e->a; 00177 }; 00178 if (y1 < pymin) { 00179 y1 = pymin; 00180 x1 = (e->c - y1) / e->a; 00181 }; 00182 if (y2 > pymax) { 00183 y2 = pymax; 00184 x2 = (e->c - y2) / e->a; 00185 }; 00186 if (y2 < pymin) { 00187 y2 = pymin; 00188 x2 = (e->c - y2) / e->a; 00189 }; 00190 } 00191 00192 doSeg(e, x1, y1, x2, y2); 00193 #ifdef STANDALONE 00194 if (doPS) 00195 line(x1, y1, x2, y2); 00196 #endif 00197 } 00198 00199 void endpoint(Edge * e, int lr, Site * s) 00200 { 00201 e->ep[lr] = s; 00202 ref(s); 00203 if (e->ep[re - lr] == (Site *) NULL) 00204 return; 00205 clip_line(e); 00206 #ifdef STANDALONE 00207 out_ep(e); 00208 #endif 00209 deref(e->reg[le]); 00210 deref(e->reg[re]); 00211 makefree(e, &efl); 00212 }
1.7.5