void Path::sample(int numSamples, QList<Eigen::Vector2d> & out) const { assert(isValid()); out.clear(); if(type() == SingleVertex) { Eigen::Vector2d pos = singleVertex()->pos(); for(int i=0; i<numSamples; ++i) out << pos; } else { assert(numSamples >= 2); double ds = length()/(numSamples-1); double cumulativeLength = 0; int indexHe = 0; KeyHalfedge he = halfedges_[indexHe]; for(int i=0; i<numSamples; ++i) { double s = i*ds; while ( (s > cumulativeLength + he.length()) && (indexHe+1 < halfedges_.size()) ) { cumulativeLength += he.length(); he = halfedges_[++indexHe]; } out << he.pos(s-cumulativeLength); } } }
// The set of cells this helper points to KeyCellSet Path::cells() const { KeyCellSet res; switch(type()) { case SingleVertex: res << vertex_; break; case OpenHalfedgeList: for(int i=0; i<size(); ++i) { KeyHalfedge he = halfedges_[i]; res << he.startVertex() << he.edge; } res << halfedges_.last().endVertex(); break; case Invalid: break; } return res; }
// The set of cells this helper points to KeyCellSet Cycle::cells() const { KeyCellSet res; switch(type()) { case SingleVertex: res << vertex_; break; case ClosedHalfedge: res << halfedges_[0].edge; break; case OpenHalfedgeList: for(int i=0; i<size(); ++i) { KeyHalfedge he = halfedges_[i]; res << he.startVertex() << he.edge; } break; case Invalid: break; } return res; }
void Cycle::sample(int numSamples, QList<EdgeSample> & out) const { assert(isValid()); out.clear(); if(type() == SingleVertex) { Eigen::Vector2d pos = singleVertex()->pos(); EdgeSample posSample(pos[0],pos[1],0); for(int i=0; i<numSamples; ++i) out << posSample; } else { QList<EdgeSample> outAux; assert(numSamples >= 2); double l = length(); double ds = l/(numSamples-1); // Computing unoffset cycle double cumulativeLength = 0; int indexHe = 0; KeyHalfedge he = halfedges_[indexHe]; for(int i=0; i<numSamples; ++i) { double s = i*ds; while ( (s > cumulativeLength + he.length()) && (indexHe+1 < halfedges_.size()) ) { cumulativeLength += he.length(); he = halfedges_[++indexHe]; } outAux << he.sample(s-cumulativeLength); } // Apply offset int i0 = std::floor( numSamples * s0_ + 0.5); if(i0 < 0) i0 = 0; if(i0 > numSamples - 1) i0 = numSamples - 1; for(int i=i0; i<numSamples; ++i) out << outAux[i]; for(int i=0; i<i0; ++i) out << outAux[i]; } }
ProperCycle::ProperCycle(const KeyEdgeSet & edgeSetConst) { // If no edge, then invalid if(edgeSetConst.isEmpty()) return; // if not all edges at same time, then invalid KeyEdge * first = *edgeSetConst.begin(); Time t = first->time(); foreach(KeyEdge * iedge, edgeSetConst) { if(iedge->time() != t) { //QMessageBox::information(0, QObject::tr("operation aborted"), // QObject::tr("not all edges are on same time")); return; } } // copy the set to be able to modify it KeyEdgeSet edgeSet = edgeSetConst; // insert first edge halfedges_ << KeyHalfedge(first, true); edgeSet.erase(edgeSet.begin()); // check case where it's a pure loop if(first->isClosed()) { if(!edgeSet.isEmpty()) { //QMessageBox::information(0, QObject::tr("operation aborted"), // QObject::tr("more than one edge and one of them is a pure loop")); halfedges_.clear(); return; } // else: good! } else { // not a pure loop, let's find the chain while(!edgeSet.isEmpty()) { KeyHalfedge lastAddedHalfedge = halfedges_.last(); // we know it's not a loop, otherwise couldn't be here KeyVertex * lastVertex = lastAddedHalfedge.endVertex(); // hence this is a valid vertex // find next KeyHalfedge nextHalfedge; auto it = edgeSet.begin(); auto itEnd = edgeSet.end(); for(;it!=itEnd;++it) { if((*it)->startVertex() == lastVertex) { nextHalfedge = KeyHalfedge(*it, true); break; } else if((*it)->endVertex() == lastVertex) { nextHalfedge = KeyHalfedge(*it, false); break; } } // if found: great, insert it! if(nextHalfedge.isValid()) { halfedges_ << nextHalfedge; edgeSet.erase(it); } else { //QMessageBox::information(0, QObject::tr("operation aborted"), // QObject::tr("not a valid loop: no valid next edge found")); halfedges_.clear(); return; } } // So far, we've inserted all N edges, and every edge i in [0,N-2] // satisfies edges_[i]->endVertex() == edges_[i+1]->startVertex() // Check that it's looping if(halfedges_.last().endVertex() != halfedges_.first().startVertex()) { //QMessageBox::information(0, QObject::tr("operation aborted"), // QObject::tr("not a valid loop: last edge not compatible with first one")); halfedges_.clear(); return; } // Check that it's simple KeyVertexSet vertices; foreach(KeyHalfedge he, halfedges_) { KeyVertex * vertex = he.startVertex(); if(vertices.contains(vertex)) { //QMessageBox::information(0, QObject::tr("operation aborted"), // QObject::tr("not a valid loop: not simple")); halfedges_.clear(); return; } else { vertices << vertex; } } // Done :-) If you're here you have a valid simple loop }