问题
I am trying to find a way to determine the rectilinear polygon from a set of integer points (indicated by the red dots in the pictures below). The image below shows what I would like to achieve:
1.
I need only the minimal set of points that define the boundary of the rectilinear polygon. Most hull algorithms I can find do not satisfy the orthogonal nature of this problem, such as the gift-wrapping algorithm, which produce the following result (which is not what I want)...
2.
How can I get the set of points that defines the boundary shown in image 1.?
Updated:
Figure 1. is no longer refereed to as convex..
回答1:
I think what you want to compute is the Rectilinear Convex Hull (or Orthogonal Convex Hull) of the set of points. The rectilinear convex hull is an ortho-convex shape, that is, the intersection of the shape with any horizontal or vertical line results in an empty set, a point, or a line segment.
The vertices of the rectilinear convex hull are the set of maximal points under vector dominance. The rectilinear convex hull can then be computed in optimal O(n log n) time. A very simple algorithm is presented in Preparata's book on Computational Geometry (see the section 4.1.3).
回答2:
Following the definition from wikipedia, it is rather easy to create a fast algorithm.
- Start constructing upper hull from the leftmost point (uppermost among such if there are many). Add this point to a list.
- Find the next point: among all the points with both coordinates strictly greater than of the current point, choose the one with minimal x coordinate. Add this point to your list and continue from it.
- Continue adding points in step 2 as long as you can.
- Repeat the same from the rightmost point (uppermost among such), but going to the left. I.e. each time choose the next point with greater y, less x, and difference in x must be minimal.
- Merge the two lists you got from steps 3 and 4, you got upper hull.
- Do the same steps 1-5 for lower hull analogously.
- Merge the upper and lower hulls found at steps 5 and 6.
In order to find the next point quickly, just sort your points by x coordinate. For example, when building the very first right-up chain, you sort by x increasing. Then iterate over all points. For each point check if its y coordinate is greater than the current value. If yes, add the point to the list and make it current.
Overall complexity would be O(N log N) for sorting.
EDIT: The description above only shows how to trace the main vertices of the hull. If you want to have a full rectilinear polygon (with line segments between consecutive points), then you have to add an additional point to your chain each time you find next point. For example, when building the right-up chain, if you find a point (x2, y2) from the current point (x1, y1), you have to add (x2, y1) and (x2, y2) to the current chain list (in this order).
回答3:
I don't know of any standard algorithm for this but it doesn't seem too complicated to define:
Assuming each point in the grid has at least 2 neighbors (or else there's no solution)
- p = a point with only two neighbors.
while p isn't null
2a. Mark p as visited
2b. next = the unmarked neighbor that has the least amount of neighbors
2c. next.parent = p
2d. p = next
done
来源:https://stackoverflow.com/questions/32496421/orthogonal-hull-algorithm