0
votes

I have the vertices of a non-self-intersecting polygon in 2-D where the x-coordinate is centred longitude and y-coordinate is centred latitude. I want to find the edges of the polygon.

I can plot the vertices and see which vertices are neighbouring and see the edges. But my question is how can I get these edges.

For example, I am considering the sample data:

> data1
    vertices       lon      lat
       5         1.133179 1.027886
       4         1.094459 1.013952
       2         1.055672 1.000000
       1         1.000000 1.028578
       3         1.038712 1.042541
       6         1.116241 1.070438

Sample Plot of the points is

enter image description here

I want to have an array like this

>edges 
      ind1 ind2
[1,]    5    6
[2,]    1    3
[3,]    3    6
[4,]    1    2
[5,]    2    4
[6,]    4    5

I am interested about this kind of shape of the polygon (with minimum area) enter image description here

I got this array by using a function ashape of the R-package alphahull. But in this function Euclidean distance is used to find distance between points, which not applicable in my case (since I am considering data on (lon, lat), we can use distHaversine distance function in the package geosphere). And this function giving unsatisfactory result in case if the polygon has large number vertices and have complex shape. This polygon may or may not be convex.

Now all I want is to build an algorithm to find the edges of the non-intersecting polygon with minimum area.

Any help in this direction will be gratefully appreciated.

2
Won't the edges be the same for unprojected coordinates?jbaums
Even if they are same using 'ashape' function for finding the edges is not giving the satisfactory result for large data set.Janak
@janak by large you mean size or point count or point density? polygon is convex or concave? if concave what is the constraint or rule for shape (with more points there is higher number of possible polygons so you need to specify some conditions to select the right one)?Spektre
@Spektre Here by large I meant the polygon has large number vertices. This polygon may or may not be convex. I edited my question.Janak
@janak I finnished the answer editSpektre

2 Answers

1
votes

Algorithm for finding all possible polygons:

  • generate the convex hull . Note that any non intersecting polygon must traverse its convex hull in order.
  • Start with any point on the convex hull Generate a list of paths from that point to each interior point, and to the next adjacent point on the convex hull
  • recursively extend each path to each remaining interior point as well as to that first free point on the convex hull
  • for each segment added to a path reject the path if it self intersects

I'm not going to post the code, but here are all 67 possible polygons for a random set of 8 points. As one can imagine the set of results blows up quickly with the number of points (eg. n=12 -> ~10000 polygons.. )

enter image description here

here are the polygons with min and max perimeters.

enter image description here

0
votes
  1. convert points from lon,lat to Cartesian x,y or x,y,z

    • use spherical or ellipsoidal surface
    • if the size is small enough you can project (x,y,z) to local surface plane to avoid 3D computing
    • you can also use lon,lat as x,y but make sure there is no zero crossing (if is then offset that axis by some value until it isn't)
  2. now there are many possible strategies

    • you did not provide any rule for the shape
    • so I assume 'minimal' perimeter/size/area and generic concave polygon
    • you can not go directly to edge lines before you know where is inside and where is outside
    • I would do this task like this: find polygon based on find holes in 2D point set
  3. modification 1

    • as you already have all the edge points (at least that is my impression)
    • so you can make flag for each point from the above algorithm
    • that will tell you where is inside or outside of polygon
    • for example take 8 directions (N,NE,E,...) and encode which way is filled and which empty
    • then on each edge start in the middle of empty direction
    • and find 2 closest lines to it (in angular terms) that are not intersecting any previous line
    • and if more available use the smallest ones
    • direction flag
    • gray means inside polygon
    • make list of all such possible lines (2 per point)
    • then search for connected loops
    • beware this modification is not 100% error prone (I do not think that is for concave polygon even possible)
  4. modification 2

    • use complete polygon from bullet 2
    • and try to match its edge points to your input edge points
    • then use the edge lines as in original polygon but with your new points
    • if some points are skipped then find closest edge line to it and divide it by this point
    • this should be more safe and accurate then bullet 3.

simple approach

  • if the above is too much for you then

    1. create list of all possible lines
    2. sort them by size ascending
    3. remove all 'long' lines that are intersecting any 'short' line
      • what is short or long depends on you
      • for example first third of lines can be the short ones and the last third the long ones
      • or make average size and what is < 0.6*avg_size or > 1.2*avg_size ...
      • or if you have N points then first 2N lines are short the rest is long (2 lines per point)
      • test all and select the best option for you ...
    4. try to find joined lines
      • find only lines that are connected once (no more then 2 lines per point)
      • remove them from list into the final solution list
      • after this you will have list of possible lines and list of found lines
    5. remove all lines from possible lines that intersect any line in found lines
      • this should remove any non relevant lines
    6. try to find connections again
      • take first possible line if found connection move it to the solution list
      • and go to bullet 5.
      • if none found continue with next line ...
      • stop if none line left or none connection found.