Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sort Four Points in Clockwise Order

Four 2D points in an array. I need to sort them in clockwise order. I think it can be done with just one swap operation but I have not been able to put this down formally.

Edit: The four points are a convex polygon in my case.

Edit: The four points are the vertices of a convex polygon. They need not be in order.

like image 446
Agnel Kurian Avatar asked Oct 28 '08 06:10

Agnel Kurian


People also ask

How do I sort clockwise points in Matlab?

[x2, y2] = poly2cw(x1, y1) arranges the Cartesian vertices in the polygonal contour ( x1 , y1 ) in clockwise order, returning the result in x2 and y2 . If x1 and y1 can contain multiple contours, represented either as NaN -separated vectors or as cell arrays, then each contour is converted to clockwise ordering.

How do you sort vertices of a polygon in counter clockwise order?

It should choose the vertex which counter clockwise index inside the polygon is higher. The first index should be the bottom left vertex. I this example it should choose →u. For the first quadrant I can say that →u>→v if |→u|>|→v| and ∀→u>∀→v.

How do you determine if a list of polygon points are in clockwise order?

Here's a simple one that will work with non-convex polygons (it'll even work with a self-intersecting polygon like a figure-eight, telling you whether it's mostly clockwise). Sum over the edges, (x2 − x1)(y2 + y1). If the result is positive the curve is clockwise, if it's negative the curve is counter-clockwise.

How do you sort coordinates of a polygon?

By choosing an arbitrary (x, y) pair as your "center", you can compute the polar angle of each point relative to your center, and then sort them based on this angle. The end result sorts the polygon's point in clockwise/counterclockwise direction.


2 Answers

If you want to take a more mathematical perspective, we can consider the permutations of 4 points

In our case there are 4 permutations that are in clockwise order

A B C D B C D A C D A B D A B C 

All other possible permutations can be converted to one of these forms with 0 or 1 swaps. (I will only consider permutations starting with A, as it is symmetrical)

  1. A B C D - done
  2. A B D C - swap C and D
  3. A C B D - swap B and C
  4. A C D B - swap A and B
  5. A D B C - swap A and D
  6. A D C B - swap B and D

Thus only one swap is ever needed - but it may take some work to identify which.

By looking at the first three points, and checking the sign of the signed area of ABC, we can determine whether they are clockwise or not. If they are clockwise then we are in case 1 2 or 5

to distinguish between these cases we have to check two more triangles - if ACD is clockwise then we can narrow this down to case 1, otherwise we must be in case 2 or 5.

To pick between cases 2 and 5, we can test ABD

We can check for the case of ABC anti-clockwise similarly.

In the worst case we have to test 3 triangles.

If your points are not convex, you would find the inside point, sort the rest and then add it in any edge. Note that if the quad is convex then 4 points no longer uniquely determine the quad, there are 3 equally valid quads.

like image 77
Oliver Hallam Avatar answered Sep 20 '22 12:09

Oliver Hallam


A couple of thoughts worth considering here;

  • Clockwise is only meaningful with respect to an origin. I would tend to think of the origin as the centre of gravity of a set of points. e.g. Clockwise relative to a point at the mean position of the four points, rather than the possibly very distant origin.

  • If you have four points, a,b,c,d, there exists multiple clockwise orderings of those points around your origin. For example, if (a,b,c,d) formed a clockwise ordering, so would (b,c,d,a), (c,d,a,b) and (d,a,b,c)

  • Do your four points already form a polygon? If so, it is a matter of checking and reversing the winding rather than sorting the points, e.g. a,b,c,d becomes d,c,b,a. If not, I would sort based on the join bearing between each point and the origin, as per Wedges response.

Edit: regarding your comments on which points to swap;

In the case of a triangle (a,b,c), we can say that it is clockwise if the third point c, is on the right hand side of the line ab. I use the following side function to determine this based on the point's coordinates;

int side(double x1,double y1,double x2,double y2,double px,double py) {  double dx1,dx2,dy1,dy2;  double o;   dx1 = x2 - x1;  dy1 = y2 - y1;  dx2 = px - x1;  dy2 = py - y1;  o = (dx1*dy2)-(dy1*dx2);  if (o > 0.0) return(LEFT_SIDE);  if (o < 0.0) return(RIGHT_SIDE);  return(COLINEAR); } 

If I have a four point convex polygon, (a,b,c,d), I can consider this as two triangles, (a,b,c) and (c,d,a). If (a,b,c) is counter clockwise, I change the winding (a,b,c,d) to (a,d,c,b) to change the winding of the polygon as a whole to clockwise.

I strongly suggest drawing this with a few sample points, to see what I'm talking about. Note you have a lot of exceptional cases to deal with, such as concave polygons, colinear points, coincident points, etc...

like image 34
SmacL Avatar answered Sep 20 '22 12:09

SmacL