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