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,
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
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
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
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
00176 b = x(s[1]);
00177 }
00178 return s;
00179 }
00180 } else {
00181
00182 while (q < a) {
00183 s = complex_.getNeighbour(1, s);
00184 assert(x(s[1]) == a);
00185 a = x(s[0]);
00186
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
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
00285
00286
00287
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_;
00307 Complex complex_;
00308 std::vector<Vertex*> myVertices_;
00309
00310 };
00311
00312 #endif