2018-11-07 11:24:06 -04:00
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
2018-12-04 11:34:07 -04:00
|
|
|
/*
|
|
|
|
* 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
|
2018-11-07 11:24:06 -04:00
|
|
|
* 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 <math.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2018-11-10 04:46:27 -04:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <algorithm>
|
2018-11-07 11:24:06 -04:00
|
|
|
|
|
|
|
#ifndef NULL
|
|
|
|
#define NULL 0
|
|
|
|
#endif
|
|
|
|
#define DELETED -2
|
|
|
|
|
|
|
|
#define le 0
|
|
|
|
#define re 1
|
|
|
|
|
2018-12-04 11:34:07 -04:00
|
|
|
struct Freenode
|
2018-11-07 11:24:06 -04:00
|
|
|
{
|
2018-12-04 11:34:07 -04:00
|
|
|
struct Freenode* nextfree;
|
2018-11-07 11:24:06 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
struct FreeNodeArrayList
|
|
|
|
{
|
2018-12-04 11:34:07 -04:00
|
|
|
struct Freenode* memory;
|
|
|
|
struct FreeNodeArrayList* next;
|
2018-11-07 11:24:06 -04:00
|
|
|
};
|
|
|
|
|
2018-12-04 11:34:07 -04:00
|
|
|
struct Freelist
|
2018-11-07 11:24:06 -04:00
|
|
|
{
|
2018-12-04 11:34:07 -04:00
|
|
|
struct Freenode* head;
|
|
|
|
int nodesize;
|
2018-11-07 11:24:06 -04:00
|
|
|
};
|
|
|
|
|
2018-12-04 11:34:07 -04:00
|
|
|
struct Point
|
2018-11-07 11:24:06 -04:00
|
|
|
{
|
2018-12-04 11:34:07 -04:00
|
|
|
float x, y;
|
|
|
|
Point() : x(0.0), y(0.0)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
Point(float x, float y) : x(x), y(y)
|
|
|
|
{
|
|
|
|
}
|
2018-11-07 11:24:06 -04:00
|
|
|
};
|
|
|
|
|
2018-12-04 11:34:07 -04:00
|
|
|
// structure used both for sites and for vertices
|
|
|
|
struct Site
|
2018-11-07 11:24:06 -04:00
|
|
|
{
|
2018-12-04 11:34:07 -04:00
|
|
|
struct Point coord;
|
|
|
|
int sitenbr;
|
|
|
|
int refcnt;
|
2018-11-07 11:24:06 -04:00
|
|
|
};
|
|
|
|
|
2018-12-04 11:34:07 -04:00
|
|
|
struct Edge
|
2018-11-07 11:24:06 -04:00
|
|
|
{
|
2018-12-04 11:34:07 -04:00
|
|
|
float a, b, c;
|
|
|
|
struct Site* ep[2];
|
|
|
|
struct Site* reg[2];
|
|
|
|
int edgenbr;
|
|
|
|
int sites[2];
|
2018-11-07 11:24:06 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
struct GraphEdge
|
|
|
|
{
|
2018-12-04 11:34:07 -04:00
|
|
|
float x1, y1, x2, y2;
|
|
|
|
int sites[2];
|
|
|
|
struct GraphEdge* next;
|
2018-11-07 11:24:06 -04:00
|
|
|
};
|
|
|
|
|
2018-12-04 11:34:07 -04:00
|
|
|
struct Halfedge
|
2018-11-07 11:24:06 -04:00
|
|
|
{
|
2018-12-04 11:34:07 -04:00
|
|
|
struct Halfedge *ELleft, *ELright;
|
|
|
|
struct Edge* ELedge;
|
|
|
|
int ELrefcnt;
|
|
|
|
char ELpm;
|
|
|
|
struct Site* vertex;
|
|
|
|
float ystar;
|
|
|
|
struct Halfedge* PQnext;
|
2018-11-07 11:24:06 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
class VoronoiDiagramGenerator
|
|
|
|
{
|
|
|
|
public:
|
2018-12-04 11:34:07 -04:00
|
|
|
VoronoiDiagramGenerator();
|
|
|
|
~VoronoiDiagramGenerator();
|
2018-11-07 11:24:06 -04:00
|
|
|
|
2018-12-04 11:34:07 -04:00
|
|
|
bool generateVoronoi(float* xValues, float* yValues, int numPoints, float minX, float maxX, float minY, float maxY,
|
|
|
|
float minDist = 0);
|
2018-11-07 11:24:06 -04:00
|
|
|
|
2018-12-04 11:34:07 -04:00
|
|
|
void resetIterator()
|
|
|
|
{
|
|
|
|
iteratorEdges = allEdges;
|
|
|
|
}
|
2018-11-07 11:24:06 -04:00
|
|
|
|
2018-12-04 11:34:07 -04:00
|
|
|
bool getNext(float& x1, float& y1, float& x2, float& y2, int* s)
|
|
|
|
{
|
|
|
|
if (iteratorEdges == 0)
|
|
|
|
return false;
|
2018-11-07 11:24:06 -04:00
|
|
|
|
2018-12-04 11:34:07 -04:00
|
|
|
x1 = iteratorEdges->x1;
|
|
|
|
x2 = iteratorEdges->x2;
|
|
|
|
y1 = iteratorEdges->y1;
|
|
|
|
y2 = iteratorEdges->y2;
|
|
|
|
std::copy(iteratorEdges->sites, iteratorEdges->sites + 2, s);
|
2018-11-07 11:24:06 -04:00
|
|
|
|
2018-12-04 11:34:07 -04:00
|
|
|
iteratorEdges = iteratorEdges->next;
|
2018-11-07 11:24:06 -04:00
|
|
|
|
2018-12-04 11:34:07 -04:00
|
|
|
return true;
|
|
|
|
}
|
2018-11-07 11:24:06 -04:00
|
|
|
|
|
|
|
private:
|
2018-12-04 11:34:07 -04:00
|
|
|
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;
|
2018-11-07 11:24:06 -04:00
|
|
|
};
|
|
|
|
|
2018-12-04 11:34:07 -04:00
|
|
|
int scomp(const void* p1, const void* p2);
|
2018-11-07 11:24:06 -04:00
|
|
|
|
|
|
|
#endif
|