//Realiza el algoritmo de Graham de las 3 monedas para hallar el Convex Hull S de una lista de Puntos Q. //Devuelve una Pila con el resultado clockwise. void grahamScan(std::list<Point2D> & Q, std::stack<Point2D> & S){ minimal = encontrarMinimal(Q); //Encuentra el minimal izquierda abajo // std::cout<<"Minimal: "; minimal.print(); borrarMinimal(Q, minimal); //Borra el minimal de la cola Q.sort(comparePoint2DPolar); //Ordena en forma polar std::cout<<"Lista ordenada\n"; printList(Q); eliminarColineales(Q); //Hace limpieza de los puntos colineales, dejando el mas lejano std::cout<<"Lista ordenada\n"; printList(Q); //Ubica las 3 primeras monedas S.push(minimal); //Agrega el primero que es el minimal //Agrega la segunda y tercera std::list<Point2D>::iterator it = Q.begin(); //Iterador para recorrer la Q for(unsigned int i = 0; i < 2 and it != Q.end(); i++, it++){ S.push(*it); } //tamanio de Q unsigned int n = Q.size(); //Loop de Graham Scan for(unsigned int i = 2; i < n and it != Q.end(); i++, it++){ Point2D ntt = nextToTop(S); Point2D nt = top(S); Point2D p = *it; while(!leftTurn(ntt, nt, p) and (S.size() > 1)){ //Si no froman un giro a la izquierda y queda mas de un elemento en S // printStack(S); S.pop(); //Saco el tope de S ntt = nextToTop(S); //Renuevo los valores y vuelvo a probar nt = top(S); } S.push(p); //Agrego el elemento a S } }
// Prints convex hull of a set of n points. void convexHull() { // Find the bottommost point int Min = 0; for (int i = 1; i < N; i++) { // Pick the bottom-most or chose the left most point in case of tie if (cmpYX(points[i], points[Min])) Min = i; } // Place the bottom-most point at first position swap(points[0], points[Min]); // Sort N - 1 points with respect to the first point. A point p1 comes // before p2 in sorted ouput if p2 has larger polar angle (in // counterclockwise direction) than p1 p0 = points[0]; qsort(&points[1], N - 1, sizeof(PointI), compare); // Create an empty stack and push first three points to it. stack<PointI> S; S.push(points[0]); S.push(points[1]); S.push(points[2]); // Process remaining n-3 points for (int i = 3; i < N; i++) { // Keep removing top while the angle formed by points next-to-top, // top, and points[i] makes a non-left turn while (getSide(nextToTop(S), points[i], S.top()) != -1) S.pop(); S.push(points[i]); } // Now stack has the output points, print contents of stack while (!S.empty()) { PointI p = S.top(); cout << p << endl; S.pop(); } }
/////////////////////////////////////////////////////////////////////////////// // Prints convex hull of a set of n points. void computeConvexHull(const std::vector<Point*>& pointArray, std::vector<Point*>& curve, const bool bVerbose) { if(bVerbose) { fprintf(stdout, "computeConvexHull: nbPts: %ld\n", pointArray.size()); } curve.resize(0); if(pointArray.size() < 3) { return; } std::vector<Point*> points; points.resize(pointArray.size()); for(size_t i=0; i<points.size(); i++) { points[i] = pointArray[i]; } const size_t n = points.size(); // Find the bottommost point size_t min = 0; Coord ymin = points[min]->y(); Coord xmin = points[min]->x(); for(size_t i=1; i<n; i++) { const Coord x = points[i]->x(); const Coord y = points[i]->y(); // Pick the bottom-most or chose the left most point in case of tie if ((y<ymin) || (isEqual(y,ymin) && x<xmin)) { min = i; xmin = x; ymin = y; } } // Place the bottom-most point at first position //std::swap(points[0], points[min]); if(min != 0) { Point* p = points[0]; points[0] = points[min]; points[min] = p; } if(0 && bVerbose) { fprintf(stdout, "pivot point: %s, at pos:%ld\n", points[0]->toString().c_str(), min); } // Sort n-1 points with respect to the first point. A point p1 comes // before p2 in sorted ouput if p2 has larger polar angle (in // counterclockwise direction) than p1 // qsort(&points[1], n-1, sizeof(Point), compare); ComparePoints<Point*> compareFunction(points[0]); // Note: for some unknown reason, the std::sort does not work on apple c++ compiler. // the swap of pointers is not working properly!!! // std::sort(points.begin()+1, points.end(), compareFunction); // BubbleSort(points, 1, compareFunction); QuickSort(points, 1, points.size()-1, compareFunction); // print the point array if(0 && bVerbose) { fprintf(stdout, "** List of sorted points\n"); for(size_t i=0; i<n; i++) { if(points[i]) { fprintf(stdout, "[%03ld]: %s \n", i, points[i]->toString().c_str()); } else { fprintf(stdout, "[%ld] null\n", i); } } fprintf(stdout, "\n\n"); } // Create an empty stack and push first three points to it. std::stack<Point*> stack; stack.push(points[0]); stack.push(points[1]); stack.push(points[2]); // Process remaining n-3 points for(size_t i=3; i<n; i++) { // Keep removing top while the angle formed by points next-to-top, // top, and points[i] makes a non-left turn while(stack.size()>1 && ComputePointOrientation(nextToTop(stack), stack.top(), points[i]) != PointOrientationConterClockWise) { stack.pop(); } stack.push(points[i]); } // collect the curve curve.resize(0); while (!stack.empty()) { curve.push_back(stack.top()); stack.pop(); } }