1

I've created a working convex hull program that is able to draw the points and lines and everything required to make it visually appealing. My question, is there a way to design it so that only one for loop is needed? Instead of making a upper and lower hull? Can't seem to figure out how I would be able to keep track once the upper hull reaches the end/begins lower.

void computeConvexHull(QPainter * painter)
{
    int k = 0;
    std::vector<QPointF> vecLinePoints(2*vecPoints.size());

    // Sort points lexicographically
    std::sort(vecPoints.begin(),vecPoints.end(), xyCompare());

    //begin with far left, work our way to lower hull
    // Build upper hull
    for (int i = vecPoints.size()-2, j = k+1; i >= 0; i--)
    {
        while (k >= j && checkPoints(vecLinePoints[k-2], vecLinePoints[k-1], vecPoints[i]) <= 0)
            k--;
        vecLinePoints[k++] = vecPoints[i];
    }

    // Build lower hull
    for (int i = 0; i < vecPoints.size(); ++i)
    {
        while (k >= 2 && checkPoints(vecLinePoints[k-2], vecLinePoints[k-1], vecPoints[i]) <= 0)
            k--;
        vecLinePoints[k++] = vecPoints[i];
    }



    //reduce size of vector
    vecLinePoints.resize(k);
  • You can use a single for-loop, but you still need two arrays and to adjust "check points". Basically if the crossproduct, `checkPoints`, is less than `0` you put it in one array, greater than `0` you put it in another array and if it's equal to `0` you put it in both arrays. Note: That your algorithm is a bit odd in that it goes right to left then left to right rather than changing the signs (not sure if this is valid). The only ways to avoid the upper and lower hulls is to use a different algorithm. I tried doing that a while back and didn't find any real benefit to one loop or two loops. – Nuclearman Dec 01 '15 at 07:42

1 Answers1

0

Sure, you could always do both upper and lower at the same time... but that's a waste. There exist more efficient algorithms than Andrew's monotone chain; see Wikipedia.

Hope this helps.

Dúthomhas
  • 8,200
  • 2
  • 17
  • 39