Voronoi.hh

00001 #ifndef __FASTJET__VORONOI_H__
00002 #define __FASTJET__VORONOI_H__
00003 
00004 //STARTHEADER
00005 // $Id: Voronoi.hh 1761 2010-09-16 10:43:18Z soyez $
00006 //
00007 // Copyright (c) 1994 by AT&T Bell Laboratories (see below)
00008 //
00009 //
00010 //----------------------------------------------------------------------
00011 // This file is included as part of FastJet but was mostly written by
00012 // S. Fortune in C, put into C++ with memory management by S
00013 // O'Sullivan, and with further interface and memeory management
00014 // modifications by Gregory Soyez.
00015 //
00016 // Permission to use, copy, modify, and distribute this software for
00017 // any purpose without fee is hereby granted, provided that this
00018 // entire notice is included in all copies of any software which is or
00019 // includes a copy or modification of this software and in all copies
00020 // of the supporting documentation for such software. THIS SOFTWARE IS
00021 // BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED WARRANTY.
00022 // IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY REPRESENTATION
00023 // OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY OF THIS
00024 // SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
00025 //
00026 //----------------------------------------------------------------------
00027 //ENDHEADER
00028 
00029 
00030 /*
00031 * The author of this software is Steven Fortune.  
00032 * Copyright (c) 1994 by AT&T Bell Laboratories.
00033 * Permission to use, copy, modify, and distribute this software for any
00034 * purpose without fee is hereby granted, provided that this entire notice
00035 * is included in all copies of any software which is or includes a copy
00036 * or modification of this software and in all copies of the supporting
00037 * documentation for such software.
00038 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
00039 * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY
00040 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
00041 * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
00042 */
00043 
00044 /* 
00045 * This code was originally written by Stephan Fortune in C code.  I,
00046 * Shane O'Sullivan, have since modified it, encapsulating it in a C++
00047 * class and, fixing memory leaks and adding accessors to the Voronoi
00048 * Edges.  Permission to use, copy, modify, and distribute this
00049 * software for any purpose without fee is hereby granted, provided
00050 * that this entire notice is included in all copies of any software
00051 * which is or includes a copy or modification of this software and in
00052 * all copies of the supporting documentation for such software.  THIS
00053 * SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
00054 * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY
00055 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
00056 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
00057 * PURPOSE.
00058 */
00059 
00060 #include "fastjet/ClusterSequenceWithArea.hh"
00061 #include <vector>
00062 #include <math.h>
00063 #include <stdlib.h>
00064 #include <string.h>
00065 
00066 #define DELETED -2
00067 #define le 0
00068 #define re 1
00069 
00070 //using namespace std;
00071 
00072 FASTJET_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
00073 
00074 /**
00075  * \if internal_doc
00076  * @ingroup internal
00077  * \class Point
00078  * class to handle a 2d point
00079  * \endif
00080  */
00081 class Point{
00082 public:
00083   /// defailt ctor
00084   Point() : x(0.0), y(0.0) {}
00085 
00086   /// ctor with initialisation
00087   Point(double _x, double _y) : x(_x), y(_y) {}
00088 
00089   /// addition
00090   inline Point operator + (const Point &p) const{
00091     return Point(x+p.x, y+p.y);
00092   }
00093 
00094   /// subtraction
00095   inline Point operator - (const Point &p) const{
00096     return Point(x-p.x, y-p.y);
00097   }
00098 
00099   /// scalar multiplication
00100   inline Point operator * (const double t) const{
00101     return Point(x*t, y*t);
00102   }
00103 
00104   /// vector coordinates
00105   double x,y;
00106 };
00107 
00108 
00109 /// norm of a vector
00110 inline double norm(const Point p){
00111   return p.x*p.x+p.y*p.y;
00112 }
00113 
00114 
00115 /// 2D vector product
00116 inline double vector_product(const Point &p1, const Point &p2){
00117   return p1.x*p2.y-p1.y*p2.x;
00118 }
00119 
00120 
00121 /// scalar product
00122 inline double scalar_product(const Point &p1, const Point &p2){
00123   return p1.x*p2.x+p1.y*p2.y;
00124 }
00125 
00126 
00127 /**
00128  * \if internal_doc
00129  * @ingroup internal
00130  * \class GraphEdge
00131  * handle an edge of the Voronoi Diagram.
00132  * \endif
00133  */
00134 class GraphEdge{
00135 public:
00136   /// coordinates of the extreme points
00137   double x1,y1,x2,y2;
00138 
00139   /// indices of the parent sites that define the edge
00140   int point1, point2;
00141 
00142   /// pointer to the next edge
00143   GraphEdge* next;
00144 };
00145 
00146 
00147 /**
00148  * \if internal_doc
00149  * @ingroup internal
00150  * \class Site
00151  * structure used both for particle sites and for vertices.
00152  * \endif
00153  */
00154 class Site{
00155  public:
00156   Point coord;
00157   int sitenbr;
00158   int refcnt;
00159 };
00160 
00161 
00162 
00163 class Freenode{
00164 public:
00165   Freenode *nextfree;
00166 };
00167 
00168 
00169 class FreeNodeArrayList{
00170 public:
00171   Freenode* memory;
00172   FreeNodeArrayList* next;
00173 };
00174 
00175 
00176 class Freelist{
00177 public:
00178   Freenode *head;
00179   int nodesize;
00180 };
00181 
00182 class Edge{
00183 public:
00184   double a,b,c;
00185   Site *ep[2];
00186   Site *reg[2];
00187   int edgenbr;
00188 };
00189 
00190 
00191 class Halfedge{
00192 public:
00193   Halfedge *ELleft, *ELright;
00194   Edge *ELedge;
00195   int ELrefcnt;
00196   char ELpm;
00197   Site *vertex;
00198   volatile double ystar;
00199   Halfedge *PQnext;
00200 };
00201 
00202 /**
00203  * \if internal_doc
00204  * @ingroup internal
00205  * \class VoronoiDiagramGenerator
00206  * Shane O'Sullivan C++ version of Stephan Fortune Voronoi diagram
00207  * generator
00208  * \endif
00209  */
00210 class VoronoiDiagramGenerator{
00211 public:
00212   VoronoiDiagramGenerator();
00213   ~VoronoiDiagramGenerator();
00214 
00215   bool generateVoronoi(std::vector<Point> *_parent_sites,
00216                        double minX, double maxX, double minY, double maxY, 
00217                        double minDist=0);
00218 
00219   inline void resetIterator(){
00220     iteratorEdges = allEdges;
00221   }
00222 
00223   bool getNext(GraphEdge **e){
00224     if(iteratorEdges == 0)
00225       return false;
00226     
00227     *e = iteratorEdges;
00228     iteratorEdges = iteratorEdges->next;
00229     return true;
00230   }
00231   
00232   std::vector<Point> *parent_sites;
00233   int n_parent_sites;
00234 
00235 private:
00236   void cleanup();
00237   void cleanupEdges();
00238   char *getfree(Freelist *fl);  
00239   Halfedge *PQfind();
00240   int PQempty();
00241         
00242   Halfedge **ELhash;
00243   Halfedge *HEcreate(), *ELleft(), *ELright(), *ELleftbnd();
00244   Halfedge *HEcreate(Edge *e,int pm);
00245   
00246   Point PQ_min();
00247   Halfedge *PQextractmin();     
00248   void freeinit(Freelist *fl,int size);
00249   void makefree(Freenode *curr,Freelist *fl);
00250   void geominit();
00251   void plotinit();
00252   bool voronoi(int triangulate);
00253   void ref(Site *v);
00254   void deref(Site *v);
00255   void endpoint(Edge *e,int lr,Site * s);
00256 
00257   void ELdelete(Halfedge *he);
00258   Halfedge *ELleftbnd(Point *p);
00259   Halfedge *ELright(Halfedge *he);
00260   void makevertex(Site *v);
00261   void out_triple(Site *s1, Site *s2,Site * s3);
00262   
00263   void PQinsert(Halfedge *he,Site * v, double offset);
00264   void PQdelete(Halfedge *he);
00265   bool ELinitialize();
00266   void ELinsert(Halfedge *lb, Halfedge *newHe);
00267   Halfedge * ELgethash(int b);
00268   Halfedge *ELleft(Halfedge *he);
00269   Site *leftreg(Halfedge *he);
00270   void out_site(Site *s);
00271   bool PQinitialize();
00272   int PQbucket(Halfedge *he);
00273   void clip_line(Edge *e);
00274   char *myalloc(unsigned n);
00275   int right_of(Halfedge *el,Point *p);
00276 
00277   Site *rightreg(Halfedge *he);
00278   Edge *bisect(Site *s1, Site *s2);
00279   double dist(Site *s,Site *t);
00280   Site *intersect(Halfedge *el1, Halfedge *el2, Point *p=0);
00281 
00282   void out_bisector(Edge *e);
00283   void out_ep(Edge *e);
00284   void out_vertex(Site *v);
00285   Site *nextone();
00286 
00287   void pushGraphEdge(double x1, double y1, double x2, double y2, 
00288                      Site *s1, Site *s2);
00289 
00290   void openpl();
00291   void circle(double x, double y, double radius);
00292   void range(double minX, double minY, double maxX, double maxY);
00293 
00294   Freelist hfl;
00295   Halfedge *ELleftend, *ELrightend;
00296   int ELhashsize;
00297   
00298   int triangulate, sorted, plot, debug;
00299   double xmin, xmax, ymin, ymax, deltax, deltay;
00300   
00301   Site *sites;
00302   int nsites;
00303   int siteidx;
00304   int sqrt_nsites;
00305   int nvertices;
00306   Freelist sfl;
00307   Site *bottomsite;
00308   
00309   int nedges;
00310   Freelist efl;
00311   int PQhashsize;
00312   Halfedge *PQhash;
00313   int PQcount;
00314   int PQmin;
00315   
00316   int ntry, totalsearch;
00317   double pxmin, pxmax, pymin, pymax, cradius;
00318   int total_alloc;
00319   
00320   double borderMinX, borderMaxX, borderMinY, borderMaxY;
00321   
00322   FreeNodeArrayList* allMemoryList;
00323   FreeNodeArrayList* currentMemoryBlock;
00324   
00325   GraphEdge* allEdges;
00326   GraphEdge* iteratorEdges;
00327   
00328   double minDistanceBetweenSites;
00329 };
00330 
00331 int scomp(const void *p1,const void *p2);
00332 
00333 
00334 FASTJET_END_NAMESPACE
00335 
00336 #endif