Delaunay1.h

Go to the documentation of this file.
00001 #ifndef Delaunay1_HEADER
00002 #define Delaunay1_HEADER
00003 
00004 #ifdef HAVE_CONFIG_H
00005 # include <config.h>
00006 #endif
00007 
00008 #include <topology/Complex1.h>
00009 #include "IncrementalDelaunay.h"
00010 
00011 #undef DEBUG_DELAUNAY
00012 #define DEBUG_DELAUNAY 1
00013 
00016 template <unsigned ambient,
00017   class Vertex_, class SimplexData,
00018   class VertexPrinter>
00019 class IncrementalDelaunay<ambient, 1, Vertex_, SimplexData, VertexPrinter> {
00020 public:
00021 static const unsigned topological = 1;
00022 typedef Vertex_ Vertex;
00023 typedef Geometry::Point<ambient> Point; 
00024 typedef Geometry::Point<topological> PPoint; 
00025 typedef Geometry::ProjectionPlane<ambient, topological> ProjectionPlane;
00026 typedef Geometry::BoundingBox<topological> BoundingBox;
00027 typedef Geometry::CenterRadius<ambient> CenterRadius;
00028 typedef SimplicialComplex<topological, Vertex_, SimplexData, VertexPrinter> Complex;
00029 typedef typename Complex::Simplex Simplex;
00030 typedef typename Complex::Cavity Cavity;
00031 typedef typename Complex::Star Star;
00032 
00033 /***************************************************************************
00034  ***************************************************************************/
00035 public:
00036 IncrementalDelaunay(const ProjectionPlane& plane, Vertex *a, Vertex *b)
00037   : plane_(plane)
00038   , complex_(isOriented(a,b) ? a : b, isOriented(a,b) ? b : a)
00039 {
00040   assert(isOriented());
00041 }
00042 
00043 static IncrementalDelaunay *fromSimplex(const ProjectionPlane& plane, Vertex *a, Vertex *b) {
00044   return new IncrementalDelaunay(plane, a, b);
00045 }
00046 
00047 static IncrementalDelaunay *fromSimplex(Vertex *a, Vertex *b) {
00048   boost::array<Point, 2> p;
00049   p[0] = a->toPoint();
00050   p[1] = b->toPoint();
00051   return new IncrementalDelaunay(ProjectionPlane(p.begin(), p.end()), a, b);
00052 }
00053 
00054 static IncrementalDelaunay *fromSimplex(const vector<Vertex*>& verts) {
00055   assert(verts.size() == 2);
00056   return fromSimplex(verts[0], verts[1]);
00057 }
00058 
00059 template<class vertex_iterator>
00060 static IncrementalDelaunay *computeDelaunaySlowlyFromVertices (vertex_iterator begin, vertex_iterator end)
00061 {
00062   assert(begin != end);
00063   Vertex *a = *begin;
00064   ++begin;
00065   assert(begin != end);
00066   Vertex *b = *begin;
00067   assert(++begin == end);
00068 
00069   return fromSimplex(a, b);
00070 }
00071 
00072 static IncrementalDelaunay *makeBoundingSimplex(
00073     const ProjectionPlane& plane,
00074     BoundingBox box, // copy
00075     double buffer) {
00076   if (buffer != 0.0) { box = box.scale(buffer); }
00077   box.scale(buffer);
00078   Vertex *a = new Vertex(plane.unproject(box.mincorner));
00079   Vertex *b = new Vertex(plane.unproject(box.mincorner + PPoint(box.extent)));
00080   IncrementalDelaunay *id = new IncrementalDelaunay(plane, a, b);
00081   id->myVertices_.push_back(a);
00082   id->myVertices_.push_back(b);
00083   return id;
00084 }
00085 
00086 template <class point_iterator>
00087 static IncrementalDelaunay *makeBoundingSimplex(point_iterator begin, point_iterator end, double buffer) {
00088   ProjectionPlane plane(begin, end);
00089   BoundingBox box(begin, end, plane);
00090   return makeBoundingSimplex(plane, box, buffer);
00091 }
00092 
00093 /***************************************************************************
00094  ***************************************************************************/
00095 const Complex& getComplex() const {
00096   return complex_;
00097 }
00098 Complex& getComplexRW() {
00099   return complex_;
00100 }
00101 const Simplex& getHandle() const {
00102   return complex_.getHandle();
00103 }
00104 
00105 /***************************************************************************
00106  ***************************************************************************/
00107 #ifdef NDEBUG
00108 #define unused(p)
00109 #else
00110 #define unused(p) p
00111 #endif
00112 void computeCavity(const Simplex& s, const Point& unused(p), Cavity& cavity, bool append = false) const {
00113   // The cavity in 1-d is just the single simplex.
00114   if (!append) { assert(cavity.empty()); }
00115   assert(inSimplexAffine(s, p));
00116   cavity.add(s);
00117 }
00118 
00119 void computeCavity(const Simplex& s, const Point& unused(p), Cavity& cavity, vector<Simplex>& neighbours, bool append = false) const {
00120 #undef unused
00121   assert(isMember(s));
00122   if (!append) {
00123     assert(cavity.empty());
00124     assert(neighbours.empty());
00125   }
00126   assert(inSimplexAffine(s, p));
00127   cavity.add(s);
00128 
00129   // Get both (or just one, or none) the neighbours of s.
00130   Simplex n = complex_.getNeighbour(0, s);
00131   if (complex_.isMember(n)) { neighbours.push_back(n); }
00132   n = complex_.getNeighbour(1, s);
00133   if (complex_.isMember(n)) { neighbours.push_back(n); }
00134 }
00135 
00136 void computeStar(const Cavity& cavity, Vertex *v, Star& star) {
00137   assert(cavity.size() == 1);
00138   complex_.computeStar(*cavity.begin(), v, star);
00139 }
00140 
00141 void insertVertex(const Cavity& cavity, Star& star) {
00142   complex_.replaceCavity(cavity, star);
00143 }
00144 
00145 void insertVertex(const Simplex& s, Vertex *v) {
00146   complex_.replaceCavity(s, v);
00147 }
00148 void insertVertex(const Cavity& cavity, Vertex *v) {
00149   complex_.replaceCavity(cavity, v);
00150 }
00151 
00152 void expensiveInsertVertex(Vertex *v) {
00153   insertVertex(expensiveLocate(v), v);
00154 }
00155 
00156 Simplex expensiveLocate(const Vertex *v) {
00157   return expensiveLocate(v->toPoint());
00158 }
00159 
00160 Simplex expensiveLocate(const Point& p) {
00161   Simplex s = getHandle();
00162   double q = x(p);
00163   double a = x(s[0]);
00164   double b = x(s[1]);
00165   assert(a < b);
00166 
00167   if (q > a) {
00168     // go right until we find our simplex (could be right here!)
00169     if (q < b) {
00170       return s;
00171     } else {
00172       while (q > b) {
00173         s = complex_.getNeighbour(0, s);
00174         assert(x(s[0]) == b);
00175         // a = x(s[0]);
00176         b = x(s[1]);
00177       }
00178       return s;
00179     }
00180   } else {
00181     // go left until we find our simplex
00182     while (q < a) {
00183       s = complex_.getNeighbour(1, s);
00184       assert(x(s[1]) == a);
00185       a = x(s[0]);
00186       // b = x(s[1]);
00187     }
00188     return s;
00189   }
00190 }
00191 
00192 
00193 /***************************************************************************
00194  ***************************************************************************/
00195 private:
00196 double x(const Vertex *v) const {
00197   return plane_.project(v->toPoint())[0];
00198 }
00199 double x(const Point& p) const {
00200   return plane_.project(p)[0];
00201 }
00202 
00203 public:
00204 const ProjectionPlane& getPlane() const {
00205   return plane_;
00206 }
00207 
00208 CenterRadius circumcenter(const Simplex& s) const {
00209   assert(isMember(s));
00210   return Geometry::template circumcenter_segment<ambient>(s[0]->toPoint(), s[1]->toPoint());
00211 }
00212 
00213 static double radiusEdge2(const Simplex&) {
00214   return 1.0;
00215 }
00216 
00217 static double computeSigma(const Simplex&) {
00218   return 1.0;
00219 }
00220 
00221 static double radiusRadius(const Simplex&) {
00222   return 1.0;
00223 }
00224 
00225 /***************************************************************************
00226  ***************************************************************************/
00227 bool isMember(const Simplex& s) const {
00228   return getComplex().isMember(s);
00229 }
00230 
00231 bool inSphere(const Simplex& s, const Point& p) const {
00232   // TODO: make robust
00233   CenterRadius cr = circumcenter(s);
00234   return p.dist2(cr.center) < cr.radius2;
00235 }
00236 
00237 bool inSphereAffine(const Simplex& s, const Point& p) const {
00238   double a = x(s[0]);
00239   double b = x(s[1]);
00240   double q = x(p);
00241   assert (a < b);
00242   return a < q && q < b;
00243 }
00244 
00245 bool inSimplexAffine(const Simplex& s, const Point& p) const {
00246   return inSphereAffine(s, p);
00247 }
00248 
00249 bool isOriented(const Simplex& s) const {
00250   return isOriented(s[0], s[1]);
00251 }
00252 bool isOriented(const Vertex *a, const Vertex *b) const {
00253   bool isO = x(a) < x(b);
00254 #if DEBUG_DELAUNAY
00255   if (!isO) {
00256     printf("Unoriented segment: Vertices %s and %s (at %s and %s)\n",
00257         a->toString().c_str(), b->toString().c_str(),
00258         a->toPoint().toString().c_str(), b->toPoint().toString().c_str());
00259     printf("Project to %g and %g\n", x(a), x(b));
00260   }
00261 #endif
00262   return isO;
00263 }
00264 
00265 private:
00266 struct CheckOriented {
00267   const IncrementalDelaunay *del;
00268   CheckOriented(const IncrementalDelaunay *del): del(del) { }
00269   static bool canEnter(const Simplex&) { return true; }
00270   bool choose(const Simplex& s) { return !del->isOriented(s); }
00271 };
00272 public:
00273 bool isOriented() const {
00274   CheckOriented co(this);
00275   return !complex_.dfsBySimplex(co, getHandle());
00276 }
00277 static bool isDelaunay() { return true; }
00278 
00279 /***************************************************************************
00280  ***************************************************************************/
00281 public:
00282 
00283 /***************************************************************************
00284  * \name Data access
00285  * We have to be careful with what we return, in order to handle void data.
00286  * We forward the request on to the complex, and then we pull out the
00287  * user's part of it.
00288  ***************************************************************************/
00289 typedef typename hudson::Bucket<SimplexData>::reference data_ref;
00290 typedef typename hudson::Bucket<SimplexData>::const_reference data_const_ref;
00291 data_ref getDataRW(const Simplex& s) {
00292   return complex_.getDataRW(s);
00293 }
00294 
00296 data_const_ref getData(const Simplex& s) const {
00297   return complex_.getData(s);
00298 }
00299 
00300 
00301 
00302 /***************************************************************************
00303  ***************************************************************************/
00304 
00305 private:
00306 ProjectionPlane plane_; // MUST be before complex_
00307 Complex complex_;
00308 std::vector<Vertex*> myVertices_;
00309 
00310 };
00311 
00312 #endif

Generated on Thu Mar 27 19:04:12 2008 by  doxygen 1.4.6