00001 #include <iostream>
00002 #include <iomanip>
00003 #include <limits>
00004 #include <list>
00005 #include <set>
00006 #include <stack>
00007 #include <assert.h>
00008 #include "geometry.hpp"
00009 #include "properties.hpp"
00010 #include "coloring.hpp"
00011 #include "query_point.hpp"
00012 #include <CGAL/IO/Qt_widget.h>
00013 #include <CGAL/IO/Qt_widget_Polygon_2.h>
00014
00015 using namespace Arak;
00016 using namespace Arak::Geometry;
00017
00018 #ifdef SANITY_CHECK
00019
00020 #define TEST_VALIDITY test();
00021 #else
00022
00023 #define TEST_VALIDITY if (Arak::Util::default_random.uniform(10000) == 0) test();
00024 #endif
00025
00026 double Coloring::Vertex::logSine() {
00027 Geometry::Point a, b = this->point(), c;
00028 if (type() == INTERIOR) {
00029 a = getPrevVertex()->point();
00030 c = getNextVertex()->point();
00031 } else if (type() == BOUNDARY) {
00032 if (hasPrevIntEdge())
00033 a = getPrevVertex()->point();
00034 else
00035 a = getNextVertex()->point();
00036 c = getNextBdEdge()->getNextVertex()->point();
00037 if (CGAL::angle(a, b, c) != CGAL::ACUTE)
00038 c = getPrevBdEdge()->getPrevVertex()->point();
00039 } else assert(false);
00040 return logSineB(a, b, c);
00041 }
00042
00043 bool Coloring::InteriorEdge::crosses(const Geometry::Point& a,
00044 const Geometry::Point& b) const {
00045 return Arak::Geometry::crosses(*this, a, b);
00046 }
00047
00048 Geometry::Point Coloring::Edge::randomPoint(Arak::Util::Random& random) const {
00049 return random.uniform(this->segment());
00050 }
00051
00052 Geometry::Point
00053 Coloring::BoundaryEdge::randomPoint(Arak::Util::Random& random) const {
00054 Geometry::Point p = Edge::randomPoint(random);
00055 #ifndef EXACT_GEOM_CXN
00056
00057
00058
00059
00060
00061 const Coloring::VertexHandle c1 = getPrevCornerVertex();
00062 const Coloring::VertexHandle c2 = getNextCornerVertex();
00063 if (c1->x() == c2->x())
00064 p = Geometry::Point(c1->x(), p.y());
00065 else if (c1->y() == c2->y())
00066 p = Geometry::Point(p.x(), c1->y());
00067 else
00068 assert(false);
00069 #endif
00070 return p;
00071 }
00072
00073 void Coloring::test() const {
00074
00075 for (int i = 0; i < numVertices(Vertex::INTERIOR); i++) {
00076 VertexHandle v = getVertex(Vertex::INTERIOR, i);
00077 assert(v->index == i);
00078 assert(v->type() == Vertex::INTERIOR);
00079 assert(v == v->getNextIntEdge()->getPrevVertex());
00080 assert(v == v->getPrevIntEdge()->getNextVertex());
00081 #ifdef EXACT_GEOM_CXN
00082 assert(interior(*v));
00083 #endif
00084 }
00085
00086 for (int i = 0; i < numVertices(Vertex::BOUNDARY); i++) {
00087 VertexHandle v = getVertex(Vertex::BOUNDARY, i);
00088 assert(v->index == i);
00089 assert(v->type() == Vertex::BOUNDARY);
00090 assert(v->hasPrevIntEdge() || v->hasNextIntEdge());
00091 assert(!v->hasNextIntEdge() ||
00092 (v == v->getNextIntEdge()->getPrevVertex()));
00093 assert(!v->hasPrevIntEdge() ||
00094 (v == v->getPrevIntEdge()->getNextVertex()));
00095 assert(v == v->getNextBdEdge()->getPrevVertex());
00096 assert(v == v->getPrevBdEdge()->getNextVertex());
00097 #ifdef EXACT_GEOM_CXN
00098 assert(boundary(*v));
00099 #endif
00100 }
00101
00102 for (int i = 0; i < numVertices(Vertex::CORNER); i++) {
00103 VertexHandle v = getVertex(Vertex::CORNER, i);
00104 assert(v->index == i);
00105 assert(v->type() == Vertex::CORNER);
00106 assert(v == v->getNextBdEdge()->getPrevVertex());
00107 assert(v == v->getPrevBdEdge()->getNextVertex());
00108 assert(v->Geometry::Point::operator==(bd[i]));
00109 }
00110
00111 for (int i = 0; i < numInteriorEdges(); i++) {
00112 IntEdgeHandle e = getInteriorEdge(i);
00113 assert(e->index == i);
00114 assert(!(e->getNextVertex() == e->getPrevVertex()));
00115 assert(e == e->getNextVertex()->getPrevIntEdge());
00116 assert(e == e->getPrevVertex()->getNextIntEdge());
00117 assert((e->getNextVertex()->type() == Vertex::INTERIOR) ||
00118 (e->getNextVertex()->type() == Vertex::BOUNDARY));
00119 assert((e->getPrevVertex()->type() == Vertex::INTERIOR) ||
00120 (e->getPrevVertex()->type() == Vertex::BOUNDARY));
00121 assert(Segment(*(e->getPrevVertex()), *(e->getNextVertex())) ==
00122 ((Segment)*e));
00123 assert(e->getNextVertex()->Geometry::Point::operator!=(*(e->getPrevVertex())));
00124 assert(CGAL::to_double(CGAL::squared_distance(*(e->getPrevVertex()),
00125 *(e->getNextVertex()))) >=
00126 minEdgeLengthSq);
00127 #ifdef TRIANGULATION_EDGE_INDEX
00128
00129 TFaceHandle fh;
00130 int index;
00131 assert(tri.is_edge(e->prevVertex->tvh, e->nextVertex->tvh, fh, index));
00132 assert(fh->is_constrained(index));
00133 assert(tri.is_valid(false, 0));
00134 #endif
00135 }
00136
00137 for (int i = 0; i < numInteriorEdges(); i++) {
00138 IntEdgeHandle e = getInteriorEdge(i);
00139 for (int j = 0; j < numInteriorEdges(); j++) {
00140 if (i == j) continue;
00141 IntEdgeHandle f = getInteriorEdge(j);
00142 assert(!e->crosses(f->source(), f->target()));
00143 }
00144 }
00145
00146 for (int i = 0; i < numBoundaryEdges(); i++) {
00147 BdEdgeHandle e = getBoundaryEdge(i);
00148 assert(e->index == i);
00149 assert(!(e->getNextVertex() == e->getPrevVertex()));
00150 assert(e == e->getNextVertex()->getPrevBdEdge());
00151 assert(e == e->getPrevVertex()->getNextBdEdge());
00152 assert((e->getNextVertex()->type() == Vertex::BOUNDARY) ||
00153 (e->getNextVertex()->type() == Vertex::CORNER));
00154 assert((e->getPrevVertex()->type() == Vertex::BOUNDARY) ||
00155 (e->getPrevVertex()->type() == Vertex::CORNER));
00156 assert(Segment(*(e->getPrevVertex()), *(e->getNextVertex())) ==
00157 ((Segment)*e));
00158 assert(e->getNextVertex()->point() != e->getPrevVertex()->point());
00159
00160 if (e->getPrevVertex()->type() == Vertex::CORNER)
00161 assert(e->getPrevCornerVertex() == e->getPrevVertex());
00162 else
00163 assert(e->getPrevCornerVertex() ==
00164 e->getPrevVertex()->getPrevCornerVertex());
00165 if (e->getNextVertex()->type() == Vertex::CORNER)
00166 assert(e->getNextCornerVertex() == e->getNextVertex());
00167 else
00168 assert(e->getNextCornerVertex() ==
00169 e->getNextVertex()->getNextCornerVertex());
00170 }
00171
00172 for (int i = 0; i < queryPoints->size(); i++)
00173 assert(color(queryPoints->point(i)) ==
00174 queryPoints->point(i).color());
00175 }
00176
00177 Coloring::IntEdgeHandle Coloring::newInteriorEdge(VertexHandle prev,
00178 VertexHandle next) {
00179
00180 assert(prev->point() != next->point());
00181
00182 IntEdgeHandle e = intEdgeStore.newItem();
00183 e->index = interiorEdges.size();
00184 interiorEdges.push_back(e);
00185 e->nextVertex = e->prevVertex = VertexHandle();
00186
00187 e->Segment::operator=(Segment(prev->point(), next->point()));
00188
00189 e->prevVertex = prev;
00190 e->nextVertex = next;
00191
00192 assert(!(e->nextVertex->prevIntEdge.valid()));
00193 assert(!(e->prevVertex->nextIntEdge.valid()));
00194 e->nextVertex->prevIntEdge = e->prevVertex->nextIntEdge = e;
00195 #ifdef GRID_EDGE_INDEX
00196
00197 typedef InteriorEdgeIndex::LineCellIterator Iterator;
00198 Iterator it(*intEdgeIndex, *prev, *next, Iterator::SEGMENT()), end;
00199 while (it != end) {
00200 InteriorEdgeIndex::Cell& cell = *it;
00201 InteriorEdgeIndex::Cell::Entry entry = cell.add(e);
00202 if (e->unused.empty())
00203 e->entries.push_front(entry);
00204 else {
00205 InteriorEdge::CellEntryList::iterator jt = e->unused.begin();
00206 *jt = entry;
00207 e->entries.splice(e->entries.begin(), e->unused, jt);
00208 }
00209 ++it;
00210 }
00211 #endif
00212 #ifdef TRIANGULATION_EDGE_INDEX
00213
00214 tri.insert_constraint(prev->tvh, next->tvh);
00215 #endif
00216
00217 return *e;
00218 }
00219
00220 Coloring::BdEdgeHandle Coloring::newBoundaryEdge(VertexHandle prev,
00221 VertexHandle next,
00222 VertexHandle prevCorner,
00223 VertexHandle nextCorner) {
00224 assert(prev->type() != Vertex::INTERIOR);
00225 assert(next->type() != Vertex::INTERIOR);
00226
00227 assert(prev->point() != next->point());
00228
00229 BdEdgeHandle e = bdEdgeStore.newItem();
00230 e->index = boundaryEdges.size();
00231 boundaryEdges.push_back(e);
00232 e->nextVertex = e->prevVertex = VertexHandle();
00233
00234 e->Segment::operator=(Segment(*prev, *next));
00235
00236 e->prevVertex = prev;
00237 e->nextVertex = next;
00238
00239 assert(!(e->nextVertex->prevBdEdge.valid()));
00240 assert(!(e->prevVertex->nextBdEdge.valid()));
00241 e->nextVertex->prevBdEdge = e->prevVertex->nextBdEdge = e;
00242 e->prevCorner = prevCorner;
00243 e->nextCorner = nextCorner;
00244
00245 return *e;
00246 }
00247
00248 void Coloring::initialize(Geometry::Rectangle &boundary,
00249 int gridRows, int gridCols,
00250 double minEdgeLength) {
00251 clear();
00252 this->minEdgeLengthSq = minEdgeLength * minEdgeLength;
00253 bd = boundary;
00254 intEdgeIndex = new InteriorEdgeIndex(boundary, gridRows, gridCols);
00255 queryPoints = NULL;
00256
00257 VertexHandle firstVertex = newVertex(Vertex::CORNER, bd[0]);
00258 VertexHandle prevVertex = firstVertex;
00259 for (int i = 1; i < 4; i++) {
00260 VertexHandle nextVertex = newVertex(Vertex::CORNER, bd[i]);
00261 newBoundaryEdge(prevVertex, nextVertex, prevVertex, nextVertex);
00262 prevVertex = nextVertex;
00263 }
00264 newBoundaryEdge(*prevVertex, firstVertex, *prevVertex, firstVertex);
00265 assert(numVertices(Vertex::CORNER) == 4);
00266 assert(numBoundaryEdges() == 4);
00267
00268
00269
00270 queryPoints = new QueryPointIndex(boundary, 1, 1);
00271
00272 for (int i = 0; i < queryPoints->size(); i++) {
00273 assert(interior(queryPoints->point(i)));
00274 queryPoints->point(i).setColor(WHITE);
00275 }
00276 TEST_VALIDITY;
00277 #ifdef SANITY_CHECK
00278 std::cerr << "WARNING: compiled with SANITY_CHECK on; expect poor performance" << std::endl;
00279 #endif
00280 }
00281
00282 Coloring::Coloring()
00283 : intEdgeIndex(NULL), queryPoints(NULL) {
00284 Geometry::Rectangle r(Geometry::Kernel::RT(0), Geometry::Kernel::RT(0),
00285 Geometry::Kernel::RT(1), Geometry::Kernel::RT(1));
00286 initialize(r, 10, 10);
00287 }
00288
00289 Coloring::Coloring(Geometry::Rectangle &boundary,
00290 int gridRows, int gridCols, double minEdgeLength)
00291 : intEdgeIndex(NULL), queryPoints(NULL) {
00292 initialize(boundary, gridRows, gridCols, minEdgeLength);
00293 }
00294
00295 Coloring::Coloring(const Arak::Util::PropertyMap& props)
00296 : intEdgeIndex(NULL), queryPoints(NULL) {
00297 using namespace Arak::Util;
00298 double x, y, width, height;
00299 int rows, cols;
00300 assert(parse(getp(props, "arak.coloring.xmin"), x));
00301 assert(parse(getp(props, "arak.coloring.ymin"), y));
00302 assert(parse(getp(props, "arak.coloring.width"), width));
00303 assert(parse(getp(props, "arak.coloring.height"), height));
00304 assert(parse(getp(props, "arak.coloring.rows"), rows));
00305 assert(parse(getp(props, "arak.coloring.cols"), cols));
00306 Geometry::Rectangle boundary(x, y, x + width, y + height);
00307 double mel = 0.0;
00308 if (hasp(props, "arak.coloring.min_edge_length"))
00309 assert(parse(getp(props, "arak.coloring.min_edge_length"), mel));
00310 initialize(boundary, rows, cols, mel);
00311 }
00312
00313 void Coloring::clear() {
00314
00315 if (intEdgeIndex != NULL) {
00316 delete intEdgeIndex;
00317 intEdgeIndex = NULL;
00318 }
00319
00320 if (queryPoints != NULL) {
00321 delete queryPoints;
00322 queryPoints = NULL;
00323 }
00324
00325 for (unsigned int i = 0; i < interiorVertices.size(); i++)
00326 delete &*(interiorVertices[i]);
00327 interiorVertices.clear();
00328 for (unsigned int i = 0; i < boundaryVertices.size(); i++)
00329 delete &*(boundaryVertices[i]);
00330 boundaryVertices.clear();
00331 for (unsigned int i = 0; i < cornerVertices.size(); i++)
00332 delete &*(cornerVertices[i]);
00333 cornerVertices.clear();
00334
00335 for (unsigned int i = 0; i < interiorEdges.size(); i++)
00336 delete &*(interiorEdges[i]);
00337 interiorEdges.clear();
00338 for (unsigned int i = 0; i < boundaryEdges.size(); i++)
00339 delete &*(boundaryEdges[i]);
00340 boundaryEdges.clear();
00341 }
00342
00343 Coloring::~Coloring() {
00344 clear();
00345 }
00346
00347 void Coloring::addQueryPoints(const QueryPointIndex& index) const {
00348
00349 for (int i = 0; i < index.size(); i++) {
00350 const QueryPoint q = index.point(i);
00351 q.setColor(color(q));
00352 }
00353
00354 QueryPointIndex *newQueryPoints =
00355 new QueryPointIndex(*queryPoints, index);
00356
00357 delete queryPoints;
00358 queryPoints = newQueryPoints;
00359 TEST_VALIDITY;
00360 }
00361
00362 Coloring::VertexHandle Coloring::newVertex(Vertex::Type type,
00363 const Geometry::Point& p) {
00364 VertexHandle v = vertexStore.newItem();
00365
00366
00367 v->t = type;
00368 v->Geometry::Point::operator=(p);
00369 #ifdef TRIANGULATION_EDGE_INDEX
00370 v->tvh = tri.insert(p);
00371 v->tvh->vertex = v;
00372 #endif
00373 switch (type) {
00374 case Vertex::INTERIOR:
00375 v->index = interiorVertices.size();
00376 interiorVertices.push_back(v);
00377 break;
00378 case Vertex::BOUNDARY:
00379 v->index = boundaryVertices.size();
00380 boundaryVertices.push_back(v);
00381 break;
00382 case Vertex::CORNER:
00383 v->index = cornerVertices.size();
00384 cornerVertices.push_back(v);
00385 break;
00386 default:
00387 assert(false);
00388 }
00389
00390 v->nextIntEdge = v->prevIntEdge = IntEdgeHandle();
00391 v->nextBdEdge = v->prevBdEdge = BdEdgeHandle();
00392 return *v;
00393 }
00394
00395 void Coloring::freeVertex(Coloring::VertexHandle& v) {
00396
00397 assert(!(v->nextIntEdge.valid()));
00398 assert(!(v->prevIntEdge.valid()));
00399 assert(!(v->nextBdEdge.valid()));
00400 assert(!(v->prevBdEdge.valid()));
00401 #ifdef TRIANGULATION_EDGE_INDEX
00402
00403 tri.remove(v->tvh);
00404 v->tvh = TVertexHandle();
00405 #endif
00406
00407 int n;
00408 switch (v->type()) {
00409 case Vertex::INTERIOR:
00410 n = interiorVertices.size();
00411 if (n > 1) {
00412 VertexHandle w = interiorVertices[n - 1];
00413 interiorVertices[n - 1] = interiorVertices[v->index];
00414 interiorVertices[v->index] = w;
00415 w->index = v->index;
00416 }
00417 interiorVertices.pop_back();
00418 break;
00419 case Vertex::BOUNDARY:
00420 n = boundaryVertices.size();
00421 if (n > 1) {
00422 VertexHandle w = boundaryVertices[n - 1];
00423 boundaryVertices[n - 1] = boundaryVertices[v->index];
00424 boundaryVertices[v->index] = w;
00425 w->index = v->index;
00426 }
00427 boundaryVertices.pop_back();
00428 break;
00429 case Vertex::CORNER:
00430 n = cornerVertices.size();
00431 if (n > 1) {
00432 VertexHandle w = cornerVertices[n - 1];
00433 cornerVertices[n - 1] = cornerVertices[v->index];
00434 cornerVertices[v->index] = w;
00435 w->index = v->index;
00436 }
00437 cornerVertices.pop_back();
00438 break;
00439 default:
00440 assert(false);
00441 }
00442 v->t = Vertex::INVALID;
00443 v->index = -1;
00444 vertexStore.deleteItem(&*v);
00445
00446 v = VertexHandle();
00447 }
00448
00449 void Coloring::freeEdge(Coloring::IntEdgeHandle& e) {
00450 #ifdef TRIANGULATION_EDGE_INDEX
00451
00452 TFaceHandle fh;
00453 int i;
00454 assert(tri.is_edge(e->prevVertex->tvh, e->nextVertex->tvh, fh, i));
00455 tri.remove_constrained_edge(fh, i);
00456 #endif
00457 #ifdef GRID_EDGE_INDEX
00458
00459 for (InteriorEdge::CellEntryList::iterator it = e->entries.begin();
00460 it != e->entries.end(); it++)
00461 it->remove();
00462 e->unused.splice(e->unused.begin(), e->entries,
00463 e->entries.begin(),
00464 e->entries.end());
00465 #endif
00466
00467 if (e->nextVertex.valid()) {
00468 e->nextVertex->prevIntEdge = IntEdgeHandle();
00469 e->nextVertex = VertexHandle();
00470 }
00471 if (e->prevVertex.valid()) {
00472 e->prevVertex->nextIntEdge = IntEdgeHandle();
00473 e->prevVertex = VertexHandle();
00474 }
00475
00476 int n = interiorEdges.size();
00477 if (n > 1) {
00478 IntEdgeHandle f = interiorEdges[n - 1];
00479 interiorEdges[n - 1] = interiorEdges[e->index];
00480 interiorEdges[e->index] = f;
00481 f->index = e->index;
00482 }
00483 interiorEdges.pop_back();
00484 e->index = -1;
00485 intEdgeStore.deleteItem(&*e);
00486
00487 e = IntEdgeHandle();
00488 }
00489
00490 void Coloring::freeEdge(Coloring::BdEdgeHandle& e) {
00491
00492 if (e->nextVertex.valid()) {
00493 e->nextVertex->prevBdEdge = BdEdgeHandle();
00494 e->nextVertex = VertexHandle();
00495 }
00496 if (e->prevVertex.valid()) {
00497 e->prevVertex->nextBdEdge = BdEdgeHandle();
00498 e->prevVertex = VertexHandle();
00499 }
00500
00501 int n = boundaryEdges.size();
00502 if (n > 1) {
00503 BdEdgeHandle f = boundaryEdges[n - 1];
00504 boundaryEdges[n - 1] = boundaryEdges[e->index];
00505 boundaryEdges[e->index] = f;
00506 f->index = e->index;
00507 }
00508 boundaryEdges.pop_back();
00509 e->index = -1;
00510 bdEdgeStore.deleteItem(&*e);
00511
00512 e = BdEdgeHandle();
00513 }
00514
00515 bool Coloring::deleteVertex(VertexHandle v, TEST_IF_VALID_TAG) const {
00516 TEST_VALIDITY;
00517 assert(v->type() == Vertex::INTERIOR);
00518
00519 if (v->getNextVertex()->hasNextIntEdge() &&
00520 v->getNextVertex()->getNextVertex() == v->getPrevVertex())
00521 return false;
00522 IntEdgeHandle xv = v->getPrevIntEdge();
00523 IntEdgeHandle vy = v->getNextIntEdge();
00524 VertexHandle x = xv->getPrevVertex();
00525 VertexHandle y = vy->getNextVertex();
00526 Geometry::Point a = *v, b = *x, c = *y;
00527
00528 if ((minEdgeLengthSq > 0.0) &&
00529 (CGAL::to_double(CGAL::squared_distance(b, c)) < minEdgeLengthSq))
00530 return false;
00531
00532
00533
00534
00535 if (!compatible(b, c))
00536 return false;
00537 return true;
00538 }
00539
00540 bool Coloring::deleteVertex(VertexHandle& v, DO_WITHOUT_TEST_TAG) {
00541 IntEdgeHandle xv = v->getPrevIntEdge();
00542 IntEdgeHandle vy = v->getNextIntEdge();
00543 VertexHandle x = xv->getPrevVertex();
00544 VertexHandle y = vy->getNextVertex();
00545 Geometry::Point a = *v, b = *x, c = *y;
00546
00547 notifyEdgeWillBeRemoved(xv);
00548 notifyEdgeWillBeRemoved(vy);
00549 notifyVertexWillBeRemoved(x);
00550 notifyVertexWillBeRemoved(v);
00551 notifyVertexWillBeRemoved(y);
00552
00553 freeEdge(xv);
00554 freeEdge(vy);
00555 freeVertex(v);
00556 IntEdgeHandle xy = newInteriorEdge(x, y);
00557
00558 notifyEdgeHasBeenAdded(xy);
00559 notifyVertexHasBeenAdded(x);
00560 notifyVertexHasBeenAdded(y);
00561
00562 recolored(a, b, c);
00563 TEST_VALIDITY;
00564 return true;
00565 }
00566
00567 bool Coloring::deleteVertex(VertexHandle& v, DO_IF_VALID_TAG) {
00568 if (!deleteVertex(v, TEST_IF_VALID_TAG())) return false;
00569 return deleteVertex(v, DO_WITHOUT_TEST_TAG());
00570 }
00571
00572 bool Coloring::splitEdge(IntEdgeHandle e,
00573 const Geometry::Point& p,
00574 TEST_IF_VALID_TAG) const {
00575 VertexHandle u = e->getPrevVertex();
00576 VertexHandle v = e->getNextVertex();
00577 assert(p != *u);
00578 assert(p != *v);
00579
00580 if ((minEdgeLengthSq > 0.0) &&
00581 ((CGAL::to_double(CGAL::squared_distance(*u, p)) < minEdgeLengthSq) ||
00582 (CGAL::to_double(CGAL::squared_distance(p, *v)) < minEdgeLengthSq)))
00583 return false;
00584
00585
00586
00587 if (!compatible(*u, p) || !compatible(p, *v))
00588 return false;
00589 return true;
00590 }
00591
00592 bool Coloring::splitEdge(IntEdgeHandle& e,
00593 const Geometry::Point& p,
00594 DO_WITHOUT_TEST_TAG) {
00595 VertexHandle u = e->getPrevVertex();
00596 VertexHandle v = e->getNextVertex();
00597
00598 notifyEdgeWillBeRemoved(e);
00599 notifyVertexWillBeRemoved(u);
00600 notifyVertexWillBeRemoved(v);
00601
00602 freeEdge(e);
00603 VertexHandle x = newVertex(Vertex::INTERIOR, p);
00604
00605 IntEdgeHandle ux = newInteriorEdge(u, x);
00606 IntEdgeHandle xv = newInteriorEdge(x, v);
00607
00608 notifyVertexHasBeenAdded(x);
00609 notifyVertexHasBeenAdded(u);
00610 notifyVertexHasBeenAdded(v);
00611 notifyEdgeHasBeenAdded(ux);
00612 notifyEdgeHasBeenAdded(xv);
00613
00614 recolored(*u, *v, p);
00615 TEST_VALIDITY;
00616 return true;
00617 }
00618
00619 bool Coloring::splitEdge(IntEdgeHandle& e,
00620 const Geometry::Point& p,
00621 DO_IF_VALID_TAG) {
00622 if (!splitEdge(e, p, TEST_IF_VALID_TAG())) return false;
00623 return splitEdge(e, p, DO_WITHOUT_TEST_TAG());
00624 }
00625
00626 bool Coloring::newInteriorTriangle(const Geometry::Point& xp,
00627 const Geometry::Point& yp,
00628 const Geometry::Point& zp,
00629 TEST_IF_VALID_TAG) const {
00630 #ifdef EXACT_GEOM_CXN
00631
00632 assert(interior(xp) && interior(yp) && interior(zp));
00633 #endif
00634
00635 if ((minEdgeLengthSq > 0.0) &&
00636 ((CGAL::to_double(CGAL::squared_distance(xp, yp)) < minEdgeLengthSq) ||
00637 (CGAL::to_double(CGAL::squared_distance(yp, zp)) < minEdgeLengthSq) ||
00638 (CGAL::to_double(CGAL::squared_distance(zp, xp)) < minEdgeLengthSq)))
00639 return false;
00640
00641 if (!compatible(xp, yp) ||
00642 !compatible(yp, zp) ||
00643 !compatible(zp, xp))
00644 return false;
00645 return true;
00646 }
00647
00648 Coloring::VertexHandle
00649 Coloring::newInteriorTriangle(const Geometry::Point& xp,
00650 const Geometry::Point& yp,
00651 const Geometry::Point& zp,
00652 DO_WITHOUT_TEST_TAG) {
00653
00654 VertexHandle x = newVertex(Vertex::INTERIOR, xp);
00655 VertexHandle y = newVertex(Vertex::INTERIOR, yp);
00656 VertexHandle z = newVertex(Vertex::INTERIOR, zp);
00657
00658 IntEdgeHandle xy = newInteriorEdge(x, y);
00659 IntEdgeHandle yz = newInteriorEdge(y, z);
00660 IntEdgeHandle zx = newInteriorEdge(z, x);
00661
00662 notifyVertexHasBeenAdded(x);
00663 notifyVertexHasBeenAdded(y);
00664 notifyVertexHasBeenAdded(z);
00665 notifyEdgeHasBeenAdded(xy);
00666 notifyEdgeHasBeenAdded(yz);
00667 notifyEdgeHasBeenAdded(zx);
00668
00669 recolored(xp, yp, zp);
00670 TEST_VALIDITY;
00671 return x;
00672 }
00673
00674 Coloring::VertexHandle
00675 Coloring::newInteriorTriangle(const Geometry::Point& xp,
00676 const Geometry::Point& yp,
00677 const Geometry::Point& zp,
00678 DO_IF_VALID_TAG) {
00679 if (!newInteriorTriangle(xp, yp, zp, TEST_IF_VALID_TAG()))
00680 return VertexHandle();
00681 else return newInteriorTriangle(xp, yp, zp, DO_WITHOUT_TEST_TAG());
00682 }
00683
00684 bool Coloring::newBoundaryTriangle(Coloring::BdEdgeHandle e,
00685 const Geometry::Point& up,
00686 const Geometry::Point& vp,
00687 const Geometry::Point& wp,
00688 TEST_IF_VALID_TAG) const {
00689 #ifdef EXACT_GEOM_CXN
00690
00691 assert(interior(wp));
00692
00693 assert(e->has_on(up) && e->has_on(vp));
00694 #endif
00695
00696
00697 assert(e->source() != up);
00698 assert(e->source() != vp);
00699 assert(e->target() != up);
00700 assert(e->target() != vp);
00701
00702 if ((minEdgeLengthSq > 0.0) &&
00703 ((CGAL::to_double(CGAL::squared_distance(vp, wp)) < minEdgeLengthSq) ||
00704 (CGAL::to_double(CGAL::squared_distance(wp, up)) < minEdgeLengthSq)))
00705 return false;
00706
00707 if (!compatible(vp, wp) || !compatible(wp, up))
00708 return false;
00709 return true;
00710 }
00711
00712 Coloring::VertexHandle
00713 Coloring::newBoundaryTriangle(Coloring::BdEdgeHandle e,
00714 const Geometry::Point& up,
00715 const Geometry::Point& vp,
00716 const Geometry::Point& wp,
00717 DO_WITHOUT_TEST_TAG) {
00718 const int oldNumBdEdges = numBoundaryEdges();
00719
00720 VertexHandle u = newVertex(Vertex::BOUNDARY, up);
00721 VertexHandle v = newVertex(Vertex::BOUNDARY, vp);
00722 VertexHandle w = newVertex(Vertex::INTERIOR, wp);
00723
00724 IntEdgeHandle uw = newInteriorEdge(u, w);
00725 IntEdgeHandle wv = newInteriorEdge(w, v);
00726
00727 VertexHandle p = e->getPrevVertex();
00728 VertexHandle q = e->getNextVertex();
00729 VertexHandle prevCorner = e->getPrevCornerVertex();
00730 VertexHandle nextCorner = e->getNextCornerVertex();
00731 freeEdge(e);
00732 if (squared_distance(*p, *u) < squared_distance(*p, *v)) {
00733 newBoundaryEdge(p, u, prevCorner, nextCorner);
00734 newBoundaryEdge(u, v, prevCorner, nextCorner);
00735 newBoundaryEdge(v, q, prevCorner, nextCorner);
00736 } else {
00737 newBoundaryEdge(p, v, prevCorner, nextCorner);
00738 newBoundaryEdge(v, u, prevCorner, nextCorner);
00739 newBoundaryEdge(u, q, prevCorner, nextCorner);
00740 }
00741
00742 notifyVertexHasBeenAdded(u);
00743 notifyVertexHasBeenAdded(v);
00744 notifyVertexHasBeenAdded(w);
00745 notifyEdgeHasBeenAdded(uw);
00746 notifyEdgeHasBeenAdded(wv);
00747
00748 recolored(up, vp, wp);
00749 assert(numBoundaryEdges() - 2 == oldNumBdEdges);
00750 TEST_VALIDITY;
00751 return u;
00752 }
00753
00754 Coloring::VertexHandle
00755 Coloring::newBoundaryTriangle(Coloring::BdEdgeHandle e,
00756 const Geometry::Point& up,
00757 const Geometry::Point& vp,
00758 const Geometry::Point& wp,
00759 DO_IF_VALID_TAG) {
00760 if (!newBoundaryTriangle(e, up, vp, wp, TEST_IF_VALID_TAG()))
00761 return VertexHandle();
00762 else return newBoundaryTriangle(e, up, vp, wp, DO_WITHOUT_TEST_TAG());
00763 }
00764
00765 bool Coloring::newCornerTriangle(VertexHandle corner,
00766 const Geometry::Point& u,
00767 const Geometry::Point& v,
00768 TEST_IF_VALID_TAG) const {
00769 TEST_VALIDITY;
00770 assert(u != *corner);
00771 assert(v != *corner);
00772
00773 if ((minEdgeLengthSq > 0.0) &&
00774 (CGAL::to_double(CGAL::squared_distance(u, v)) < minEdgeLengthSq))
00775 return false;
00776 return compatible(u, v);
00777 }
00778
00779 Coloring::VertexHandle Coloring::newCornerTriangle(VertexHandle corner,
00780 const Geometry::Point& u,
00781 const Geometry::Point& v,
00782 DO_WITHOUT_TEST_TAG) {
00783 TEST_VALIDITY;
00784 const int oldNumBdEdges = numBoundaryEdges();
00785
00786 BdEdgeHandle prevBdEdge = corner->getPrevBdEdge();
00787 VertexHandle prevCorner = prevBdEdge->getPrevCornerVertex();
00788 #ifdef EXACT_GEOM_CXN
00789 assert(prevBdEdge->has_on(u));
00790 #endif
00791 VertexHandle prevBdVertex = prevBdEdge->getPrevVertex();
00792 VertexHandle newPrevBdVertex = newVertex(Vertex::BOUNDARY, u);
00793 freeEdge(prevBdEdge);
00794 prevBdEdge = newBoundaryEdge(newPrevBdVertex, corner, prevCorner, corner);
00795 newBoundaryEdge(prevBdVertex, newPrevBdVertex, prevCorner, corner);
00796
00797 BdEdgeHandle nextBdEdge = corner->getNextBdEdge();
00798 VertexHandle nextCorner = nextBdEdge->getNextCornerVertex();
00799 #ifdef EXACT_GEOM_CXN
00800 assert(nextBdEdge->has_on(v));
00801 #endif
00802 VertexHandle nextBdVertex = nextBdEdge->getNextVertex();
00803 VertexHandle newNextBdVertex = newVertex(Vertex::BOUNDARY, v);
00804 freeEdge(nextBdEdge);
00805 nextBdEdge = newBoundaryEdge(corner, newNextBdVertex, corner, nextCorner);
00806 newBoundaryEdge(newNextBdVertex, nextBdVertex, corner, nextCorner);
00807
00808 IntEdgeHandle interiorEdge =
00809 newInteriorEdge(newPrevBdVertex, newNextBdVertex);
00810
00811
00812 notifyVertexHasBeenAdded(newPrevBdVertex);
00813 notifyVertexHasBeenAdded(newNextBdVertex);
00814 notifyEdgeHasBeenAdded(interiorEdge);
00815
00816 recolored(u, v, *corner);
00817 TEST_VALIDITY;
00818 assert(numBoundaryEdges() - 2 == oldNumBdEdges);
00819 return newPrevBdVertex;
00820 }
00821
00822 Coloring::VertexHandle Coloring::newCornerTriangle(VertexHandle corner,
00823 const Geometry::Point& u,
00824 const Geometry::Point& v,
00825 DO_IF_VALID_TAG) {
00826 if (!newCornerTriangle(corner, u, v, TEST_IF_VALID_TAG())) return false;
00827 else return newCornerTriangle(corner, u, v, DO_WITHOUT_TEST_TAG());
00828 }
00829
00830 bool Coloring::deleteIntTriangle(VertexHandle vh, TEST_IF_VALID_TAG) const {
00831
00832 if (vh->type() != Vertex::INTERIOR) return false;
00833 if (!vh->hasNextIntEdge()) return false;
00834 VertexHandle vi = vh->getNextVertex();
00835 if (vi->type() != Vertex::INTERIOR) return false;
00836 if (!vi->hasNextIntEdge()) return false;
00837 VertexHandle vj = vi->getNextVertex();
00838 if (vj->type() != Vertex::INTERIOR) return false;
00839 if (!vj->hasNextIntEdge()) return false;
00840 if (vj->getNextVertex() != vh) return false;
00841 return true;
00842 }
00843
00844 bool Coloring::deleteIntTriangle(VertexHandle& vh, DO_WITHOUT_TEST_TAG) {
00845
00846 VertexHandle va = vh;
00847 IntEdgeHandle ab = va->getNextIntEdge();
00848 VertexHandle vb = ab->getNextVertex();
00849 IntEdgeHandle bc = vb->getNextIntEdge();
00850 VertexHandle vc = bc->getNextVertex();
00851 IntEdgeHandle ca = vc->getNextIntEdge();
00852 Geometry::Point pa = va->point();
00853 Geometry::Point pb = vb->point();
00854 Geometry::Point pc = vc->point();
00855
00856 notifyEdgeWillBeRemoved(ab);
00857 notifyEdgeWillBeRemoved(bc);
00858 notifyEdgeWillBeRemoved(ca);
00859 notifyVertexWillBeRemoved(va);
00860 notifyVertexWillBeRemoved(vb);
00861 notifyVertexWillBeRemoved(vc);
00862
00863 freeEdge(ab);
00864 freeEdge(bc);
00865 freeEdge(ca);
00866 freeVertex(va);
00867 freeVertex(vb);
00868 freeVertex(vc);
00869 vh = VertexHandle();
00870
00871 recolored(pa, pb, pc);
00872 TEST_VALIDITY;
00873 return true;
00874 }
00875
00876 bool Coloring::deleteIntTriangle(VertexHandle& vh, DO_IF_VALID_TAG) {
00877 if (!deleteIntTriangle(vh, TEST_IF_VALID_TAG())) return false;
00878 else return deleteIntTriangle(vh, DO_WITHOUT_TEST_TAG());
00879 }
00880
00881 bool Coloring::deleteBdTriangle(VertexHandle vh, TEST_IF_VALID_TAG) const {
00882
00883 if (vh->hasPrevIntEdge()) vh = vh->getPrevVertex();
00884 if (vh->hasPrevIntEdge()) vh = vh->getPrevVertex();
00885
00886
00887 if (vh->type() != Vertex::BOUNDARY) return false;
00888
00889 VertexHandle vi = vh->getNextVertex();
00890 if (vi->type() != Vertex::INTERIOR) return false;
00891 if (!vi->hasNextIntEdge()) return false;
00892 VertexHandle vj = vi->getNextVertex();
00893 if (vj->type() != Vertex::BOUNDARY) return false;
00894
00895 if (vh->getNextCornerVertex() != vj->getNextCornerVertex())
00896 return false;
00897 return true;
00898 }
00899
00900 void Coloring::disconnectFromBd(VertexHandle v) {
00901 assert(v->type() == Vertex::BOUNDARY);
00902 BdEdgeHandle prevBoundaryEdge = v->getPrevBdEdge();
00903 BdEdgeHandle nextBoundaryEdge = v->getNextBdEdge();
00904 VertexHandle prevVertex = prevBoundaryEdge->getPrevVertex();
00905 VertexHandle nextVertex = nextBoundaryEdge->getNextVertex();
00906 VertexHandle prevCorner = prevBoundaryEdge->getPrevCornerVertex();
00907 VertexHandle nextCorner = nextBoundaryEdge->getNextCornerVertex();
00908 freeEdge(prevBoundaryEdge);
00909 freeEdge(nextBoundaryEdge);
00910 newBoundaryEdge(prevVertex, nextVertex, prevCorner, nextCorner);
00911 }
00912
00913 bool Coloring::deleteBdTriangle(VertexHandle& vh, DO_WITHOUT_TEST_TAG) {
00914
00915 if (vh->hasPrevIntEdge()) vh = vh->getPrevVertex();
00916 if (vh->hasPrevIntEdge()) vh = vh->getPrevVertex();
00917 VertexHandle va = vh;
00918 IntEdgeHandle ab = va->getNextIntEdge();
00919 VertexHandle vb = ab->getNextVertex();
00920 IntEdgeHandle bc = vb->getNextIntEdge();
00921 VertexHandle vc = bc->getNextVertex();
00922 Geometry::Point pa = va->point();
00923 Geometry::Point pb = vb->point();
00924 Geometry::Point pc = vc->point();
00925
00926 notifyEdgeWillBeRemoved(ab);
00927 notifyEdgeWillBeRemoved(bc);
00928 notifyVertexWillBeRemoved(va);
00929 notifyVertexWillBeRemoved(vb);
00930 notifyVertexWillBeRemoved(vc);
00931
00932 freeEdge(ab);
00933 freeEdge(bc);
00934 disconnectFromBd(va);
00935 disconnectFromBd(vc);
00936 freeVertex(va);
00937 freeVertex(vb);
00938 freeVertex(vc);
00939 vh = VertexHandle();
00940
00941 recolored(pa, pb, pc);
00942 TEST_VALIDITY;
00943 return true;
00944 }
00945
00946 bool Coloring::deleteBdTriangle(VertexHandle& vh, DO_IF_VALID_TAG) {
00947 if (!deleteBdTriangle(vh, TEST_IF_VALID_TAG())) return false;
00948 else return deleteBdTriangle(vh, DO_WITHOUT_TEST_TAG());
00949 }
00950
00951 bool Coloring::deleteCornerTriangle(VertexHandle vh, TEST_IF_VALID_TAG) const {
00952
00953 if (vh->hasPrevIntEdge()) vh = vh->getPrevVertex();
00954
00955
00956 if (vh->type() != Vertex::BOUNDARY) return false;
00957
00958 VertexHandle vi = vh->getNextVertex();
00959 if (vi->type() != Vertex::BOUNDARY) return false;
00960 return true;
00961 }
00962
00963 bool Coloring::deleteCornerTriangle(VertexHandle& vh, DO_WITHOUT_TEST_TAG) {
00964
00965 if (vh->hasPrevIntEdge()) vh = vh->getPrevVertex();
00966 VertexHandle va = vh;
00967 IntEdgeHandle ab = va->getNextIntEdge();
00968 VertexHandle vb = ab->getNextVertex();
00969 VertexHandle vaNextCorner = va->getNextCornerVertex();
00970 VertexHandle vbNextCorner = vb->getNextCornerVertex();
00971 Geometry::Point pa = va->point();
00972 Geometry::Point pb = vb->point();
00973 Geometry::Point pc;
00974 if (vaNextCorner->getNextCornerVertex() == vbNextCorner)
00975 pc = vaNextCorner->point();
00976 else if (vbNextCorner->getNextCornerVertex() == vaNextCorner)
00977 pc = vbNextCorner->point();
00978
00979 notifyEdgeWillBeRemoved(ab);
00980 notifyVertexWillBeRemoved(va);
00981 notifyVertexWillBeRemoved(vb);
00982
00983 freeEdge(ab);
00984 disconnectFromBd(va);
00985 disconnectFromBd(vb);
00986 freeVertex(va);
00987 freeVertex(vb);
00988 vh = VertexHandle();
00989
00990 recolored(pa, pb, pc);
00991 TEST_VALIDITY;
00992 return true;
00993 }
00994
00995 bool Coloring::deleteCornerTriangle(VertexHandle& vh, DO_IF_VALID_TAG) {
00996 if (!deleteCornerTriangle(vh, TEST_IF_VALID_TAG())) return false;
00997 else return deleteCornerTriangle(vh, DO_WITHOUT_TEST_TAG());
00998 }
00999
01000 bool Coloring::moveIntVertex(Coloring::VertexHandle v,
01001 const Geometry::Point& p,
01002 TEST_IF_VALID_TAG) const {
01003 assert(v->type() == Vertex::INTERIOR);
01004 #ifdef EXACT_GEOM_CXN
01005 assert(interior(p));
01006 #endif
01007 if (v->point() == p) return true;
01008
01009 if ((minEdgeLengthSq > 0.0) &&
01010 ((CGAL::to_double(CGAL::squared_distance(p, v->getNextVertex()->point())) < minEdgeLengthSq) ||
01011 (CGAL::to_double(CGAL::squared_distance(p, v->getPrevVertex()->point())) < minEdgeLengthSq)))
01012 return false;
01013 if (!compatible(p, v->getNextVertex()->point()) ||
01014 !compatible(p, v->getPrevVertex()->point()))
01015 return false;
01016 return true;
01017 }
01018
01019 bool Coloring::moveIntVertex(Coloring::VertexHandle& v,
01020 const Geometry::Point& p,
01021 DO_WITHOUT_TEST_TAG) {
01022 IntEdgeHandle uv = v->getPrevIntEdge();
01023 VertexHandle u = uv->getPrevVertex();
01024 IntEdgeHandle vw = v->getNextIntEdge();
01025 VertexHandle w = vw->getNextVertex();
01026
01027 notifyEdgeWillBeRemoved(uv);
01028 notifyEdgeWillBeRemoved(vw);
01029 notifyVertexWillBeRemoved(u);
01030 notifyVertexWillBeRemoved(v);
01031 notifyVertexWillBeRemoved(w);
01032
01033 Geometry::Point oldLoc = *v;
01034 freeEdge(uv);
01035 freeEdge(vw);
01036 freeVertex(v);
01037 v = newVertex(Vertex::INTERIOR, p);
01038 uv = newInteriorEdge(u, v);
01039 vw = newInteriorEdge(v, w);
01040
01041 notifyVertexHasBeenAdded(u);
01042 notifyVertexHasBeenAdded(v);
01043 notifyVertexHasBeenAdded(w);
01044 notifyEdgeHasBeenAdded(uv);
01045 notifyEdgeHasBeenAdded(vw);
01046
01047 recolored(*u, p, *w, oldLoc);
01048 TEST_VALIDITY;
01049 return true;
01050 }
01051
01052 bool Coloring::moveIntVertex(Coloring::VertexHandle& v,
01053 const Geometry::Point& p,
01054 DO_IF_VALID_TAG) {
01055 if (!moveIntVertex(v, p, TEST_IF_VALID_TAG())) return false;
01056 return moveIntVertex(v, p, DO_WITHOUT_TEST_TAG());
01057 }
01058
01059 bool Coloring::moveVertexAlongBd(Coloring::VertexHandle v,
01060 const Geometry::Point& p,
01061 TEST_IF_VALID_TAG) const {
01062 TEST_VALIDITY;
01063
01064
01065 assert(v->type() == Vertex::BOUNDARY);
01066 #ifdef EXACT_GEOM_CXN
01067 assert(v->getPrevBdEdge()->has_on(p) || v->getNextBdEdge()->has_on(p));
01068 #endif
01069 if (v->point() == p) return true;
01070
01071
01072
01073 bool isRoot = v->hasNextIntEdge();
01074 IntEdgeHandle e = isRoot ? v->getNextIntEdge() : v->getPrevIntEdge();
01075 VertexHandle u = isRoot ? e->getNextVertex() : e->getPrevVertex();
01076 if ((minEdgeLengthSq > 0.0) &&
01077 (CGAL::to_double(CGAL::squared_distance(*u, p)) < minEdgeLengthSq))
01078 return false;
01079 if (!compatible(*u, p)) return false;
01080 return true;
01081 }
01082
01083 bool Coloring::moveVertexAlongBd(Coloring::VertexHandle& v,
01084 const Geometry::Point& p,
01085 DO_WITHOUT_TEST_TAG) {
01086 const int oldNumBdEdges = numBoundaryEdges();
01087
01088
01089 bool isRoot = v->hasNextIntEdge();
01090 IntEdgeHandle e = isRoot ? v->getNextIntEdge() : v->getPrevIntEdge();
01091 VertexHandle u = isRoot ? e->getNextVertex() : e->getPrevVertex();
01092
01093 const Geometry::Point oldLoc = v->point();
01094 BdEdgeHandle prevBdEdge = v->getPrevBdEdge();
01095 BdEdgeHandle nextBdEdge = v->getNextBdEdge();
01096 VertexHandle prevCorner = nextBdEdge->getPrevCornerVertex();
01097 VertexHandle nextCorner = nextBdEdge->getNextCornerVertex();
01098 VertexHandle nextBdVertex = nextBdEdge->getNextVertex();
01099 VertexHandle prevBdVertex = prevBdEdge->getPrevVertex();
01100
01101 notifyEdgeWillBeRemoved(e);
01102 notifyVertexWillBeRemoved(u);
01103 notifyVertexWillBeRemoved(v);
01104
01105 freeEdge(e);
01106 freeEdge(prevBdEdge);
01107 freeEdge(nextBdEdge);
01108 freeVertex(v);
01109
01110 v = newVertex(Vertex::BOUNDARY, p);
01111 e = isRoot ? newInteriorEdge(v, u) : newInteriorEdge(u, v);
01112 prevBdEdge = newBoundaryEdge(prevBdVertex, v, prevCorner, nextCorner);
01113 nextBdEdge = newBoundaryEdge(v, nextBdVertex, prevCorner, nextCorner);
01114
01115 notifyVertexHasBeenAdded(u);
01116 notifyVertexHasBeenAdded(v);
01117 notifyEdgeHasBeenAdded(e);
01118
01119 recolored(*u, oldLoc, p);
01120 assert(oldNumBdEdges == numBoundaryEdges());
01121 TEST_VALIDITY;
01122 return true;
01123 }
01124
01125 bool Coloring::moveVertexAlongBd(Coloring::VertexHandle& v,
01126 const Geometry::Point& p,
01127 DO_IF_VALID_TAG) {
01128 if (!moveVertexAlongBd(v, p, TEST_IF_VALID_TAG())) return false;
01129 return moveVertexAlongBd(v, p, DO_WITHOUT_TEST_TAG());
01130 }
01131
01132 bool Coloring::moveBdVertexPastCorner(Coloring::BdEdgeHandle bdEdge,
01133 const Geometry::Point& p,
01134 TEST_IF_VALID_TAG) const {
01135 TEST_VALIDITY;
01136 bool prevIsCorner =
01137 (bdEdge->getPrevVertex()->type() == Coloring::Vertex::CORNER);
01138 Coloring::VertexHandle corner =
01139 (prevIsCorner ? bdEdge->getPrevVertex() : bdEdge->getNextVertex());
01140 Coloring::VertexHandle bdVertex =
01141 (prevIsCorner ? bdEdge->getNextVertex() : bdEdge->getPrevVertex());
01142 assert(bdVertex->type() == Coloring::Vertex::BOUNDARY);
01143 #ifdef EXACT_GEOM_CXN
01144 Coloring::BdEdgeHandle otherEdge =
01145 (prevIsCorner ? corner->getPrevBdEdge() : corner->getNextBdEdge());
01146 assert(otherEdge->has_on(p));
01147 #endif
01148 bool isRoot = bdVertex->hasNextIntEdge();
01149 Coloring::IntEdgeHandle intEdge = (isRoot ?
01150 bdVertex->getNextIntEdge() :
01151 bdVertex->getPrevIntEdge());
01152 Coloring::VertexHandle adjVertex = (isRoot ?
01153 intEdge->getNextVertex() :
01154 intEdge->getPrevVertex());
01155
01156
01157 if ((adjVertex->type() == Vertex::BOUNDARY) &&
01158 ((prevIsCorner && (adjVertex->getNextCornerVertex() == corner)) ||
01159 (!prevIsCorner && (adjVertex->getPrevCornerVertex() == corner))))
01160 return false;
01161
01162 if ((minEdgeLengthSq > 0.0) &&
01163 (CGAL::to_double(CGAL::squared_distance(p, *adjVertex)) < minEdgeLengthSq))
01164 return false;
01165
01166
01167 if (!compatible(p, *adjVertex)) return false;
01168 return true;
01169 }
01170
01171 bool Coloring::moveBdVertexPastCorner(Coloring::BdEdgeHandle& bdEdge,
01172 const Geometry::Point& p,
01173 DO_WITHOUT_TEST_TAG) {
01174 const int oldNumBdEdges = numBoundaryEdges();
01175 bool prevIsCorner =
01176 (bdEdge->getPrevVertex()->type() == Coloring::Vertex::CORNER);
01177 Coloring::VertexHandle corner =
01178 (prevIsCorner ? bdEdge->getPrevVertex() : bdEdge->getNextVertex());
01179 Coloring::VertexHandle bdVertex =
01180 (prevIsCorner ? bdEdge->getNextVertex() : bdEdge->getPrevVertex());
01181 assert(bdVertex->type() == Coloring::Vertex::BOUNDARY);
01182 bool isRoot = bdVertex->hasNextIntEdge();
01183 Coloring::IntEdgeHandle intEdge = (isRoot ?
01184 bdVertex->getNextIntEdge() :
01185 bdVertex->getPrevIntEdge());
01186 Coloring::VertexHandle adjVertex = (isRoot ?
01187 intEdge->getNextVertex() :
01188 intEdge->getPrevVertex());
01189
01190 notifyEdgeWillBeRemoved(intEdge);
01191 notifyVertexWillBeRemoved(bdVertex);
01192 notifyVertexWillBeRemoved(adjVertex);
01193
01194 Geometry::Point oldLoc = *bdVertex;
01195 Coloring::BdEdgeHandle nextBdEdge = bdEdge->getNextVertex()->getNextBdEdge();
01196 Coloring::VertexHandle nextBdVertex = nextBdEdge->getNextVertex();
01197 Coloring::BdEdgeHandle prevBdEdge = bdEdge->getPrevVertex()->getPrevBdEdge();
01198 Coloring::VertexHandle prevBdVertex = prevBdEdge->getPrevVertex();
01199 Coloring::VertexHandle prevCorner = corner->getPrevCornerVertex();
01200 Coloring::VertexHandle nextCorner = corner->getNextCornerVertex();
01201
01202 freeEdge(prevBdEdge);
01203 freeEdge(bdEdge);
01204 freeEdge(nextBdEdge);
01205 freeEdge(intEdge);
01206 freeVertex(bdVertex);
01207
01208 bdVertex = newVertex(Vertex::BOUNDARY, p);
01209 intEdge = isRoot ? newInteriorEdge(bdVertex, adjVertex) :
01210 newInteriorEdge(adjVertex, bdVertex);
01211 if (prevIsCorner) {
01212 newBoundaryEdge(prevBdVertex, bdVertex, prevCorner, corner);
01213 bdEdge = newBoundaryEdge(bdVertex, corner, prevCorner, corner);
01214 newBoundaryEdge(corner, nextBdVertex, corner, nextCorner);
01215 } else {
01216 newBoundaryEdge(prevBdVertex, corner, prevCorner, corner);
01217 bdEdge = newBoundaryEdge(corner, bdVertex, corner, nextCorner);
01218 newBoundaryEdge(bdVertex, nextBdVertex, corner, nextCorner);
01219 }
01220
01221 notifyVertexHasBeenAdded(bdVertex);
01222 notifyVertexHasBeenAdded(adjVertex);
01223 notifyEdgeHasBeenAdded(intEdge);
01224
01225 recolored(*adjVertex, p, *corner, oldLoc);
01226 TEST_VALIDITY;
01227 assert(oldNumBdEdges == numBoundaryEdges());
01228 return true;
01229 }
01230
01231 bool Coloring::moveBdVertexPastCorner(Coloring::BdEdgeHandle& bdEdge,
01232 const Geometry::Point& p,
01233 DO_IF_VALID_TAG) {
01234 if (!moveBdVertexPastCorner(bdEdge, p, TEST_IF_VALID_TAG())) return false;
01235 return moveBdVertexPastCorner(bdEdge, p, DO_WITHOUT_TEST_TAG());
01236 }
01237
01238 bool Coloring::recolorQuadrilateral(IntEdgeHandle ab,
01239 IntEdgeHandle cd,
01240 bool ac,
01241 TEST_IF_VALID_TAG) const {
01242 VertexHandle a = ab->getPrevVertex();
01243 VertexHandle b = ab->getNextVertex();
01244 VertexHandle c = cd->getPrevVertex();
01245 VertexHandle d = cd->getNextVertex();
01246
01247
01248
01249
01250 VertexHandle w = a;
01251 VertexHandle x = (ac ? c : d);
01252 VertexHandle y = b;
01253 VertexHandle z = (ac ? d : c);
01254
01255
01256 if ((w == x) || (y == z)) return false;
01257
01258 if (CGAL::do_intersect(Segment(*w, *x), Segment(*y, *z))) return false;
01259
01260
01261 if ((d->hasNextIntEdge() && (d->getNextVertex() == a))
01262 ||
01263 (b->hasNextIntEdge() && (b->getNextVertex() == c)))
01264 return false;
01265
01266
01267 if ((w->type() == Vertex::BOUNDARY) &&
01268 (x->type() == Vertex::BOUNDARY) &&
01269 (x->getNextCornerVertex() == w->getNextCornerVertex()))
01270 return false;
01271 if ((y->type() == Vertex::BOUNDARY) &&
01272 (z->type() == Vertex::BOUNDARY) &&
01273 (y->getNextCornerVertex() == z->getNextCornerVertex()))
01274 return false;
01275
01276 if ((minEdgeLengthSq > 0.0) &&
01277 ((CGAL::to_double(CGAL::squared_distance(*w, *x)) < minEdgeLengthSq) ||
01278 (CGAL::to_double(CGAL::squared_distance(*y, *z)) < minEdgeLengthSq)))
01279 return false;
01280
01281
01282
01283 if (!compatible(*w, *x) || !compatible(*y, *z)) return false;
01284 return true;
01285 }
01286
01287 bool Coloring::recolorQuadrilateral(IntEdgeHandle& ab,
01288 IntEdgeHandle& cd,
01289 bool ac,
01290 DO_WITHOUT_TEST_TAG) {
01297 VertexHandle a = ab->getPrevVertex();
01298 VertexHandle b = ab->getNextVertex();
01299 VertexHandle c = cd->getPrevVertex();
01300 VertexHandle d = cd->getNextVertex();
01301
01302 notifyEdgeWillBeRemoved(ab);
01303 notifyEdgeWillBeRemoved(cd);
01304 notifyVertexWillBeRemoved(a);
01305 notifyVertexWillBeRemoved(b);
01306 notifyVertexWillBeRemoved(c);
01307 notifyVertexWillBeRemoved(d);
01308 if (ac) {
01309
01310
01311
01312
01313 freeEdge(ab);
01314 freeEdge(cd);
01315
01316 VertexHandle v = b;
01317 while ((v != c) && v->hasNextIntEdge()) v = v->getNextVertex();
01318 const bool b2c = (v == c);
01319
01320 v = d;
01321 while ((v != a) && v->hasNextIntEdge()) v = v->getNextVertex();
01322 const bool d2a = (v == a);
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344 if (!(d2a && !b2c)) {
01345
01346
01347
01348 v = c;
01349 VertexHandle u =
01350 v->hasPrevIntEdge() ? v->getPrevVertex() : VertexHandle();
01351 if (u.valid()) {
01352
01353 IntEdgeHandle uv = v->getPrevIntEdge();
01354 freeEdge(uv);
01355 }
01356
01357
01358 while (u.valid()) {
01359
01360 VertexHandle t =
01361 u->hasPrevIntEdge() ? u->getPrevVertex() : VertexHandle();
01362 if (t.valid()) {
01363
01364 IntEdgeHandle tu = u->getPrevIntEdge();
01365 freeEdge(tu);
01366 }
01367
01368 newInteriorEdge(v, u);
01369
01370 v = u;
01371 u = t;
01372 }
01373 }
01374
01375 if (!b2c) {
01376
01377
01378
01379 v = d;
01380 VertexHandle u =
01381 v->hasNextIntEdge() ? v->getNextVertex() : VertexHandle();
01382 if (u.valid()) {
01383
01384 IntEdgeHandle vu = v->getNextIntEdge();
01385 freeEdge(vu);
01386 }
01387
01388
01389 while (u.valid()) {
01390
01391 VertexHandle t =
01392 u->hasNextIntEdge() ? u->getNextVertex() : VertexHandle();
01393 if (t.valid()) {
01394
01395 IntEdgeHandle ut = u->getNextIntEdge();
01396 freeEdge(ut);
01397 }
01398
01399 newInteriorEdge(u, v);
01400
01401 v = u;
01402 u = t;
01403 }
01404 }
01405
01406 if (b2c && d2a) {
01407 ab = newInteriorEdge(a, c);
01408 cd = newInteriorEdge(b, d);
01409 } else if (b2c && !d2a) {
01410 ab = newInteriorEdge(a, c);
01411 cd = newInteriorEdge(b, d);
01412 } else if (!b2c && d2a) {
01413 ab = newInteriorEdge(c, a);
01414 cd = newInteriorEdge(d, b);
01415 } else {
01416 ab = newInteriorEdge(a, c);
01417 cd = newInteriorEdge(d, b);
01418 }
01419 } else {
01420
01421 freeEdge(ab);
01422 freeEdge(cd);
01423 ab = newInteriorEdge(a, d);
01424 cd = newInteriorEdge(c, b);
01425 }
01426
01427 notifyVertexHasBeenAdded(a);
01428 notifyVertexHasBeenAdded(b);
01429 notifyVertexHasBeenAdded(c);
01430 notifyVertexHasBeenAdded(d);
01431 notifyEdgeHasBeenAdded(ab);
01432 notifyEdgeHasBeenAdded(cd);
01433
01434 if (ac)
01435 recolored(*b, *a, *c, *d);
01436 else
01437 recolored(*b, *a, *d, *c);
01438 TEST_VALIDITY;
01439 return true;
01440 }
01441
01442 bool Coloring::recolorQuadrilateral(IntEdgeHandle& ab,
01443 IntEdgeHandle& cd,
01444 bool ac,
01445 DO_IF_VALID_TAG) {
01446 if (!recolorQuadrilateral(ab, cd, ac, TEST_IF_VALID_TAG())) return false;
01447 return recolorQuadrilateral(ab, cd, ac, DO_WITHOUT_TEST_TAG());
01448 }
01449
01450 #ifdef TRIANGULATION_EDGE_INDEX
01451 Coloring::Tracer::Tracer(const Geometry::Point& source,
01452 const Geometry::Point& target,
01453 const Coloring::TriangulationIndex& tri,
01454 bool isRay,
01455 const Coloring::TFaceHandle hint)
01456 : source(source), target(target), tri(&tri), circ(),
01457 edge(Coloring::TFaceHandle(), 0),
01458 forwards(true), valid(true), isRay(isRay) {
01465
01466 TFaceHandle fh = tri.locate(this->source, hint);
01467
01468 Coloring::TFaceCirculator start = circ = tri.line_walk(source, target, fh);
01469 assert(tri.is_infinite(start) == false);
01470
01471
01472
01473 if (!isRay &&
01474 (tri.triangle(start).has_on_unbounded_side(target) == false)) {
01475 valid = false;
01476 return;
01477 }
01478
01479 ++circ;
01480 int nbr;
01481 assert(start->has_neighbor(circ, nbr));
01482 Geometry::Segment e = tri.segment(start, nbr);
01483 if (tri.is_infinite(circ) == false) {
01484 Geometry::Point p = start->vertex(tri.cw(nbr))->point();
01485 Geometry::Point q = start->vertex(tri.ccw(nbr))->point();
01486 Geometry::Point s = source - (target - source);
01487 Geometry::Point t = target + (target - source);
01488 CGAL::Orientation so = CGAL::orientation(p, q, s);
01489 CGAL::Orientation to = CGAL::orientation(p, q, t);
01490 assert(so != CGAL::COLLINEAR);
01491 assert(to != CGAL::COLLINEAR);
01492 forwards = (so != to);
01493 } else
01494 forwards = false;
01495
01496 circ = tri.line_walk(source, target, fh);
01497
01498 this->operator++();
01499 }
01500
01501 Coloring::Tracer& Coloring::Tracer::operator++() {
01502 assert(valid);
01503
01504
01505 while (true) {
01506 assert(tri->is_infinite(circ) == false);
01507 Coloring::TFaceCirculator prev = circ;
01508 if (forwards) ++circ; else --circ;
01509
01510
01511 int nbr;
01512 if (prev->has_neighbor(circ, nbr)) {
01513
01514
01515 if (prev->is_constrained(nbr) &&
01516 crosses(tri->segment(prev, nbr), source, target)) {
01517 edge = TEdge(prev, nbr);
01518 return *this;
01519 }
01520
01521 if (!isRay) {
01522 Geometry::Point p = prev->vertex(tri->cw(nbr))->point();
01523 Geometry::Point q = prev->vertex(tri->ccw(nbr))->point();
01524 CGAL::Orientation so = CGAL::orientation(p, q, source);
01525 CGAL::Orientation to = CGAL::orientation(p, q, target);
01526 if ((to == CGAL::COLLINEAR) || (so == to)) {
01527 valid = false;
01528 return *this;
01529 }
01530 }
01531 } else {
01532
01533
01534 }
01535
01536 if (tri->is_infinite(circ)) {
01537 valid = false;
01538 return *this;
01539 }
01540 }
01541 }
01542 #endif // #ifdef TRIANGULATION_EDGE_INDEX
01543
01544 #ifdef GRID_EDGE_INDEX
01545 bool Coloring::compatible(const Geometry::Point &xp,
01546 const Geometry::Point &yp) const {
01547 typedef InteriorEdgeIndex::ConstLineCellIterator Iterator;
01548 Iterator it(*intEdgeIndex, xp, yp, Iterator::SEGMENT()), end;
01549 typedef InteriorEdgeIndex::Cell Cell;
01550 while (it != end) {
01551 const InteriorEdgeIndex::Cell& cell = *it;
01552 const InteriorEdgeIndex::Cell::ItemList& edges = cell.getItemList();
01553 typedef InteriorEdgeIndex::Cell::ItemList::const_iterator EdgeIterator;
01554 for (EdgeIterator jt = edges.begin(); jt != edges.end(); jt++) {
01555 const IntEdgeHandle e = *jt;
01556 if (e->crosses(xp, yp)) {
01557 return false;
01558 }
01559 }
01560 ++it;
01561 }
01562 return true;
01563 }
01564 #endif // #ifdef GRID_EDGE_INDEX
01565
01566 #ifdef TRIANGULATION_EDGE_INDEX
01567 bool Coloring::compatible(const Geometry::Point &xp,
01568 const Geometry::Point &yp,
01569 TFaceHandle fh) const {
01570 Tracer trace(xp, yp, tri, outside(yp), fh);
01571 bool found = (trace != Tracer());
01572 return !found;
01573 }
01574 #endif // #ifdef TRIANGULATION_EDGE_INDEX
01575
01576 bool Coloring::trace(const Geometry::Point &xp,
01577 const Geometry::Point &yp,
01578 IntEdgeHandle& edge,
01579 Geometry::Point& ipt,
01580 Geometry::Kernel::FT& sd) const {
01581 #ifdef TRIANGULATION_EDGE_INDEX
01582 Tracer trace(xp, yp, tri);
01583 if (trace != Tracer()) {
01584 TFaceHandle fh = trace->first;
01585 int i = trace->second;
01586 TVertexHandle tva = fh->vertex(tri.cw(i));
01587 TVertexHandle tvb = fh->vertex(tri.ccw(i));
01588 VertexHandle va = tva->vertex;
01589 VertexHandle vb = tvb->vertex;
01590 if (va->hasPrevIntEdge() && (va->getPrevVertex() == vb))
01591 edge = va->getPrevIntEdge();
01592 else if (va->hasNextIntEdge() && (va->getNextVertex() == vb))
01593 edge = va->getNextIntEdge();
01594 else
01595 assert(false);
01596 CGAL::Object result = CGAL::intersection(edge->segment(),
01597 Geometry::Segment(xp, yp));
01598 assert(CGAL::assign(ipt, result));
01599 sd = squared_distance(ipt, xp);
01600 return true;
01601 } else
01602 return false;
01603 #endif
01604 #ifdef GRID_EDGE_INDEX
01605 typedef InteriorEdgeIndex::ConstLineCellIterator Iterator;
01606 Iterator it(*intEdgeIndex, xp, yp, Iterator::SEGMENT()), end;
01607 typedef const InteriorEdgeIndex::Cell Cell;
01608 const Segment segment(xp, yp);
01609 edge = IntEdgeHandle();
01610 while (it != end) {
01611 Cell& cell = *it;
01612 const Cell::ItemList& edges = cell.getItemList();
01613 typedef Cell::ItemList::const_iterator EdgeIterator;
01614 for (EdgeIterator jt = edges.begin(); jt != edges.end(); jt++) {
01615 const IntEdgeHandle e = *jt;
01616 Geometry::Point intersection;
01617 CGAL::Object result = CGAL::intersection(*e, segment);
01618 if (CGAL::assign(intersection, result)) {
01619 Geometry::Kernel::FT d = squared_distance(intersection, xp);
01620 if ((!edge.valid()) || (d < sd)) {
01621 edge = e;
01622 sd = d;
01623 ipt = intersection;
01624 }
01625 }
01626 }
01627 if (edge.valid()) break;
01628 ++it;
01629 }
01630 return edge.valid();
01631 #endif
01632 }
01633
01634 Geometry::Point Coloring::randomPoint(Arak::Util::Random& random) const {
01639 return Geometry::Point(random.uniform(CGAL::to_double(bd.xmin()),
01640 CGAL::to_double(bd.xmax())),
01641 random.uniform(CGAL::to_double(bd.ymin()),
01642 CGAL::to_double(bd.ymax())));
01643 }
01644
01645 Color Coloring::color(const Geometry::Point& point) const {
01646
01647 QueryPoint q = queryPoints->closest(point);
01648 Color c = q.color();
01649 assert(c != INVALID_COLOR);
01650 if (q == point) return c;
01651 #ifndef GRID_EDGE_INDEX
01652
01653
01654 Tracer trace(q, point, tri);
01655 while (trace != Tracer()) {
01656 ++trace;
01657 c = opposite(c);
01658 }
01659 return c;
01660 #else
01661
01662
01663 std::set<IntEdgeHandle> counted;
01664 typedef InteriorEdgeIndex::ConstLineCellIterator Iterator;
01665 Iterator it(*intEdgeIndex, q, point, Iterator::SEGMENT()), end;
01666 typedef InteriorEdgeIndex::Cell Cell;
01667 while (it != end) {
01668 const Cell& cell = *it;
01669 const Cell::ItemList& edges = cell.getItemList();
01670 typedef Cell::ItemList::const_iterator EdgeIterator;
01671 for (EdgeIterator jt = edges.begin(); jt != edges.end(); jt++) {
01672 const IntEdgeHandle e = *jt;
01673 if ((counted.find(e) == counted.end()) && e->crosses(q, point)) {
01674 counted.insert(e);
01675 c = opposite(c);
01676 }
01677 }
01678 ++it;
01679 }
01680 return c;
01681 #endif
01682 }
01683
01684 bool Coloring::solid(const Geometry::Polygon& poly, Arak::Color color) const {
01685 #ifdef GRID_EDGE_INDEX
01686
01687
01688 if (this->color(poly[0]) != color) return false;
01689
01690
01691 int size = poly.size();
01692 for (int i = 0; i < size; i++)
01693 if (!compatible(poly[i], poly[(i + 1) % size])) return false;
01694
01695
01696 typedef InteriorEdgeIndex::ConstConvexPolygonCellIterator CellIterator;
01697 typedef InteriorEdgeIndex::Cell Cell;
01698 typedef Cell::ItemList::const_iterator EdgeIterator;
01699 CellIterator end;
01700 for (CellIterator it(*intEdgeIndex, poly); it != end; ++it) {
01701 const Cell& cell = *it;
01702 const Cell::ItemList& edges = cell.getItemList();
01703 for (EdgeIterator jt = edges.begin(); jt != edges.end(); jt++) {
01704 const IntEdgeHandle e = *jt;
01705 const VertexHandle u = e->getPrevVertex();
01706 const VertexHandle v = e->getNextVertex();
01707 if (!cell.has_on_unbounded_side(u->point()) &&
01708 !poly.has_on_unbounded_side(u->point()))
01709 return false;
01710 if (!cell.has_on_unbounded_side(v->point()) &&
01711 !poly.has_on_unbounded_side(v->point()))
01712 return false;
01713 }
01714 }
01715
01716 return true;
01717 #endif
01718 #ifdef TRIANGULATION_EDGE_INDEX
01719
01720
01721 assert(false);
01722 #endif
01723 }
01724
01725 void Coloring::addListener(Listener& listener) const {
01726
01727 if (std::find(listeners.begin(), listeners.end(), &listener) ==
01728 listeners.end())
01729 listeners.push_front(&listener);
01730 }
01731
01732 void Coloring::recolored(const Geometry::Point& a,
01733 const Geometry::Point& b,
01734 const Geometry::Point& c) {
01735 queryPoints->recolor(a, b, c);
01736 typedef std::list<Listener*>::iterator ListenerIterator;
01737 for (ListenerIterator it = listeners.begin(); it != listeners.end(); it++) {
01738 Listener *listener = *it;
01739 listener->recolored(a, b, c);
01740 }
01741 }
01742
01743 void Coloring::recolored(const Geometry::Point& a,
01744 const Geometry::Point& b,
01745 const Geometry::Point& c,
01746 const Geometry::Point& d) {
01747 queryPoints->recolor(a, b, c, d);
01748 typedef std::list<Listener*>::iterator ListenerIterator;
01749 for (ListenerIterator it = listeners.begin(); it != listeners.end(); it++) {
01750 Listener *listener = *it;
01751 listener->recolored(a, b, c, d);
01752 }
01753 }
01754
01755 void Coloring::getPointWithColor(Geometry::Point& p, Color& c) const {
01756 const QueryPoint& q = queryPoints->point(0);
01757 p = q;
01758 c = q.color();
01759 }
01760
01761 void Coloring::visualize(CGAL::Qt_widget& widget,
01762 bool drawEdges,
01763 bool drawVertices,
01764 bool drawRegions,
01765 bool drawQueries) const {
01766 using namespace CGAL;
01767 if (drawRegions) {
01768
01769 typedef TriangulationTraits<FaceColorInfo>::Triangulation Triangulation;
01770 Triangulation tri;
01771 this->toTriangulation(tri);
01772
01773 widget << LineWidth(0);
01774 Triangulation::Finite_faces_iterator it = tri.finite_faces_begin();
01775 Triangulation::Finite_faces_iterator end = tri.finite_faces_end();
01776 while (it != end) {
01777 Geometry::Triangle triangle = tri.triangle(it);
01778 bool white = (it->info().color == Arak::WHITE);
01779
01780 widget << (white ? CGAL::WHITE : CGAL::BLACK);
01781 widget << CGAL::FillColor(white ? CGAL::WHITE : CGAL::BLACK);
01782 widget << LineWidth(1) << triangle;
01783 it++;
01784 }
01785
01786 widget << CGAL::BLACK << noFill << LineWidth(1) << bd;
01787 }
01788 if (drawQueries) {
01789
01790 widget << PointSize(4) << PointStyle(DISC);
01791 const QueryPointIndex& queryPoints = getQueryPoints();
01792 for (int i = 0; i < queryPoints.size(); i++) {
01793 if (queryPoints.point(i).color() == BLACK)
01794 widget << CGAL::BLACK << queryPoints.point(i);
01795 else
01796 widget << CGAL::BLUE << queryPoints.point(i);
01797 }
01798 }
01799 if (drawEdges) {
01800
01801
01802
01803
01804 widget << BLUE << LineWidth(2);
01805 for (int i = 0; i < numInteriorEdges(); i++) {
01806 const Coloring::IntEdgeHandle e = getInteriorEdge(i);
01807 widget << e->segment();
01808 }
01809
01810 widget << RED;
01811 for (int i = 0; i < numBoundaryEdges(); i++) {
01812 const Coloring::BdEdgeHandle e = getBoundaryEdge(i);
01813 widget << e->segment();
01814 }
01815 }
01816 if (drawVertices) {
01817
01818 widget << PointSize(6) << PointStyle(DISC) << BLUE;
01819 for (int i = 0; i < numVertices(Coloring::Vertex::INTERIOR); i++) {
01820 const Coloring::VertexHandle v =
01821 getVertex(Coloring::Vertex::INTERIOR, i);
01822 widget << v->point();
01823 }
01824
01825 widget << RED;
01826 for (int i = 0; i < numVertices(Coloring::Vertex::BOUNDARY); i++) {
01827 const Coloring::VertexHandle v =
01828 getVertex(Coloring::Vertex::BOUNDARY, i);
01829 widget << v->point();
01830 }
01831 }
01832 }
01833
01834
01835 #define COLORING_HEADER "\
01836 #######################################################################\n\
01837 # \n\
01838 # This file represents a binary polygonal coloring of a rectangular \n\
01839 # subset of the plane. It is described by its boundary, the \n\
01840 # vertices and edges of the coloring, and the color of a point in the \n\
01841 # interior of the coloring. \n\
01842 # \n\
01843 # The point coordinates are represented to 40 decimal places to \n\
01844 # prevent truncation and rounding from causing vertices that are close \n\
01845 # to appear at the same location (and related problems). \n\
01846 # \n\
01847 #######################################################################\n"
01848
01849 void Coloring::write(std::ostream& out) const {
01850
01851 out << COLORING_HEADER << std::endl;
01852
01853 out << "# The coordinates of the boundary rectangle: xmin ymin xmax ymax"
01854 << std::endl << bd << std::endl;
01855
01856 out << std::endl << "# Number of boundary vertices:" << std::endl;
01857 out << numVertices(Vertex::BOUNDARY) << std::endl;
01858 out << "# Boundary vertices [index x y]:" << std::endl;
01859 out << std::scientific << std::setprecision(40);
01860 for (int i = 0; i < numVertices(Vertex::BOUNDARY); i++) {
01861 VertexHandle v = getVertex(Vertex::BOUNDARY, i);
01862 out << v->index << " "
01863 << CGAL::to_double(v->point().x()) << " "
01864 << CGAL::to_double(v->point().y()) << std::endl;
01865 }
01866 out << std::endl << "# Number of interior vertices:" << std::endl;
01867 out << numVertices(Vertex::INTERIOR) << std::endl;
01868 out << "# Interior vertices [index x y]:" << std::endl;
01869 for (int i = 0; i < numVertices(Vertex::INTERIOR); i++) {
01870 VertexHandle v = getVertex(Vertex::INTERIOR, i);
01871 out << v->index << " "
01872 << CGAL::to_double(v->point().x()) << " "
01873 << CGAL::to_double(v->point().y()) << std::endl;
01874 }
01875
01876 out << std::endl << "# Number of boundary edges:" << std::endl;
01877 out << numBoundaryEdges() << std::endl;
01878 out << "# Boundary edges; each edge is specified by:" << std::endl;
01879 out << "# a. index " << std::endl;
01880 out << "# b. previous corner index (0-3, counter-clockwise from lower-left)"
01881 << std::endl;
01882 out << "# c. next corner index (0-3, counter-clockwise from lower-left)"
01883 << std::endl;
01884 out << "# d. previous vertex type (1:boundary, 2:corner)"
01885 << std::endl;
01886 out << "# e. previous vertex index" << std::endl;
01887 out << "# f. next vertex type (1:boundary, 2:corner)"
01888 << std::endl;
01889 out << "# g. next vertex index" << std::endl;
01890 for (int i = 0; i < numBoundaryEdges(); i++) {
01891 BdEdgeHandle e = getBoundaryEdge(i);
01892 out << e->index << " "
01893 << e->getPrevCornerVertex()->index << " "
01894 << e->getNextCornerVertex()->index << " "
01895 << e->getPrevVertex()->type() << " "
01896 << e->getPrevVertex()->index << " "
01897 << e->getNextVertex()->type() << " "
01898 << e->getNextVertex()->index << std::endl;
01899 }
01900 out << std::endl << "# Number of interior edges:" << std::endl;
01901 out << numInteriorEdges() << std::endl;
01902 out << "# Interior edges; each edge is specified by:" << std::endl;
01903 out << "# a. index " << std::endl;
01904 out << "# b. previous vertex type (0:interior, 1:boundary)"
01905 << std::endl;
01906 out << "# c. previous vertex index" << std::endl;
01907 out << "# d. next vertex type (0:interior, 1:boundary)"
01908 << std::endl;
01909 out << "# e. next vertex index" << std::endl;
01910 for (int i = 0; i < numInteriorEdges(); i++) {
01911 IntEdgeHandle e = getInteriorEdge(i);
01912 out << e->index << " "
01913 << e->getPrevVertex()->type() << " "
01914 << e->getPrevVertex()->index << " "
01915 << e->getNextVertex()->type() << " "
01916 << e->getNextVertex()->index << std::endl;
01917 }
01918
01919 out << std::endl << "# Location of query point:" << std::endl;
01920 Geometry::Point point;
01921 Color color;
01922 getPointWithColor(point, color);
01923 out << point << std::endl;
01924 out << std::endl << "# Color of query point (0:white, 1:black):"
01925 << std::endl;
01926 out << color << std::endl;
01927
01928 out << std::endl << "# End of coloring" << std::endl;
01929 }
01930
01931 void Coloring::writeBinary(std::ostream& out) const {
01932 double d;
01933 unsigned short int n;
01934 unsigned char c;
01935
01936 d = CGAL::to_double(bd.xmin());
01937 out.write(reinterpret_cast<char*>(&d), sizeof(d));
01938 d = CGAL::to_double(bd.ymin());
01939 out.write(reinterpret_cast<char*>(&d), sizeof(d));
01940 d = CGAL::to_double(bd.xmax());
01941 out.write(reinterpret_cast<char*>(&d), sizeof(d));
01942 d = CGAL::to_double(bd.ymax());
01943 out.write(reinterpret_cast<char*>(&d), sizeof(d));
01944
01945 n = numVertices(Vertex::BOUNDARY);
01946 out.write(reinterpret_cast<char*>(&n), sizeof(n));
01947 for (int i = 0; i < numVertices(Vertex::BOUNDARY); i++) {
01948 VertexHandle v = getVertex(Vertex::BOUNDARY, i);
01949
01950
01951
01952
01953 d = CGAL::to_double(v->point().x());
01954 out.write(reinterpret_cast<char*>(&d), sizeof(d));
01955 d = CGAL::to_double(v->point().y());
01956 out.write(reinterpret_cast<char*>(&d), sizeof(d));
01957 }
01958 n = numVertices(Vertex::INTERIOR);
01959 out.write(reinterpret_cast<char*>(&n), sizeof(n));
01960 for (int i = 0; i < numVertices(Vertex::INTERIOR); i++) {
01961 VertexHandle v = getVertex(Vertex::INTERIOR, i);
01962
01963
01964
01965
01966 d = CGAL::to_double(v->point().x());
01967 out.write(reinterpret_cast<char*>(&d), sizeof(d));
01968 d = CGAL::to_double(v->point().y());
01969 out.write(reinterpret_cast<char*>(&d), sizeof(d));
01970 }
01971
01972 n = numBoundaryEdges();
01973 out.write(reinterpret_cast<char*>(&n), sizeof(n));
01974 for (int i = 0; i < numBoundaryEdges(); i++) {
01975 BdEdgeHandle e = getBoundaryEdge(i);
01976
01977
01978
01979
01980 n = e->getPrevCornerVertex()->index;
01981 out.write(reinterpret_cast<char*>(&n), sizeof(n));
01982 n = e->getNextCornerVertex()->index;
01983 out.write(reinterpret_cast<char*>(&n), sizeof(n));
01984 c = e->getPrevVertex()->type();
01985 out.write(reinterpret_cast<char*>(&c), sizeof(c));
01986 n = e->getPrevVertex()->index;
01987 out.write(reinterpret_cast<char*>(&n), sizeof(n));
01988 c = e->getNextVertex()->type();
01989 out.write(reinterpret_cast<char*>(&c), sizeof(c));
01990 n = e->getNextVertex()->index;
01991 out.write(reinterpret_cast<char*>(&n), sizeof(n));
01992 }
01993
01994 n = numInteriorEdges();
01995 out.write(reinterpret_cast<char*>(&n), sizeof(n));
01996 for (int i = 0; i < numInteriorEdges(); i++) {
01997 IntEdgeHandle e = getInteriorEdge(i);
01998
01999
02000
02001
02002 c = e->getPrevVertex()->type();
02003 out.write(reinterpret_cast<char*>(&c), sizeof(c));
02004 n = e->getPrevVertex()->index;
02005 out.write(reinterpret_cast<char*>(&n), sizeof(n));
02006 c = e->getNextVertex()->type();
02007 out.write(reinterpret_cast<char*>(&c), sizeof(c));
02008 n = e->getNextVertex()->index;
02009 out.write(reinterpret_cast<char*>(&n), sizeof(n));
02010 }
02011
02012 Geometry::Point point;
02013 Color color;
02014 getPointWithColor(point, color);
02015 d = CGAL::to_double(point.x());
02016 out.write(reinterpret_cast<char*>(&d), sizeof(d));
02017 d = CGAL::to_double(point.y());
02018 out.write(reinterpret_cast<char*>(&d), sizeof(d));
02019 c = color;
02020 out.write(reinterpret_cast<char*>(&c), sizeof(c));
02021 }
02022
02023 void Coloring::writeXfig(std::ostream& out) const {
02024 int xfigUnitsPerInch = 1200;
02025 double nativeUnitsPerInch = CGAL::to_double(bd.xmax() - bd.xmin()) / 7.5;
02026 double xfigUnitsPerNativeUnit =
02027 double(xfigUnitsPerInch) / nativeUnitsPerInch;
02028
02029 out << "#FIG 3.2" << std::endl;
02030 out << "Portrait" << std::endl;
02031 out << "Center" << std::endl;
02032 out << "Inches" << std::endl;
02033 out << "Letter" << std::endl;
02034 out << "100.00" << std::endl;
02035 out << "Single" << std::endl;
02036 out << "-2" << std::endl;
02037 out << xfigUnitsPerInch << " 2" << std::endl;
02038
02039
02040 out << "2 "
02041 << "2 "
02042 << "0 "
02043 << "1 "
02044 << "0 "
02045 << "7 "
02046 << "50 "
02047 << "-1 "
02048 << "-1 "
02049 << "0.000 "
02050 << "0 "
02051 << "0 "
02052 << "-1 "
02053 << "0 "
02054 << "0 "
02055 << "5 "
02056 << std::endl;
02057
02058
02059
02060 out << " ";
02061 for (int i = 0; i < 5; i++)
02062 out << int(CGAL::to_double(bd.vertex(i).x()) * xfigUnitsPerNativeUnit)
02063 << " "
02064 << -int(CGAL::to_double(bd.vertex(i).y()) * xfigUnitsPerNativeUnit)
02065 << " ";
02066 out << std::endl;
02067
02068
02069 typedef TriangulationTraits<FaceColorInfo>::Triangulation Triangulation;
02070 Triangulation tri;
02071 this->toTriangulation(tri);
02072
02073 Triangulation::Finite_faces_iterator it = tri.finite_faces_begin();
02074 Triangulation::Finite_faces_iterator end = tri.finite_faces_end();
02075 while (it != end) {
02076 Geometry::Triangle triangle = tri.triangle(it);
02077 bool white = (it->info().color == Arak::WHITE);
02078 if (!white) {
02079
02080 out << "2 "
02081 << "1 "
02082 << "0 "
02083 << "1 "
02084 << "0 "
02085 << "-1 "
02086 << "50 "
02087 << "-1 "
02088 << "20 "
02089 << "0.000 "
02090 << "0 "
02091 << "0 "
02092 << "-1 "
02093 << "0 "
02094 << "0 "
02095 << "4 "
02096 << std::endl;
02097 out << " ";
02098 for (int i = 0; i < 4; i++)
02099 out << int(CGAL::to_double(triangle.vertex(i).x()) *
02100 xfigUnitsPerNativeUnit)
02101 << " "
02102 << -int(CGAL::to_double(triangle.vertex(i).y()) *
02103 xfigUnitsPerNativeUnit)
02104 << " ";
02105 out << std::endl;
02106 }
02107 it++;
02108 }
02109 out << std::endl;
02110 }
02111
02112 bool Coloring::read(std::istream& in) {
02113 int rows = intEdgeIndex->numRows();
02114 int cols = intEdgeIndex->numCols();
02115 Geometry::Rectangle bd;
02116 in >> skipcomments;
02117 in >> bd;
02118 if (!in.good()) return false;
02119 initialize(bd, rows, cols);
02120
02121 while (numBoundaryEdges() > 0) {
02122 BdEdgeHandle e = getBoundaryEdge(0);
02123 freeEdge(e);
02124 }
02125
02126 int n;
02127 Geometry::Point p;
02128 in >> skipcomments;
02129 in >> n;
02130 in >> skipcomments;
02131 int index;
02132 if (!in.good()) return false;
02133
02134 for (int i = 0; i < n; i++) {
02135 in >> index;
02136 assert(index == i);
02137 in >> p;
02138 if (!in.good()) return false;
02139 assert(newVertex(Vertex::BOUNDARY, p)->index == i);
02140 }
02141
02142 in >> skipcomments;
02143 in >> n;
02144 in >> skipcomments;
02145 if (!in.good()) return false;
02146
02147 for (int i = 0; i < n; i++) {
02148 in >> index;
02149 assert(index == i);
02150 in >> p;
02151 if (!in.good()) return false;
02152 assert(newVertex(Vertex::INTERIOR, p)->index == i);
02153 }
02154
02155 in >> skipcomments;
02156 in >> n;
02157 in >> skipcomments;
02158 if (!in.good()) return false;
02159 int prevTypeInt, nextTypeInt;
02160 Vertex::Type prevType, nextType;
02161 int prevIndex, nextIndex;
02162 int prevCornerIndex, nextCornerIndex;
02163
02164 for (int i = 0; i < n; i++) {
02165 in >> index;
02166 assert(index == i);
02167 in >> prevCornerIndex
02168 >> nextCornerIndex
02169 >> prevTypeInt
02170 >> prevIndex
02171 >> nextTypeInt
02172 >> nextIndex;
02173 if (!in.good()) return false;
02174 switch (prevTypeInt) {
02175 case 1: prevType = Vertex::BOUNDARY; break;
02176 case 2: prevType = Vertex::CORNER; break;
02177 default: return false;
02178 };
02179 switch (nextTypeInt) {
02180 case 1: nextType = Vertex::BOUNDARY; break;
02181 case 2: nextType = Vertex::CORNER; break;
02182 default: return false;
02183 };
02184 newBoundaryEdge(getVertex(prevType, prevIndex),
02185 getVertex(nextType, nextIndex),
02186 getVertex(Vertex::CORNER, prevCornerIndex),
02187 getVertex(Vertex::CORNER, nextCornerIndex));
02188 }
02189
02190 in >> skipcomments;
02191 in >> n;
02192 in >> skipcomments;
02193 if (!in.good()) return false;
02194
02195 for (int i = 0; i < n; i++) {
02196 in >> index;
02197 assert(index == i);
02198 in >> prevTypeInt >> prevIndex >> nextTypeInt >> nextIndex;
02199 if (!in.good()) return false;
02200 switch (prevTypeInt) {
02201 case 0: prevType = Vertex::INTERIOR; break;
02202 case 1: prevType = Vertex::BOUNDARY; break;
02203 default: return false;
02204 };
02205 switch (nextTypeInt) {
02206 case 0: nextType = Vertex::INTERIOR; break;
02207 case 1: nextType = Vertex::BOUNDARY; break;
02208 default: return false;
02209 };
02210 newInteriorEdge(getVertex(prevType, prevIndex),
02211 getVertex(nextType, nextIndex));
02212 }
02213
02214 int colorInt;
02215 Color c;
02216 in >> skipcomments >> p >> skipcomments >> colorInt;
02217 if (!in.good()) return false;
02218 switch (colorInt) {
02219 case 0: c = WHITE; break;
02220 case 1: c = BLACK; break;
02221 default: return false;
02222 }
02223
02224
02225 assert(queryPoints->size() == 1);
02226 QueryPoint& q = queryPoints->point(0);
02227 if (color(p) != c) q.setColor(opposite(q.color()));
02228
02229 test();
02230 return true;
02231 }
02232
02233 bool Coloring::readBinary(std::istream& in) {
02234
02235 double xmin, ymin, xmax, ymax;
02236 in.read(reinterpret_cast<char*>(&xmin), sizeof(xmin));
02237 in.read(reinterpret_cast<char*>(&ymin), sizeof(ymin));
02238 in.read(reinterpret_cast<char*>(&xmax), sizeof(xmax));
02239 in.read(reinterpret_cast<char*>(&ymax), sizeof(ymax));
02240 if (!in.good()) return false;
02241 bd = Geometry::Rectangle(Geometry::Kernel::FT(xmin),
02242 Geometry::Kernel::FT(ymin),
02243 Geometry::Kernel::FT(xmax),
02244 Geometry::Kernel::FT(ymax));
02245 int rows = intEdgeIndex->numRows();
02246 int cols = intEdgeIndex->numCols();
02247 initialize(bd, rows, cols);
02248
02249 while (numBoundaryEdges() > 0) {
02250 BdEdgeHandle e = getBoundaryEdge(0);
02251 freeEdge(e);
02252 }
02253
02254 unsigned short int n;
02255 in.read(reinterpret_cast<char*>(&n), sizeof(n));
02256 double x, y;
02257 if (!in.good()) return false;
02258
02259 for (int i = 0; i < n; i++) {
02260
02261
02262
02263
02264 in.read(reinterpret_cast<char*>(&x), sizeof(x));
02265 in.read(reinterpret_cast<char*>(&y), sizeof(y));
02266 if (!in.good()) return false;
02267 Geometry::Point p(x, y);
02268 assert(newVertex(Vertex::BOUNDARY, p)->index == i);
02269 }
02270
02271 in.read(reinterpret_cast<char*>(&n), sizeof(n));
02272 if (!in.good()) return false;
02273
02274 for (int i = 0; i < n; i++) {
02275
02276
02277
02278
02279 in.read(reinterpret_cast<char*>(&x), sizeof(x));
02280 in.read(reinterpret_cast<char*>(&y), sizeof(y));
02281 if (!in.good()) return false;
02282 Geometry::Point p(x, y);
02283 assert(newVertex(Vertex::INTERIOR, p)->index == i);
02284 }
02285
02286 in.read(reinterpret_cast<char*>(&n), sizeof(n));
02287 if (!in.good()) return false;
02288 unsigned char prevTypeInt, nextTypeInt;
02289 Vertex::Type prevType, nextType;
02290 unsigned short int prevIndex, nextIndex;
02291 unsigned short int prevCornerIndex, nextCornerIndex;
02292
02293 for (int i = 0; i < n; i++) {
02294
02295
02296
02297
02298 in.read(reinterpret_cast<char*>(&prevCornerIndex),
02299 sizeof(prevCornerIndex));
02300 in.read(reinterpret_cast<char*>(&nextCornerIndex),
02301 sizeof(nextCornerIndex));
02302 in.read(reinterpret_cast<char*>(&prevTypeInt), sizeof(prevTypeInt));
02303 in.read(reinterpret_cast<char*>(&prevIndex), sizeof(prevIndex));
02304 in.read(reinterpret_cast<char*>(&nextTypeInt), sizeof(nextTypeInt));
02305 in.read(reinterpret_cast<char*>(&nextIndex), sizeof(nextIndex));
02306 if (!in.good()) return false;
02307 switch (prevTypeInt) {
02308 case 1: prevType = Vertex::BOUNDARY; break;
02309 case 2: prevType = Vertex::CORNER; break;
02310 default: return false;
02311 };
02312 switch (nextTypeInt) {
02313 case 1: nextType = Vertex::BOUNDARY; break;
02314 case 2: nextType = Vertex::CORNER; break;
02315 default: return false;
02316 };
02317 newBoundaryEdge(getVertex(prevType, prevIndex),
02318 getVertex(nextType, nextIndex),
02319 getVertex(Vertex::CORNER, prevCornerIndex),
02320 getVertex(Vertex::CORNER, nextCornerIndex));
02321 }
02322
02323 in.read(reinterpret_cast<char*>(&n), sizeof(n));
02324 if (!in.good()) return false;
02325
02326 for (int i = 0; i < n; i++) {
02327
02328
02329
02330
02331 in.read(reinterpret_cast<char*>(&prevTypeInt), sizeof(prevTypeInt));
02332 in.read(reinterpret_cast<char*>(&prevIndex), sizeof(prevIndex));
02333 in.read(reinterpret_cast<char*>(&nextTypeInt), sizeof(nextTypeInt));
02334 in.read(reinterpret_cast<char*>(&nextIndex), sizeof(nextIndex));
02335 if (!in.good()) return false;
02336 switch (prevTypeInt) {
02337 case 0: prevType = Vertex::INTERIOR; break;
02338 case 1: prevType = Vertex::BOUNDARY; break;
02339 default: return false;
02340 };
02341 switch (nextTypeInt) {
02342 case 0: nextType = Vertex::INTERIOR; break;
02343 case 1: nextType = Vertex::BOUNDARY; break;
02344 default: return false;
02345 };
02346 newInteriorEdge(getVertex(prevType, prevIndex),
02347 getVertex(nextType, nextIndex));
02348 }
02349
02350 unsigned char colorInt;
02351 in.read(reinterpret_cast<char*>(&x), sizeof(x));
02352 in.read(reinterpret_cast<char*>(&y), sizeof(y));
02353 Geometry::Point p(x, y);
02354 in.read(reinterpret_cast<char*>(&colorInt), sizeof(colorInt));
02355 if (!in.good()) return false;
02356 Color c;
02357 switch (colorInt) {
02358 case 0: c = WHITE; break;
02359 case 1: c = BLACK; break;
02360 default: return false;
02361 }
02362
02363
02364 assert(queryPoints->size() == 1);
02365 QueryPoint& q = queryPoints->point(0);
02366 if (color(p) != c) q.setColor(opposite(q.color()));
02367
02368 test();
02369 return true;
02370 }