ConvexHull findConvexHull(PointSet *pointSet) { int pointCount = pointSet->getSize(); pointSet->sortPointsByAngle(); if (pointCount <= 3) { // The points are already a convex hull ConvexHull hull; for (int i = 0; i < pointCount; ++i) { hull.addPoint(*pointSet->getPoint(i)); } if (pointCount > 0) { hull.addPoint(*pointSet->getPoint(0)); } return hull; } std::stack<const Point *> candiates; const Point *prev; const Point *now; candiates.push(pointSet->getLastPoint()); candiates.push(pointSet->getReferencePoint()); // Is always the first (idx 0) // element in the point set for (int i = 1; i < pointCount;) { const Point *point = pointSet->getPoint(i); now = candiates.top(); candiates.pop(); prev = candiates.top(); candiates.push(now); if (isCCW(prev->pos(), now->pos(), point->pos())) { if (point->pos() == now->pos() && USE_CUSTOM_ALGO_FIX) { std::cout << "I saved your algorithm" << std::endl; } else { candiates.push(point); } ++i; } else { candiates.pop(); } } ConvexHull hull(candiates); return hull; }
static size_t computeEdgesAndIntersect(const GrMatrix& matrix, const GrMatrix& inverse, GrPoint* vertices, size_t numVertices, GrEdgeArray* edges, float sign) { if (numVertices < 3) { return 0; } matrix.mapPoints(vertices, numVertices); if (sign == 0.0f) { sign = isCCW(vertices, numVertices) ? -1.0f : 1.0f; } GrPoint p = sanitizePoint(vertices[numVertices - 1]); for (size_t i = 0; i < numVertices; ++i) { GrPoint q = sanitizePoint(vertices[i]); if (p == q) { continue; } GrDrawState::Edge edge = computeEdge(p, q, sign); edge.fZ += 0.5f; // Offset by half a pixel along the tangent. *edges->append() = edge; p = q; } int count = edges->count(); if (count == 0) { return 0; } GrDrawState::Edge prev_edge = edges->at(0); for (int i = 0; i < count; ++i) { GrDrawState::Edge edge = edges->at(i < count - 1 ? i + 1 : 0); if (parallel(edge, prev_edge)) { // 3 points are collinear; offset by half the tangent instead vertices[i].fX -= edge.fX * 0.5f; vertices[i].fY -= edge.fY * 0.5f; } else { vertices[i] = prev_edge.intersect(edge); } inverse.mapPoints(&vertices[i], 1); prev_edge = edge; } return edges->count(); }
HullState findConvexHullStep(PointSet *pointSet, int simulateUntilStep) { int step = 0; int pointCount = pointSet->getSize(); pointSet->sortPointsByAngle(); //++step; if (step++ == simulateUntilStep) // sort done -> update numbers { return HullState::SortDone(step); } if (pointCount <= 3) { // The points are already a convex hull ConvexHull hull; for (int i = 0; i < pointCount; ++i) { hull.addPoint(*pointSet->getPoint(i)); } if (pointCount > 0) { hull.addPoint(*pointSet->getPoint(0)); } return HullState::HullFound(hull); } std::stack<const Point *> candiates; const Point *prev; const Point *now; candiates.push(pointSet->getLastPoint()); candiates.push(pointSet->getReferencePoint()); // Is always the first (idx 0) // element in the point set //++step; if (step++ == simulateUntilStep) // break print candidates { return HullState::CandidateAdded(candiates, step); } for (int i = 1; i < pointCount;) { const Point *point = pointSet->getPoint(i); now = candiates.top(); candiates.pop(); prev = candiates.top(); candiates.push(now); if (isCCW(prev->pos(), now->pos(), point->pos())) { candiates.push(point); // std::cout << "adding " << i << std::endl; ++i; //++step; if (step++ == simulateUntilStep) // break print candidates { return HullState::CandidateAdded(candiates, step); } } else { //++step; if (step++ == simulateUntilStep) // break print candidates { return HullState::CandidatePoped(candiates, point, step); } // std::cout << "pop" << std::endl; candiates.pop(); } } ConvexHull hull(candiates); return HullState::HullFound(hull); }