// Returns whether the facet facet is attached to the cell // that is used to represent facet bool edge_attached_to(const DT_3& dt, const Edge& edge, const Facet& facet) { if(dt.is_infinite(facet)) { return false; } Vertex_handle v1 = edge.first->vertex(edge.second); Vertex_handle v2 = edge.first->vertex(edge.third); Cell_handle cell = facet.first; int i1 = facet.second; int i2 = cell->index(v1); int i3 = cell->index(v2); CGAL_assertion(i1!=i2); CGAL_assertion(i1!=i3); CGAL_assertion(i2!=i3); int j = 0; while(j==i1 || j==i2 || j==i3) { j++; } // j is the index of the third point of the facet Vertex_handle w = cell->vertex(j); return CGAL::side_of_bounded_sphere(v1->point(),v2->point(),w->point())==CGAL::ON_BOUNDED_SIDE; }
static Cell_handle findBestCell(const Vector_3 &direction, const Vertex_handle &infinity, const Cell_handle &startingCell) { DEBUG_START; /* FIXME: Maybe some hint will be useful here */ ASSERT(startingCell->has_vertex(infinity) && "Wrong input"); Cell_handle bestCell = startingCell; Cell_handle nextCell = bestCell; double maxProduct = calculateProduct(direction, bestCell, infinity); unsigned numIterations = 0; do { ++numIterations; bestCell = nextCell; ASSERT(bestCell->has_vertex(infinity) && "Wrong iteration"); int infinityIndex = bestCell->index(infinity); for (int i = 0; i < NUM_CELL_VERTICES; ++i) { if (i == infinityIndex) continue; Cell_handle neighbor = bestCell->neighbor(i); double product = calculateProduct(direction, neighbor, infinity); if (product > maxProduct) { nextCell = neighbor; maxProduct = product; } } } while (nextCell != bestCell); ASSERT(bestCell->has_vertex(infinity) && "Wrong result"); DEBUG_END; return bestCell; }
static void printCell(const Cell_handle &cell, const Vertex_handle &infinity) { DEBUG_START; unsigned infinityIndex = cell->index(infinity); for (unsigned i = 0; i < NUM_CELL_VERTICES; ++i) if (i != infinityIndex) std::cout << cell->vertex(i)->info() << " "; std::cout << std::endl; DEBUG_END; }
AlphaSimplex3D:: AlphaSimplex3D(const Delaunay3D::Facet& f, const SimplexSet& simplices, const Delaunay3D& Dt) { Cell_handle c = f.first; for (int i = 0; i < 4; ++i) if (i != f.second) Parent::add(c->vertex(i)); Cell_handle o = c->neighbor(f.second); int oi = o->index(c); VertexSet::const_iterator v = static_cast<const Parent*>(this)->vertices().begin(); const DPoint& p1 = (*v++)->point(); const DPoint& p2 = (*v++)->point(); const DPoint& p3 = (*v)->point(); attached_ = false; if (!Dt.is_infinite(c->vertex(f.second)) && CGAL::side_of_bounded_sphere(p1, p2, p3, c->vertex(f.second)->point()) == CGAL::ON_BOUNDED_SIDE) attached_ = true; else if (!Dt.is_infinite(o->vertex(oi)) && CGAL::side_of_bounded_sphere(p1, p2, p3, o->vertex(oi)->point()) == CGAL::ON_BOUNDED_SIDE) attached_ = true; else alpha_ = CGAL::squared_radius(p1, p2, p3); if (attached_) { if (Dt.is_infinite(c)) alpha_ = simplices.find(AlphaSimplex3D(*o))->alpha(); else if (Dt.is_infinite(o)) alpha_ = simplices.find(AlphaSimplex3D(*c))->alpha(); else alpha_ = std::min(simplices.find(AlphaSimplex3D(*c))->alpha(), simplices.find(AlphaSimplex3D(*o))->alpha()); } }
bool DualPolyhedron_3::lift(Cell_handle cell, unsigned iNearest) { DEBUG_START; Vector_3 xOld = cell->info().point - CGAL::Origin(); std::cout << "Old tangient point: " << xOld << std::endl; const auto activeGroup = calculateActiveGroup(cell, iNearest, items); if (activeGroup.empty()) { DEBUG_END; return false; } Vector_3 xNew = leastSquaresPoint(activeGroup, items); std::cout << "New tangient point: " << xNew << std::endl; ASSERT(cell->has_vertex(infinite_vertex())); unsigned infinityIndex = cell->index(infinite_vertex()); std::vector<Vertex_handle> vertices; Vertex_handle dominator; double alphaMax = 0.; double alphaMax2 = 0.; for (unsigned i = 0; i < NUM_CELL_VERTICES; ++i) { if (i == infinityIndex) continue; vertices.push_back(cell->vertex(i)); Vertex_handle vertex = mirror_vertex(cell, i); Plane_3 plane = ::dual(vertex->point()); double alpha; bool succeeded; std::tie(succeeded, alpha) = calculateAlpha(xOld, xNew, plane); if (!succeeded) return false; std::cout << "Alpha #" << i << ": " << alpha << std::endl; ASSERT(alpha <= 1. && "Wrongly computed alpha"); if (alpha > alphaMax) { alphaMax2 = alphaMax; alphaMax = alpha; dominator = vertex; } } std::cout << "Maximal alpha: " << alphaMax << std::endl; std::cout << "Maximal alpha 2nd: " << alphaMax2 << std::endl; ASSERT(alphaMax < 1. && "What to do then?"); if (alphaMax > 0.) { std::cout << "Full move is impossible, performing partial move" << std::endl; partiallyMove(xOld, xNew, vertices, dominator, alphaMax, alphaMax2); } else { std::cout << "Performing full move" << std::endl; if (!fullyMove(vertices, xNew, activeGroup)) { DEBUG_END; return false; } } DEBUG_END; return true; }