/* * The author of this software is Steven Fortune. Copyright (c) 1994 by AT&T * Bell Laboratories. * Permission to use, copy, modify, and distribute this software for any * purpose without fee is hereby granted, provided that this entire notice * is included in all copies of any software which is or includes a copy * or modification of this software and in all copies of the supporting * documentation for such software. * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. */ /* * This code was originally written by Stephan Fortune in C code. I, Shane O'Sullivan, * have since modified it, encapsulating it in a C++ class and, fixing memory leaks and * adding accessors to the Voronoi Edges. * Permission to use, copy, modify, and distribute this software for any * purpose without fee is hereby granted, provided that this entire notice * is included in all copies of any software which is or includes a copy * or modification of this software and in all copies of the supporting * documentation for such software. * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. */ #ifndef VORONOI_DIAGRAM_GENERATOR #define VORONOI_DIAGRAM_GENERATOR #include #include #include #include #include #ifndef NULL #define NULL 0 #endif #define DELETED -2 #define le 0 #define re 1 struct Freenode { struct Freenode* nextfree; }; struct FreeNodeArrayList { struct Freenode* memory; struct FreeNodeArrayList* next; }; struct Freelist { struct Freenode* head; int nodesize; }; struct Point { float x, y; Point() : x(0.0), y(0.0) { } Point(float x, float y) : x(x), y(y) { } }; // structure used both for sites and for vertices struct Site { struct Point coord; int sitenbr; int refcnt; }; struct Edge { float a, b, c; struct Site* ep[2]; struct Site* reg[2]; int edgenbr; int sites[2]; }; struct GraphEdge { float x1, y1, x2, y2; int sites[2]; struct GraphEdge* next; }; struct Halfedge { struct Halfedge *ELleft, *ELright; struct Edge* ELedge; int ELrefcnt; char ELpm; struct Site* vertex; float ystar; struct Halfedge* PQnext; }; class VoronoiDiagramGenerator { public: VoronoiDiagramGenerator(); ~VoronoiDiagramGenerator(); bool generateVoronoi(float* xValues, float* yValues, int numPoints, float minX, float maxX, float minY, float maxY, float minDist = 0); void resetIterator() { iteratorEdges = allEdges; } bool getNext(float& x1, float& y1, float& x2, float& y2, int* s) { if (iteratorEdges == 0) return false; x1 = iteratorEdges->x1; x2 = iteratorEdges->x2; y1 = iteratorEdges->y1; y2 = iteratorEdges->y2; std::copy(iteratorEdges->sites, iteratorEdges->sites + 2, s); iteratorEdges = iteratorEdges->next; return true; } private: void cleanup(); void cleanupEdges(); char* getfree(struct Freelist* fl); struct Halfedge* PQfind(); int PQempty(); struct Halfedge** ELhash; struct Halfedge *HEcreate(), *ELleft(), *ELright(), *ELleftbnd(); struct Halfedge* HEcreate(struct Edge* e, int pm); struct Point PQ_min(); struct Halfedge* PQextractmin(); void freeinit(struct Freelist* fl, int size); void makefree(struct Freenode* curr, struct Freelist* fl); void geominit(); void plotinit(); bool voronoi(int triangulate); void ref(struct Site* v); void deref(struct Site* v); void endpoint(struct Edge* e, int lr, struct Site* s); void ELdelete(struct Halfedge* he); struct Halfedge* ELleftbnd(struct Point* p); struct Halfedge* ELright(struct Halfedge* he); void makevertex(struct Site* v); void out_triple(struct Site* s1, struct Site* s2, struct Site* s3); void PQinsert(struct Halfedge* he, struct Site* v, float offset); void PQdelete(struct Halfedge* he); bool ELinitialize(); void ELinsert(struct Halfedge* lb, struct Halfedge* newHe); struct Halfedge* ELgethash(int b); struct Halfedge* ELleft(struct Halfedge* he); struct Site* leftreg(struct Halfedge* he); void out_site(struct Site* s); bool PQinitialize(); int PQbucket(struct Halfedge* he); void clip_line(struct Edge* e); char* myalloc(unsigned n); int right_of(struct Halfedge* el, struct Point* p); struct Site* rightreg(struct Halfedge* he); struct Edge* bisect(struct Site* s1, struct Site* s2); float dist(struct Site* s, struct Site* t); struct Site* intersect(struct Halfedge* el1, struct Halfedge* el2, struct Point* p = 0); void out_bisector(struct Edge* e); void out_ep(struct Edge* e); void out_vertex(struct Site* v); struct Site* nextone(); void pushGraphEdge(float x1, float y1, float x2, float y2, int s[2]); void openpl(); void line(float x1, float y1, float x2, float y2, int s[2]); void circle(float x, float y, float radius); void range(float minX, float minY, float maxX, float maxY); struct Freelist hfl; struct Halfedge *ELleftend, *ELrightend; int ELhashsize; int triangulate, sorted, plot, debug; float xmin, xmax, ymin, ymax, deltax, deltay; struct Site* sites; int nsites; int siteidx; int sqrt_nsites; int nvertices; struct Freelist sfl; struct Site* bottomsite; int nedges; struct Freelist efl; int PQhashsize; struct Halfedge* PQhash; int PQcount; int PQmin; int ntry, totalsearch; float pxmin, pxmax, pymin, pymax, cradius; int total_alloc; float borderMinX, borderMaxX, borderMinY, borderMaxY; FreeNodeArrayList* allMemoryList; FreeNodeArrayList* currentMemoryBlock; GraphEdge* allEdges; GraphEdge* iteratorEdges; float minDistanceBetweenSites; }; int scomp(const void* p1, const void* p2); #endif