/*** VORONOI.C ***/
#include "vdefs.h"
extern Site * bottomsite ;
extern Halfedge * ELleftend, * ELrightend ;
/*** implicit parameters: nsites, sqrt_nsites, xmin, xmax, ymin, ymax,
: deltax, deltay (can all be estimates).
: Performance suffers if they are wrong; better to make nsites,
: deltax, and deltay too big than too small. (?)
***/
void
voronoi(Site *(*nextsite)(void))
{
Site * newsite, * bot, * top, * temp, * p, * v ;
Point newintstar ;
int pm ;
Halfedge * lbnd, * rbnd, * llbnd, * rrbnd, * bisector ;
Edge * e ;
PQinitialize() ;
bottomsite = (*nextsite)() ;
out_site(bottomsite) ;
ELinitialize() ;
newsite = (*nextsite)() ;
newintstar.x = 0; /* gcc -Wall */
newintstar.y = 0; /* gcc -Wall */
while (1)
{
if(!PQempty())
{
newintstar = PQ_min() ;
}
if (newsite != (Site *)NULL && (PQempty()
|| newsite -> coord.y < newintstar.y
|| (newsite->coord.y == newintstar.y
&& newsite->coord.x < newintstar.x)))
{/* new site is smallest */
out_site(newsite) ;
lbnd = ELleftbnd(&(newsite->coord)) ;
rbnd = ELright(lbnd) ;
bot = rightreg(lbnd) ;
e = bisect(bot, newsite) ;
bisector = HEcreate(e, le) ;
ELinsert(lbnd, bisector) ;
p = intersect(lbnd, bisector) ;
if (p != (Site *)NULL)
{
PQdelete(lbnd) ;
PQinsert(lbnd, p, dist(p,newsite)) ;
}
lbnd = bisector ;
bisector = HEcreate(e, re) ;
ELinsert(lbnd, bisector) ;
p = intersect(bisector, rbnd) ;
if (p != (Site *)NULL)
{
PQinsert(bisector, p, dist(p,newsite)) ;
}
newsite = (*nextsite)() ;
}
else if (!PQempty()) /* intersection is smallest */
{
lbnd = PQextractmin() ;
llbnd = ELleft(lbnd) ;
rbnd = ELright(lbnd) ;
rrbnd = ELright(rbnd) ;
bot = leftreg(lbnd) ;
top = rightreg(rbnd) ;
out_triple(bot, top, rightreg(lbnd)) ;
v = lbnd->vertex ;
makevertex(v) ;
endpoint(lbnd->ELedge, lbnd->ELpm, v);
endpoint(rbnd->ELedge, rbnd->ELpm, v) ;
ELdelete(lbnd) ;
PQdelete(rbnd) ;
ELdelete(rbnd) ;
pm = le ;
if (bot->coord.y > top->coord.y)
{
temp = bot ;
bot = top ;
top = temp ;
pm = re ;
}
e = bisect(bot, top) ;
bisector = HEcreate(e, pm) ;
ELinsert(llbnd, bisector) ;
endpoint(e, re-pm, v) ;
deref(v) ;
p = intersect(llbnd, bisector) ;
if (p != (Site *) NULL)
{
PQdelete(llbnd) ;
PQinsert(llbnd, p, dist(p,bot)) ;
}
p = intersect(bisector, rrbnd) ;
if (p != (Site *) NULL)
{
PQinsert(bisector, p, dist(p,bot)) ;
}
}
else
{
break ;
}
}
for( lbnd = ELright(ELleftend) ;
lbnd != ELrightend ;
lbnd = ELright(lbnd))
{
e = lbnd->ELedge ;
out_ep(e) ;
}
}