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; }
void DualPolyhedron_3::associateVertex(const Vertex_handle &vertex) { DEBUG_START; int iPlane = vertex->info(); if (isOuterVertex(vertex)) { Cell_handle cell; int iVertex, iInfinity; bool result = is_edge(vertex, infinite_vertex(), cell, iVertex, iInfinity); ASSERT(result && "Wrong set"); TDelaunay_3::Edge edge(cell, iVertex, iInfinity); auto circulator = incident_cells(edge); auto end = circulator; do { Cell_handle currentCell = circulator; ASSERT(currentCell->has_vertex(vertex)); ASSERT(currentCell->has_vertex(infinite_vertex())); currentCell->info().associations.insert(iPlane); items[iPlane].associations.insert(currentCell); items[iPlane].resolved = true; ++circulator; } while (circulator != end); } else { Vector_3 direction = items[iPlane].direction; Cell_handle bestCell = findBestCell(direction, infinite_vertex(), infinite_cell()); bestCell->info().associations.insert(iPlane); /* FIXME: Maybe the association for a plane is singular? */ items[iPlane].associations.insert(bestCell); } DEBUG_END; }
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; }