2

I'm looking for an efficient algorithm for handling 2D dynamic rectilinear convex hulls.

I've coded up a static algorithm, but while it works in most cases, it doesn't work in all, so I'm also looking for resources on static rectilinear convex hulls. Wikipedia has some research papers on algorithms, but I can't access them. So looking for other sources or help writing up the code.

Any help would be appreciated, an algorithm in Python, most appreciated.

Current static Code:

def stepped_hull(points, is_sorted=False, return_sections=False):
    # May be equivalent to the orthogonal convex hull

    if not is_sorted:
        points = sorted(set(points))

    if len(points) <= 1:
        return points

    # Get extreme y points
    min_y = min(points, lambda p:p[1])
    max_y = max(points, lambda p:p[1])

    points_reversed = list(reversed(points))

    # Create upper section
    upper_left = build_stepped_upper(points, max_y)
    upper_right = build_stepped_upper(points_reversed, max_y)

    # Create lower section
    lower_left = build_stepped_lower(points, min_y)
    lower_right = build_stepped_lower(points_reversed, min_y)

    # Correct the ordering
    lower_right.reverse()
    upper_left.reverse()

    if return_sections:
        return lower_left, lower_right, upper_right, upper_left

    # Remove duplicate points
    hull = OrderedSet(lower_left + lower_right + upper_right + upper_left)
    return list(hull)

def build_stepped_upper(points, max_y):
    # Steps towards the highest y point

    section = [points[0]]

    if max_y != points[0]:
        for point in points:
            if point[1] >= section[-1][1]:
                section.append(point)

            if max_y == point:
                break
    return section

def build_stepped_lower(points, min_y):
    # Steps towards the lowest y point

    section = [points[0]]

    if min_y != points[0]:
        for point in points:
            if point[1] <= section[-1][1]:
                section.append(point)

            if min_y == point:
                break
    return section
Nuclearman
  • 5,029
  • 1
  • 19
  • 35
  • By dynamic do you mean you want to maintain a x-y convex hull where its points are modified along the program execution ? Do you mean your static algorithms works, but it fails for updating the convex hull, or does it fail on something else ? – mmgp Jan 19 '13 at 02:07
  • Basically, I want to create a x-y hull from a set of points, remove 1 or more hull points, recalculate the hull. Remove some sort points recalculate, so on and so on. I'd like to avoid deleting points at O(N log N), O(N) might be workable, O(log N) ideal. I'm currently using an static algorithm that gives the correct points, but due to the way I coded it, may have crossed edges in the case where a point is extreme point for both x and y. A relatively minor issue, but a sign that the algorithm may be flawed in other ways. Hence would prefer a known "correct" algorithm if possible. – Nuclearman Jan 19 '13 at 02:16
  • I confess I haven't implemented algorithms for this kind of convex hull, but is it unique (considering a single plane orientation) ? For example, if you have two points, `a` and `b`, in the same x coordinate with distinct y coordinates, can you simply link a point `c` that is to the left of both points, and also below both of them, to the uppermost between `a` and `b` ? Or is there a requirement to connect `c` first to the bottom most of them first ? – mmgp Jan 19 '13 at 02:22
  • Connecting to the uppermost in that situation would create a convex hull that has an area greater than the one done by the other method. Does that disqualify the former as a x-y convex hull ? – mmgp Jan 19 '13 at 02:23
  • The algorithm I'm using to check which points to remove, relies on the proper ordering so c-b-a is required, which is why the minor issue I have with the static algorithm is problematic. Although, now that you mention it, that might be an issue with obtaining algorithms much better than O(N) algorithms – Nuclearman Jan 19 '13 at 02:33
  • It is definitely not unique considering any plane orientation. So your crossing is probably caused by not considering the multiple possible orientations. – mmgp Jan 19 '13 at 02:33
  • That's more-less what I thought the issue was now that you mention it. Although, I should probably double check that the hull points themselves are consistent, as that is the important part. – Nuclearman Jan 19 '13 at 02:42
  • Actually, even in a single orientation there are many possible such hulls. There are also several definitions for it, I'm reading Ottmann's paper about it right now. – mmgp Jan 19 '13 at 02:44
  • I've put the algorithm, as it seems it may not be what I thought it was. – Nuclearman Jan 19 '13 at 03:02
  • Your algorithm has no chance to produce a result like in the linked wikipedia page, right ? You are not adding extra points to do so, it is actually the algorithm for "Type 2" cr-x-y-convex-hull (Ottmann's convention to distinguish between other x-y-convex-hull definitions) except for this missing part I just mentioned. This "Type 2" assumes that there are two points of yours in the minimal rectilinear rectangle (not the x-y-hull) that involves your points, and these two points are in the opposite corners of this rectangle. Ottmann also handles what he calls Type 1, 3, and 4. – mmgp Jan 19 '13 at 03:05
  • Hmmm perhaps not. Didn't notice that points were being added. – Nuclearman Jan 19 '13 at 03:19
  • They are most likely artificial points, so you can actually construct those "L" connections by going through them. – mmgp Jan 19 '13 at 03:23
  • I'd say you're probably right. – Nuclearman Jan 19 '13 at 03:31

1 Answers1

0

For implementation of correct algorithms you may want to take a look at this. For the dynamic maintenance of the Rectilinear Convex hull, it is better to look for dynamic data structures to maintain the Maxima of a Set, which is a more studied topic. The set of maximal elements of a point set is the set of vertices of the Rectilinear Convex Hull, so both problems are equivalent to each other.

You can find an algorithm that takes $O(\log n)$ time per operation in this paper.

Carlos Alegría
  • 374
  • 1
  • 3
  • 13