/****************************************************************************
 *   voronoi.h : 
 *   		 A wrap-up of Fortune's sweep line algorithm.
 *   Change Log :
 *		 Feb 13, 1998 Initial version,  Liujian Qian
 *
 *   $Id: gvoronoi.h,v 1.6 1998/08/23 19:45:03 qian Exp $
 ***************************************************************************/
#ifndef _VORONOI_H_
#define _VORONOI_H_

#include "gdatapipe.h"

/**
 * @internal
 */
struct FreeNode {
    struct FreeNode	*nextfree;
};

/**
 * @internal
 */
struct FreeList {
    struct FreeNode	*head;
    int			nodesize;
};

/**
 * @internal
 */
struct VPoint {
    double	x,y;
};

/**
 * @internal
 * structure used both for sites and for vertices 
 */
struct Site {
    VPoint	coord;
    int		sitenbr;
    int		refcnt;
};

/**
 * This struct defines the edges of a Voronoi diagram.
 * Each edge bisects two original sites. It may or may not
 * be closed on both ends.
 */
struct VEdge {
    int		edgenbr;
    double	a,b,c;  //linear parameter defining the line of the edge
    Site	*ep[2];	//the two end points (vertices) of the edge
    Site	*reg[2]; //the two original sites which this edge bisects	
    VEdge*	next;
};

/**
 * @internal
 */
struct HalfEdge {
    struct HalfEdge	*ELleft, *ELright;
    VEdge		*ELedge;
    int			ELrefcnt;
    char		ELpm;
    Site		*vertex;
    double		ystar;
    HalfEdge 		*PQnext;
};
 

/**
 * @short   A voronoi diagram generation class.
 *
 *    Given a set of 2D points, this class can generate the triangulation
 *    and voronoi diagrams out of it.
 */
class GVoronoi
{
    const   	int   le;	//left end point
    const   	int   re;	//right end point
    const	int   DELETED;

    int		n_edges, PQcount, PQmin, ntry, totalsearch;

    Site	*sites, *bottomsite;
    int		n_sites, siteidx, sqrt_nsites;
    int		n_vertices;

    FreeList	efl, hfl, sfl; //edge/half-edge/site free list
    HalfEdge	*ELleftend, *ELrightend;
    int		ELhashsize;
    HalfEdge	**ELhash;

    //the bounding box of all sites
    double	xmin, xmax, ymin, ymax, deltax, deltay;
    //the bounding box for cliping half edges.
    double      pxmin, pymin, pxmax, pymax, cradius;      
    
    HalfEdge*	PQhash;
    int 	PQhashsize;

    VEdge*	diagram_edges;
    DataPipe    edges;  	//edges of the Voronoi diagram
public:
    DataPipe    end_points;   //of the edges
    int		n_real_edges, n_end_points;

private:
    ///
    // sites stuff
    Site*       nextOne();

    ///
    // heap stuff
    int		total_alloc;
    DataPipe	mem_keeper;	//keep pointers to all the memory allocated
    void 	freeInit(FreeList* fl, int size);
    char* 	getFree(FreeList* fl);
    void	makeFree(FreeNode* curr, FreeList* fl);
    char*	myAlloc(unsigned n);

    //plot stuff
    void 	plotInit();
    int 	clipLine(VEdge* e, double& x1, double& x2, double& y1, double& y2);

    // geometry stuff
    void	geomInit();
    Site*	intersect(HalfEdge *el1, HalfEdge *el2);
    float 	dist(Site*, Site*);

    void	PQinitialize();
    void  	PQinsert(HalfEdge* he, Site* v, double offset);
    void 	PQdelete(HalfEdge* he);
    int 	PQbucket(HalfEdge* he);
    int		PQempty();
    VPoint 	PQ_min();
    HalfEdge*	PQextractmin();

    VEdge*	bisect(Site*, Site*);
    void 	endpoint(VEdge *e, int lr, Site *s);
    int		right_of(HalfEdge* el, VPoint *p);
    int		makeVertex(Site *v);
    int		deref(Site *v);
    int		ref(Site *v);
    
    void	addToDiagram(VEdge* e);
    
    void	ELinitialize();
    HalfEdge    *HEcreate(VEdge*, int);
    void	ELinsert(HalfEdge*, HalfEdge* );
    HalfEdge*	ELgethash(int);
    HalfEdge*	ELleftbnd(VPoint* );
    void	ELdelete(HalfEdge* );
    HalfEdge*	ELright(HalfEdge*);
    HalfEdge*	ELleft(HalfEdge*);
    Site*	leftreg(HalfEdge*);
    Site*	rightreg(HalfEdge* );

    /**
     * comparison function between two sites.
     * This function is used by qsort() to sort all sites
     * in the order of their y-value, so that a sweep line
     * from bottom to top can be used.
     */
    static int	scomp(void*, void*);

public:    
    GVoronoi();
    virtual ~GVoronoi();

    /** 
     * initialize all the sites.
     * initialize all the sites by supplying the coordinates
     * of them as a (x,y) array.
     * This method must be called before the compute method.
     * Internally each site will be assigned a number beginning w/
     * zero.
     * @param  coords is the x y coordinates of all the sites.
     *		n     is the number of sites. 
     */
    void        sitesInit(double coords[], int n); 
    /**
     * computes the voronoi diagram for the set of sites. Once it
     * is finished you can get the list of diagram edges and vertices
     * using the methods getEdges() and getVertices(). Note that the
     * vertices are those generated by bisecting edges and *does* not 
     * include the original sites.
     */
    void	compute	();

    /**
     * return number of edges in the Voronoi diagram
     */
    int		numEdges() const {return n_edges;} ;
    /**
     * return number of vertices on the voronoi diagram.
     * (Note: they are not the original sites!)
     */
    int		numVertices() const {return n_vertices;};
    /**
     * return the pipe containing the coordinates of all the
     * edges. The following code segment steps through all the
     * edges:
     *  <pre>
     * 	double x1, y1, x2, y2;
     *  DataPipe& p = myvoronoi.getEdges(); 
     *  p.seek(0);  //reset pipe pointer to the begining!
     *  while(!p.eop()) {
     *          p>>x1>>y1>>x2>>y2;
     *	        drawLine(x1,y1, x2, y2);
     *  }; 
     *  </pre>
     */
    DataPipe&   getEdgesPipe() {edges.seek(0); return edges; }
    /**
     * return the first voronoi diagram edge. Use the public filed 'next'
     * to retrieve all the other voronoi edges.
     */
    VEdge*	getEdges() {return diagram_edges; }
    int		outputEdge(VEdge* e, double&, double&, double&, double&);    
    /**
     * get the vertices pipe. The following code segment steps
     * through all the vertices of the voronoi diagram:
     * <pre>
     * double x, y;
     * DataPipe& p = myvoronoi.getVertices(); 
     * p.seek(0);  //reset pipe pointer to the begining!
     * while(!p.eop()) {
     *          p>>x>>y;
     *	        drawPoint(x,y);
     * };
     * </pre>
     */
    DataPipe& 	getVertices() {end_points.seek(0); return end_points; }
};

    
#endif





Documentation generated by lqian@lqian-sun on Wed Jul 14 09:36:10 EDT 1999