221 changes: 221 additions & 0 deletions contrib/voronoi/geometry.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@

/*** GEOMETRY.C ***/

#include <math.h>
#include "vdefs.h"

float deltax, deltay ;
int nedges, sqrt_nsites, nvertices ;
Freelist efl ;

void
geominit(void)
{
freeinit(&efl, sizeof(Edge)) ;
nvertices = nedges = 0 ;
sqrt_nsites = sqrt(nsites+4) ;
deltay = ymax - ymin ;
deltax = xmax - xmin ;
}

Edge *
bisect(Site * s1, Site * s2)
{
float dx, dy, adx, ady ;
Edge * newedge ;

newedge = (Edge *)getfree(&efl) ;
newedge->reg[0] = s1 ;
newedge->reg[1] = s2 ;
ref(s1) ;
ref(s2) ;
newedge->ep[0] = newedge->ep[1] = (Site *)NULL ;
dx = s2->coord.x - s1->coord.x ;
dy = s2->coord.y - s1->coord.y ;
adx = dx>0 ? dx : -dx ;
ady = dy>0 ? dy : -dy ;
newedge->c = s1->coord.x * dx + s1->coord.y * dy + (dx*dx +
dy*dy) * 0.5 ;
if (adx > ady)
{
newedge->a = 1.0 ;
newedge->b = dy/dx ;
newedge->c /= dx ;
}
else
{
newedge->b = 1.0 ;
newedge->a = dx/dy ;
newedge->c /= dy ;
}
newedge->edgenbr = nedges ;
out_bisector(newedge) ;
nedges++ ;
return (newedge) ;
}

Site *
intersect(Halfedge * el1, Halfedge * el2)
{
Edge * e1, * e2, * e ;
Halfedge * el ;
float d, xint, yint ;
int right_of_site ;
Site * v ;

e1 = el1->ELedge ;
e2 = el2->ELedge ;
if ((e1 == (Edge*)NULL) || (e2 == (Edge*)NULL))
{
return ((Site *)NULL) ;
}
if (e1->reg[1] == e2->reg[1])
{
return ((Site *)NULL) ;
}
d = (e1->a * e2->b) - (e1->b * e2->a) ;
if ((-1.0e-10 < d) && (d < 1.0e-10))
{
return ((Site *)NULL) ;
}
xint = (e1->c * e2->b - e2->c * e1->b) / d ;
yint = (e2->c * e1->a - e1->c * e2->a) / d ;
if ((e1->reg[1]->coord.y < e2->reg[1]->coord.y) ||
(e1->reg[1]->coord.y == e2->reg[1]->coord.y &&
e1->reg[1]->coord.x < e2->reg[1]->coord.x))
{
el = el1 ;
e = e1 ;
}
else
{
el = el2 ;
e = e2 ;
}
right_of_site = (xint >= e->reg[1]->coord.x) ;
if ((right_of_site && (el->ELpm == le)) ||
(!right_of_site && (el->ELpm == re)))
{
return ((Site *)NULL) ;
}
v = (Site *)getfree(&sfl) ;
v->refcnt = 0 ;
v->coord.x = xint ;
v->coord.y = yint ;
return (v) ;
}

/*** returns 1 if p is to right of halfedge e ***/

int
right_of(Halfedge * el, Point * p)
{
Edge * e ;
Site * topsite ;
int right_of_site, above, fast ;
float dxp, dyp, dxs, t1, t2, t3, yl ;

e = el->ELedge ;
topsite = e->reg[1] ;
right_of_site = (p->x > topsite->coord.x) ;
if (right_of_site && (el->ELpm == le))
{
return (1) ;
}
if(!right_of_site && (el->ELpm == re))
{
return (0) ;
}
if (e->a == 1.0)
{
dyp = p->y - topsite->coord.y ;
dxp = p->x - topsite->coord.x ;
fast = 0 ;
if ((!right_of_site & (e->b < 0.0)) ||
(right_of_site & (e->b >= 0.0)))
{
fast = above = (dyp >= e->b*dxp) ;
}
else
{
above = ((p->x + p->y * e->b) > (e->c)) ;
if (e->b < 0.0)
{
above = !above ;
}
if (!above)
{
fast = 1 ;
}
}
if (!fast)
{
dxs = topsite->coord.x - (e->reg[0])->coord.x ;
above = (e->b * (dxp*dxp - dyp*dyp))
<
(dxs * dyp * (1.0 + 2.0 * dxp /
dxs + e->b * e->b)) ;
if (e->b < 0.0)
{
above = !above ;
}
}
}
else /*** e->b == 1.0 ***/
{
yl = e->c - e->a * p->x ;
t1 = p->y - yl ;
t2 = p->x - topsite->coord.x ;
t3 = yl - topsite->coord.y ;
above = ((t1*t1) > ((t2 * t2) + (t3 * t3))) ;
}
return (el->ELpm == le ? above : !above) ;
}

void
endpoint(Edge * e, int lr, Site * s)
{
e->ep[lr] = s ;
ref(s) ;
if (e->ep[re-lr] == (Site *)NULL)
{
return ;
}
out_ep(e) ;
deref(e->reg[le]) ;
deref(e->reg[re]) ;
makefree((Freenode *)e, (Freelist *) &efl) ;
}

float
dist(Site * s, Site * t)
{
float dx,dy ;

dx = s->coord.x - t->coord.x ;
dy = s->coord.y - t->coord.y ;
return (sqrt(dx*dx + dy*dy)) ;
}

void
makevertex(Site * v)
{
v->sitenbr = nvertices++ ;
out_vertex(v) ;
}

void
deref(Site * v)
{
if (--(v->refcnt) == 0 )
{
makefree((Freenode *)v, (Freelist *)&sfl) ;
}
}

void
ref(Site * v)
{
++(v->refcnt) ;
}

118 changes: 118 additions & 0 deletions contrib/voronoi/heap.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@

/*** HEAP.C ***/


#include "vdefs.h"

int PQmin, PQcount, PQhashsize ;
Halfedge * PQhash ;

void
PQinsert(Halfedge * he, Site * v, float offset)
{
Halfedge * last, * next ;

he->vertex = v ;
ref(v) ;
he->ystar = v->coord.y + offset ;
last = &PQhash[ PQbucket(he)] ;
while ((next = last->PQnext) != (Halfedge *)NULL &&
(he->ystar > next->ystar ||
(he->ystar == next->ystar &&
v->coord.x > next->vertex->coord.x)))
{
last = next ;
}
he->PQnext = last->PQnext ;
last->PQnext = he ;
PQcount++ ;
}

void
PQdelete(Halfedge * he)
{
Halfedge * last;

if(he -> vertex != (Site *) NULL)
{
last = &PQhash[PQbucket(he)] ;
while (last -> PQnext != he)
{
last = last->PQnext ;
}
last->PQnext = he->PQnext;
PQcount-- ;
deref(he->vertex) ;
he->vertex = (Site *)NULL ;
}
}

int
PQbucket(Halfedge * he)
{
int bucket ;


if (he->ystar < ymin) bucket = 0;
else if (he->ystar >= ymax) bucket = PQhashsize-1;
else bucket = (he->ystar - ymin)/deltay * PQhashsize;
if (bucket < 0)
{
bucket = 0 ;
}
if (bucket >= PQhashsize)
{
bucket = PQhashsize-1 ;
}
if (bucket < PQmin)
{
PQmin = bucket ;
}
return (bucket);
}

int
PQempty(void)
{
return (PQcount == 0) ;
}


Point
PQ_min(void)
{
Point answer ;

while (PQhash[PQmin].PQnext == (Halfedge *)NULL)
{
++PQmin ;
}
answer.x = PQhash[PQmin].PQnext->vertex->coord.x ;
answer.y = PQhash[PQmin].PQnext->ystar ;
return (answer) ;
}

Halfedge *
PQextractmin(void)
{
Halfedge * curr ;

curr = PQhash[PQmin].PQnext ;
PQhash[PQmin].PQnext = curr->PQnext ;
PQcount-- ;
return (curr) ;
}

void
PQinitialize(void)
{
int i ;

PQcount = PQmin = 0 ;
PQhashsize = 4 * sqrt_nsites ;
PQhash = (Halfedge *)myalloc(PQhashsize * sizeof *PQhash) ;
for (i = 0 ; i < PQhashsize; i++)
{
PQhash[i].PQnext = (Halfedge *)NULL ;
}
}
161 changes: 161 additions & 0 deletions contrib/voronoi/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
/*** MAIN.C ***/

#include <stdio.h>
#include <stdlib.h> /* realloc(), qsort() */

#include "vdefs.h"

Site * readone(void), * nextone(void) ;
void readsites(void) ;

int sorted, triangulate, plot, debug, nsites, siteidx ;
float xmin, xmax, ymin, ymax ;
Site * sites ;
Freelist sfl ;

int
main(int argc, char *argv[])
{
int c ;
Site *(*next)() ;

sorted = triangulate = plot = debug = 0 ;
while ((c = getopt(argc, argv, "dpst")) != EOF)
{
switch(c)
{
case 'd':
debug = 1 ;
break ;
case 's':
sorted = 1 ;
break ;
case 't':
triangulate = 1 ;
break ;
case 'p':
plot = 1 ;
break ;
}
}

freeinit(&sfl, sizeof(Site)) ;
if (sorted)
{
scanf("%d %f %f %f %f", &nsites, &xmin, &xmax, &ymin, &ymax) ;
next = readone ;
}
else
{
readsites() ;
next = nextone ;
}
siteidx = 0 ;
geominit() ;
if (plot)
{
plotinit() ;
}
voronoi(next) ;
return (0) ;
}

/*** sort sites on y, then x, coord ***/

int
scomp(const void * vs1, const void * vs2)
{
Point * s1 = (Point *)vs1 ;
Point * s2 = (Point *)vs2 ;

if (s1->y < s2->y)
{
return (-1) ;
}
if (s1->y > s2->y)
{
return (1) ;
}
if (s1->x < s2->x)
{
return (-1) ;
}
if (s1->x > s2->x)
{
return (1) ;
}
return (0) ;
}

/*** return a single in-storage site ***/

Site *
nextone(void)
{
Site * s ;

if (siteidx < nsites)
{
s = &sites[siteidx++];
return (s) ;
}
else
{
return ((Site *)NULL) ;
}
}

/*** read all sites, sort, and compute xmin, xmax, ymin, ymax ***/

void
readsites(void)
{
int i ;

nsites = 0 ;
sites = (Site *) myalloc(4000 * sizeof(Site));
while (scanf("%f %f", &sites[nsites].coord.x,
&sites[nsites].coord.y) !=EOF)
{
sites[nsites].sitenbr = nsites ;
sites[nsites++].refcnt = 0 ;
if (nsites % 4000 == 0)
sites = (Site *)
realloc(sites,(nsites+4000)*sizeof(Site));
}

qsort((void *)sites, nsites, sizeof(Site), scomp) ;
xmin = sites[0].coord.x ;
xmax = sites[0].coord.x ;
for (i = 1 ; i < nsites ; ++i)
{
if(sites[i].coord.x < xmin)
{
xmin = sites[i].coord.x ;
}
if (sites[i].coord.x > xmax)
{
xmax = sites[i].coord.x ;
}
}
ymin = sites[0].coord.y ;
ymax = sites[nsites-1].coord.y ;
}

/*** read one site ***/

Site *
readone(void)
{
Site * s ;

s = (Site *)getfree(&sfl) ;
s->refcnt = 0 ;
s->sitenbr = siteidx++ ;
if (scanf("%f %f", &(s->coord.x), &(s->coord.y)) == EOF)
{
return ((Site *)NULL ) ;
}
return (s) ;
}

57 changes: 57 additions & 0 deletions contrib/voronoi/memory.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@

/*** MEMORY.C ***/

#include <stdio.h>
#include <stdlib.h> /* malloc(), exit() */

#include "vdefs.h"

extern int sqrt_nsites, siteidx ;

void
freeinit(Freelist * fl, int size)
{
fl->head = (Freenode *)NULL ;
fl->nodesize = size ;
}

char *
getfree(Freelist * fl)
{
int i ;
Freenode * t ;
if (fl->head == (Freenode *)NULL)
{
t = (Freenode *) myalloc(sqrt_nsites * fl->nodesize) ;
for(i = 0 ; i < sqrt_nsites ; i++)
{
makefree((Freenode *)((char *)t+i*fl->nodesize), fl) ;
}
}
t = fl->head ;
fl->head = (fl->head)->nextfree ;
return ((char *)t) ;
}

void
makefree(Freenode * curr, Freelist * fl)
{
curr->nextfree = fl->head ;
fl->head = curr ;
}

int total_alloc ;

char *
myalloc(unsigned n)
{
char * t ;
if ((t=malloc(n)) == (char *) 0)
{
fprintf(stderr,"Insufficient memory processing site %d (%d bytes in use)\n",
siteidx, total_alloc) ;
return(0) ; // was exit(0) in original source, we aint having that here !!!
}
total_alloc += n ;
return (t) ;
}
244 changes: 244 additions & 0 deletions contrib/voronoi/output.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@

/*** OUTPUT.C ***/


#include <stdio.h>

#include "vdefs.h"

extern int triangulate, plot, debug ;
extern float ymax, ymin, xmax, xmin ;

float pxmin, pxmax, pymin, pymax, cradius;

void
openpl(void)
{
}

#pragma argsused
void
line(float ax, float ay, float bx, float by)
{
}

#pragma argsused
void
circle(float ax, float ay, float radius)
{
}

#pragma argsused
void
range(float pxmin, float pxmax, float pymin, float pymax)
{
}

void
out_bisector(Edge * e)
{
if (triangulate && plot && !debug)
{
line(e->reg[0]->coord.x, e->reg[0]->coord.y,
e->reg[1]->coord.x, e->reg[1]->coord.y) ;
}
if (!triangulate && !plot && !debug)
{
printf("l %f %f %f\n", e->a, e->b, e->c) ;
}
if (debug)
{
printf("line(%d) %gx+%gy=%g, bisecting %d %d\n", e->edgenbr,
e->a, e->b, e->c, e->reg[le]->sitenbr, e->reg[re]->sitenbr) ;
}
}

void
out_ep(Edge * e)
{
if (!triangulate && plot)
{
clip_line(e) ;
}
if (!triangulate && !plot)
{
printf("e %d", e->edgenbr);
printf(" %d ", e->ep[le] != (Site *)NULL ? e->ep[le]->sitenbr : -1) ;
printf("%d\n", e->ep[re] != (Site *)NULL ? e->ep[re]->sitenbr : -1) ;
}
}

void
out_vertex(Site * v)
{
if (!triangulate && !plot && !debug)
{
printf ("v %f %f\n", v->coord.x, v->coord.y) ;
}
if (debug)
{
printf("vertex(%d) at %f %f\n", v->sitenbr, v->coord.x, v->coord.y) ;
}
}

void
out_site(Site * s)
{
if (!triangulate && plot && !debug)
{
circle (s->coord.x, s->coord.y, cradius) ;
}
if (!triangulate && !plot && !debug)
{
printf("s %f %f\n", s->coord.x, s->coord.y) ;
}
if (debug)
{
printf("site (%d) at %f %f\n", s->sitenbr, s->coord.x, s->coord.y) ;
}
}

void
out_triple(Site * s1, Site * s2, Site * s3)
{
if (triangulate && !plot && !debug)
{
printf("%d %d %d\n", s1->sitenbr, s2->sitenbr, s3->sitenbr) ;
}
if (debug)
{
printf("circle through left=%d right=%d bottom=%d\n",
s1->sitenbr, s2->sitenbr, s3->sitenbr) ;
}
}

void
plotinit(void)
{
float dx, dy, d ;

dy = ymax - ymin ;
dx = xmax - xmin ;
d = ( dx > dy ? dx : dy) * 1.1 ;
pxmin = xmin - (d-dx) / 2.0 ;
pxmax = xmax + (d-dx) / 2.0 ;
pymin = ymin - (d-dy) / 2.0 ;
pymax = ymax + (d-dy) / 2.0 ;
cradius = (pxmax - pxmin) / 350.0 ;
openpl() ;
range(pxmin, pymin, pxmax, pymax) ;
}

void
clip_line(Edge * e)
{
Site * s1, * s2 ;
float x1, x2, y1, y2 ;

if (e->a == 1.0 && e->b >= 0.0)
{
s1 = e->ep[1] ;
s2 = e->ep[0] ;
}
else
{
s1 = e->ep[0] ;
s2 = e->ep[1] ;
}
if (e->a == 1.0)
{
y1 = pymin ;
if (s1 != (Site *)NULL && s1->coord.y > pymin)
{
y1 = s1->coord.y ;
}
if (y1 > pymax)
{
return ;
}
x1 = e->c - e->b * y1 ;
y2 = pymax ;
if (s2 != (Site *)NULL && s2->coord.y < pymax)
{
y2 = s2->coord.y ;
}
if (y2 < pymin)
{
return ;
}
x2 = e->c - e->b * y2 ;
if (((x1 > pxmax) && (x2 > pxmax)) || ((x1 < pxmin) && (x2 < pxmin)))
{
return ;
}
if (x1 > pxmax)
{
x1 = pxmax ;
y1 = (e->c - x1) / e->b ;
}
if (x1 < pxmin)
{
x1 = pxmin ;
y1 = (e->c - x1) / e->b ;
}
if (x2 > pxmax)
{
x2 = pxmax ;
y2 = (e->c - x2) / e->b ;
}
if (x2 < pxmin)
{
x2 = pxmin ;
y2 = (e->c - x2) / e->b ;
}
}
else
{
x1 = pxmin ;
if (s1 != (Site *)NULL && s1->coord.x > pxmin)
{
x1 = s1->coord.x ;
}
if (x1 > pxmax)
{
return ;
}
y1 = e->c - e->a * x1 ;
x2 = pxmax ;
if (s2 != (Site *)NULL && s2->coord.x < pxmax)
{
x2 = s2->coord.x ;
}
if (x2 < pxmin)
{
return ;
}
y2 = e->c - e->a * x2 ;
if (((y1 > pymax) && (y2 > pymax)) || ((y1 < pymin) && (y2 <pymin)))
{
return ;
}
if (y1> pymax)
{
y1 = pymax ;
x1 = (e->c - y1) / e->a ;
}
if (y1 < pymin)
{
y1 = pymin ;
x1 = (e->c - y1) / e->a ;
}
if (y2 > pymax)
{
y2 = pymax ;
x2 = (e->c - y2) / e->a ;
}
if (y2 < pymin)
{
y2 = pymin ;
x2 = (e->c - y2) / e->a ;
}
}
line(x1,y1,x2,y2);
}

100 changes: 100 additions & 0 deletions contrib/voronoi/t
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
0.532095 0.894141
0.189043 0.613426
0.550977 0.415724
0.00397384 0.60576
0.89423 0.666812
0.0730728 0.740658
0.64018 0.926186
0.389914 0.553149
0.046918 0.172275
0.820327 0.578957
0.166575 0.597895
0.587999 0.824301
0.184717 0.0608049
0.264707 0.661072
0.564959 0.824897
0.986991 0.654621
0.214221 0.611877
0.997171 0.807318
0.233578 0.380796
0.209772 0.585171
0.631619 0.418295
0.441601 0.474479
0.246242 0.196578
0.243191 0.428592
0.129101 0.460463
0.808454 0.240363
0.23591 0.362678
0.841259 0.0182264
0.825533 0.867529
0.780973 0.282859
0.492706 0.0717757
0.0641069 0.0241644
0.711451 0.621806
0.532239 0.872561
0.264527 0.947361
0.984485 0.373498
0.890788 0.0900603
0.81489 0.765458
0.656357 0.383494
0.161836 0.878997
0.789622 0.367808
0.00529994 0.694075
0.751558 0.0541492
0.315169 0.989785
0.0675723 0.642346
0.144209 0.130059
0.755242 0.723929
0.0258396 0.306045
0.00905612 0.544864
0.0917369 0.0311395
0.000120247 0.760615
0.599014 0.406906
0.0209242 0.0676926
0.402961 0.743223
0.536965 0.776167
0.791622 0.4288
0.0492686 0.546021
0.321031 0.883358
0.45994 0.0493888
0.306635 0.920045
0.290264 0.480864
0.117081 0.709596
0.663268 0.827229
0.25703 0.908703
0.138396 0.712536
0.37325 0.578061
0.792062 0.598336
0.761925 0.679885
0.498106 0.0823257
0.0791993 0.879007
0.389481 0.161374
0.909555 0.33623
0.78771 0.527877
0.87391 0.282804
0.914291 0.579771
0.126212 0.635836
0.962689 0.412397
0.662097 0.205412
0.514842 0.35217
0.573771 0.571652
0.541641 0.302552
0.880047 0.447681
0.854456 0.455932
0.882323 0.00625933
0.0835167 0.817145
0.868329 0.54442
0.211671 0.598359
0.169315 0.4421
0.116072 0.753312
0.900911 0.0493624
0.889781 0.970528
0.209244 0.783234
0.0556217 0.973298
0.787673 0.0775736
0.327654 0.267293
0.571657 0.956988
0.519674 0.443726
0.0206049 0.472568
0.00635056 0.409455
0.414254 0.229849
859 changes: 859 additions & 0 deletions contrib/voronoi/tt

Large diffs are not rendered by default.

135 changes: 135 additions & 0 deletions contrib/voronoi/vdefs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
#ifndef __VDEFS_H
#define __VDEFS_H

#ifndef NULL
#define NULL 0
#endif

#define DELETED -2

typedef struct tagFreenode
{
struct tagFreenode * nextfree;
} Freenode ;


typedef struct tagFreelist
{
Freenode * head;
int nodesize;
} Freelist ;

typedef struct tagPoint
{
float x ;
float y ;
} Point ;

/* structure used both for sites and for vertices */

typedef struct tagSite
{
Point coord ;
int sitenbr ;
int refcnt ;
} Site ;


typedef struct tagEdge
{
float a, b, c ;
Site * ep[2] ;
Site * reg[2] ;
int edgenbr ;
} Edge ;

#define le 0
#define re 1

typedef struct tagHalfedge
{
struct tagHalfedge * ELleft ;
struct tagHalfedge * ELright ;
Edge * ELedge ;
int ELrefcnt ;
char ELpm ;
Site * vertex ;
float ystar ;
struct tagHalfedge * PQnext ;
} Halfedge ;

/* edgelist.c */
void ELinitialize(void) ;
Halfedge * HEcreate(Edge *, int) ;
void ELinsert(Halfedge *, Halfedge *) ;
Halfedge * ELgethash(int) ;
Halfedge * ELleftbnd(Point *) ;
void ELdelete(Halfedge *) ;
Halfedge * ELright(Halfedge *) ;
Halfedge * ELleft(Halfedge *) ;
Site * leftreg(Halfedge *) ;
Site * rightreg(Halfedge *) ;
extern int ELhashsize ;
extern Site * bottomsite ;
extern Freelist hfl ;
extern Halfedge * ELleftend, * ELrightend, **ELhash ;

/* geometry.c */
void geominit(void) ;
Edge * bisect(Site *, Site *) ;
Site * intersect(Halfedge *, Halfedge *) ;
int right_of(Halfedge *, Point *) ;
void endpoint(Edge *, int, Site *) ;
float dist(Site *, Site *) ;
void makevertex(Site *) ;
void deref(Site *) ;
void ref(Site *) ;
extern float deltax, deltay ;
extern int nsites, nedges, sqrt_nsites, nvertices ;
extern Freelist sfl, efl ;

/* heap.c */
void PQinsert(Halfedge *, Site *, float) ;
void PQdelete(Halfedge *) ;
int PQbucket(Halfedge *) ;
int PQempty(void) ;
Point PQ_min(void) ;
Halfedge * PQextractmin(void) ;
void PQinitialize(void) ;
extern int PQmin, PQcount, PQhashsize ;
extern Halfedge * PQhash ;

/* main.c */
extern int sorted, triangulate, plot, debug, nsites, siteidx ;
extern float xmin, xmax, ymin, ymax ;
extern Site * sites ;
extern Freelist sfl ;

/* getopt.c */
extern int getopt(int, char *const *, const char *);

/* memory.c */
void freeinit(Freelist *, int) ;
char *getfree(Freelist *) ;
void makefree(Freenode *, Freelist *) ;
char *myalloc(unsigned) ;

/* output.c */
void openpl(void) ;
void line(float, float, float, float) ;
void circle(float, float, float) ;
void range(float, float, float, float) ;
void out_bisector(Edge *) ;
void out_ep(Edge *) ;
void out_vertex(Site *) ;
void out_site(Site *) ;
void out_triple(Site *, Site *, Site *) ;
void plotinit(void) ;
void clip_line(Edge *) ;

/* voronoi.c */
void voronoi(Site *(*)()) ;

#endif


Binary file added contrib/voronoi/voronoi
Binary file not shown.
120 changes: 120 additions & 0 deletions contrib/voronoi/voronoi.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@

/*** 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)() ;
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) ;
}
}

5 changes: 4 additions & 1 deletion src/src.pro
Original file line number Diff line number Diff line change
Expand Up @@ -756,6 +756,7 @@ HEADERS += ../contrib/qtsolutions/codeeditor/codeeditor.h ../contrib/qtsolutions
../contrib/boost/GeometricTools_BSplineCurve.h \
../contrib/kmeans/kmeans_dataset.h ../contrib/kmeans/kmeans_general_functions.h ../contrib/kmeans/hamerly_kmeans.h \
../contrib/kmeans/kmeans.h ../contrib/kmeans/original_space_kmeans.h ../contrib/kmeans/triangle_inequality_base_kmeans.h
../contrib/voronoi/vdefs.h


# Train View
Expand Down Expand Up @@ -865,7 +866,9 @@ SOURCES += ../contrib/qtsolutions/codeeditor/codeeditor.cpp ../contrib/qtsolutio
../contrib/levmar/Axb_core.c ../contrib/levmar/lm.c ../contrib/levmar/lmbc.c ../contrib/levmar/lmblec.c ../contrib/levmar/lmbleic.c \
../contrib/levmar/lmlec_core.c ../contrib/levmar/misc_core.c \
../contrib/kmeans/kmeans_dataset.cpp ../contrib/kmeans/kmeans_general_functions.cpp ../contrib/kmeans/hamerly_kmeans.cpp \
../contrib/kmeans/kmeans.cpp ../contrib/kmeans/original_space_kmeans.cpp ../contrib/kmeans/triangle_inequality_base_kmeans.cpp
../contrib/kmeans/kmeans.cpp ../contrib/kmeans/original_space_kmeans.cpp ../contrib/kmeans/triangle_inequality_base_kmeans.cpp \
../contrib/voronoi/edgelist.c ../contrib/voronoi/geometry.c ../contrib/voronoi/heap.c \
../contrib/voronoi/memory.c ../contrib/voronoi/output.c ../contrib/voronoi/voronoi.c


## Train View Components
Expand Down