2
votes

I'm trying to implement in C++ the divide and conquer algorithm of finding the convex hull from a set of two dimensional points. For simplicity let's assume that all the points are described with integers.

The most important part of the algorithm is merging the two convex hulls that you have computed from previous recursive calls. This part involves finding the lower and upper tangents of the two convex hulls and then proceeding with the merging.

The merging is trivial, if you have found the four points that describe the tangents, then the points that aren't inside the polygon defined by these four points will be part of the new convex hull.

However, I have no idea how to find these four points.

Here is the pseudocode that most sources (this one is from http://www.cs.wustl.edu/~pless/506/l3.html) suggest for finding the lower tangent of convex hull HA and convex hull HB.

Finding the Lower Tangent
LowerTangent(HA ; HB ) :
(1) Let a be the rightmost point of HA .
(2) Let b be the leftmost point of HB .
(3) While ab is not a lower tangent for HA and HB do
(a) While ab is not a lower tangent to HA do a = a - 1 (move a clockwise).
(b) While ab is not a lower tangent to HB do b = b + 1 (move b counterCW).
(4) Return ab.

(1), (2)

The points are initially sorted by their x coordinate, so finding the rightmost point of HA and the leftmost point of HB can be done in O(1).

a = HA[HA.size-1]
b = HB[0]

Now I can't understand the next steps.

Having chosen this ab line segment, how can we check if ab is not a lower tangent so we can either enter the first while loop or not?

And then, how do we move the point a to a-1 by following a clockwise direction? The points are sorted by their x coordinate, and doing just a = a-1 will lead to wrong results.

Thanks!

2

2 Answers

2
votes

Your reference only briefly states:

Lower tangency is a condition that can be tested locally by an orientation test of the two vertices and neighboring vertices on the hull. (This is a simple exercise.)

and doesn't appear to give any more details. I found this reference which goes into further details of how to find the lower tangency including some example code.

Also note that your should not be sorting the X-coordinates for this purpose. This algorithm relies on the points being in their normal consecutive order that defines the polygon. Sorting by X only helps you in finding the initial points.

Pseudo-code of the lower tangency algorithm from that reference is:

idx1 = (Rightmost point index of Poly1)
idx2 = (Leftmost point index of Poly2)    

while (TRUE) 
    while (isLeft(Poly1[idx2], Poly2[idx1], Poly2[idx1+1]) <= 0)
        ++idx1;
    end while

    while (isLeft(Poly2[idx1], Poly1[idx2], Poly1[idx2-1]) >= 0)
        --idx2;
        done = FALSE;
    end while
end while

// idx1/idx2 are now the two indices that form the lower tangent    

The isLeft() code from the same reference is:

float isLeft (Point P0, Point P1, Point P2)
{
    return (P1.x - P0.x)*(P2.y - P0.y) - (P2.x - P0.x)*(P1.y - P0.y);
}
0
votes

If the two convex polygons are intersecting then it is incorrect to assume that there are only two tangents that connect the two polygons.

It depends upon how exactly the points are divided. If division ensures that the resultant convex hulls never intersect then it is fine to make such assumption. But if the division of points does not guarantee the convex hulls to be non intersecting then algorithm needs to be modified to find multiple tangents.