00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "mem.h"
00018 #include "hedges.h"
00019 #include "render.h"
00020
00021
00022 #define DELETED -2
00023
00024 Halfedge *ELleftend, *ELrightend;
00025
00026 static Freelist hfl;
00027 static int ELhashsize;
00028 static Halfedge **ELhash;
00029 static int ntry, totalsearch;
00030
00031 void ELcleanup()
00032 {
00033 freeinit(&hfl, sizeof **ELhash);
00034 free(ELhash);
00035 ELhash = NULL;
00036 }
00037
00038 void ELinitialize()
00039 {
00040 int i;
00041
00042 freeinit(&hfl, sizeof **ELhash);
00043 ELhashsize = 2 * sqrt_nsites;
00044 if (ELhash == NULL)
00045 ELhash = N_GNEW(ELhashsize, Halfedge *);
00046 for (i = 0; i < ELhashsize; i += 1)
00047 ELhash[i] = (Halfedge *) NULL;
00048 ELleftend = HEcreate((Edge *) NULL, 0);
00049 ELrightend = HEcreate((Edge *) NULL, 0);
00050 ELleftend->ELleft = (Halfedge *) NULL;
00051 ELleftend->ELright = ELrightend;
00052 ELrightend->ELleft = ELleftend;
00053 ELrightend->ELright = (Halfedge *) NULL;
00054 ELhash[0] = ELleftend;
00055 ELhash[ELhashsize - 1] = ELrightend;
00056 }
00057
00058
00059 Site *hintersect(Halfedge * el1, Halfedge * el2)
00060 {
00061 Edge *e1, *e2, *e;
00062 Halfedge *el;
00063 double d, xint, yint;
00064 int right_of_site;
00065 Site *v;
00066
00067 e1 = el1->ELedge;
00068 e2 = el2->ELedge;
00069 if (e1 == (Edge *) NULL || e2 == (Edge *) NULL)
00070 return ((Site *) NULL);
00071 if (e1->reg[1] == e2->reg[1])
00072 return ((Site *) NULL);
00073
00074 d = e1->a * e2->b - e1->b * e2->a;
00075 if (-1.0e-10 < d && d < 1.0e-10)
00076 return ((Site *) NULL);
00077
00078 xint = (e1->c * e2->b - e2->c * e1->b) / d;
00079 yint = (e2->c * e1->a - e1->c * e2->a) / d;
00080
00081 if ((e1->reg[1]->coord.y < e2->reg[1]->coord.y) ||
00082 (e1->reg[1]->coord.y == e2->reg[1]->coord.y &&
00083 e1->reg[1]->coord.x < e2->reg[1]->coord.x)) {
00084 el = el1;
00085 e = e1;
00086 } else {
00087 el = el2;
00088 e = e2;
00089 };
00090 right_of_site = xint >= e->reg[1]->coord.x;
00091 if ((right_of_site && el->ELpm == le) ||
00092 (!right_of_site && el->ELpm == re))
00093 return ((Site *) NULL);
00094
00095 v = getsite();
00096 v->refcnt = 0;
00097 v->coord.x = xint;
00098 v->coord.y = yint;
00099 return (v);
00100 }
00101
00102
00103 int right_of(Halfedge * el, Point * p)
00104 {
00105 Edge *e;
00106 Site *topsite;
00107 int right_of_site, above, fast;
00108 double dxp, dyp, dxs, t1, t2, t3, yl;
00109
00110 e = el->ELedge;
00111 topsite = e->reg[1];
00112 right_of_site = p->x > topsite->coord.x;
00113 if (right_of_site && el->ELpm == le)
00114 return (1);
00115 if (!right_of_site && el->ELpm == re)
00116 return (0);
00117
00118 if (e->a == 1.0) {
00119 dyp = p->y - topsite->coord.y;
00120 dxp = p->x - topsite->coord.x;
00121 fast = 0;
00122 if ((!right_of_site & (e->b < 0.0)) |
00123 (right_of_site & (e->b >= 0.0))) {
00124 above = dyp >= e->b * dxp;
00125 fast = above;
00126 } else {
00127 above = p->x + p->y * e->b > e->c;
00128 if (e->b < 0.0)
00129 above = !above;
00130 if (!above)
00131 fast = 1;
00132 };
00133 if (!fast) {
00134 dxs = topsite->coord.x - (e->reg[0])->coord.x;
00135 above = e->b * (dxp * dxp - dyp * dyp) <
00136 dxs * dyp * (1.0 + 2.0 * dxp / dxs + e->b * e->b);
00137 if (e->b < 0.0)
00138 above = !above;
00139 };
00140 } else {
00141 yl = e->c - e->a * p->x;
00142 t1 = p->y - yl;
00143 t2 = p->x - topsite->coord.x;
00144 t3 = yl - topsite->coord.y;
00145 above = t1 * t1 > t2 * t2 + t3 * t3;
00146 };
00147 return (el->ELpm == le ? above : !above);
00148 }
00149
00150 Halfedge *HEcreate(Edge * e, char pm)
00151 {
00152 Halfedge *answer;
00153 answer = (Halfedge *) getfree(&hfl);
00154 answer->ELedge = e;
00155 answer->ELpm = pm;
00156 answer->PQnext = (Halfedge *) NULL;
00157 answer->vertex = (Site *) NULL;
00158 answer->ELrefcnt = 0;
00159 return (answer);
00160 }
00161
00162
00163 void ELinsert(Halfedge * lb, Halfedge * new)
00164 {
00165 new->ELleft = lb;
00166 new->ELright = lb->ELright;
00167 (lb->ELright)->ELleft = new;
00168 lb->ELright = new;
00169 }
00170
00171
00172 static Halfedge *ELgethash(int b)
00173 {
00174 Halfedge *he;
00175
00176 if (b < 0 || b >= ELhashsize)
00177 return ((Halfedge *) NULL);
00178 he = ELhash[b];
00179 if (he == (Halfedge *) NULL || he->ELedge != (Edge *) DELETED)
00180 return (he);
00181
00182
00183 ELhash[b] = (Halfedge *) NULL;
00184 if ((he->ELrefcnt -= 1) == 0)
00185 makefree(he, &hfl);
00186 return ((Halfedge *) NULL);
00187 }
00188
00189 Halfedge *ELleftbnd(Point * p)
00190 {
00191 int i, bucket;
00192 Halfedge *he;
00193
00194
00195 bucket = (p->x - xmin) / deltax * ELhashsize;
00196 if (bucket < 0)
00197 bucket = 0;
00198 if (bucket >= ELhashsize)
00199 bucket = ELhashsize - 1;
00200 he = ELgethash(bucket);
00201 if (he == (Halfedge *) NULL) {
00202 for (i = 1; 1; i += 1) {
00203 if ((he = ELgethash(bucket - i)) != (Halfedge *) NULL)
00204 break;
00205 if ((he = ELgethash(bucket + i)) != (Halfedge *) NULL)
00206 break;
00207 };
00208 totalsearch += i;
00209 };
00210 ntry += 1;
00211
00212 if (he == ELleftend || (he != ELrightend && right_of(he, p))) {
00213 do {
00214 he = he->ELright;
00215 } while (he != ELrightend && right_of(he, p));
00216 he = he->ELleft;
00217 } else
00218 do {
00219 he = he->ELleft;
00220 } while (he != ELleftend && !right_of(he, p));
00221
00222
00223 if (bucket > 0 && bucket < ELhashsize - 1) {
00224 if (ELhash[bucket] != (Halfedge *) NULL)
00225 ELhash[bucket]->ELrefcnt -= 1;
00226 ELhash[bucket] = he;
00227 ELhash[bucket]->ELrefcnt += 1;
00228 };
00229 return (he);
00230 }
00231
00232
00233
00234
00235 void ELdelete(Halfedge * he)
00236 {
00237 (he->ELleft)->ELright = he->ELright;
00238 (he->ELright)->ELleft = he->ELleft;
00239 he->ELedge = (Edge *) DELETED;
00240 }
00241
00242
00243 Halfedge *ELright(Halfedge * he)
00244 {
00245 return (he->ELright);
00246 }
00247
00248 Halfedge *ELleft(Halfedge * he)
00249 {
00250 return (he->ELleft);
00251 }
00252
00253
00254 Site *leftreg(Halfedge * he)
00255 {
00256 if (he->ELedge == (Edge *) NULL)
00257 return (bottomsite);
00258 return (he->ELpm == le ? he->ELedge->reg[le] : he->ELedge->reg[re]);
00259 }
00260
00261 Site *rightreg(Halfedge * he)
00262 {
00263 if (he->ELedge == (Edge *) NULL)
00264 return (bottomsite);
00265 return (he->ELpm == le ? he->ELedge->reg[re] : he->ELedge->reg[le]);
00266 }