| 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) ; | ||
| } | ||
|
|
| 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 ; | ||
| } | ||
| } |
| 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) ; | ||
| } | ||
|
|
| 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) ; | ||
| } |
| 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); | ||
| } | ||
|
|
| 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 |
| 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 | ||
|
|
||
|
|
| 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) ; | ||
| } | ||
| } | ||
|
|