Answer the question
In order to leave comments, you need to log in
Sorting points counterclockwise?
I have a class that implements the IComparer interface , I also have an array that contains elements of the Point data type I created . The Point class contains two fields: the abscissa and the ordinate. My task is to sort the points in this array in ascending counterclockwise order starting from the point (1, 0). What I did: I determined the degree measure of the points using the Math.Atan2() function , then using the CompareTo() function I compared the points in the array, but the problem is that when I ran the debugger through the program, I found that Atan2()defines the degree measure of a point clockwise, that is, a point with coordinates (1, 0) is defined as 180 degrees, and a point with coordinates (-1, 0) as 0 degrees, although it should be the other way around.
How the array should be sorted: (1, 0) (0.01, 1) (0, 1) (-1, 0) (0, -1)
Code:
public class Point
{
public double X;
public double Y;
}
public class ClockwiseComparer : IComparer<Point>
{
public int Compare(Point point, Point point_2)
{
double angle1 = Math.Atan2(point.Y, point.X) * (180 / Math.PI);
double angle2 = Math.Atan2(point_2.Y, point_2.X) * (180 / Math.PI);
return angle1.CompareTo(angle2);
}
}
public static void Main()
{
var array = new[]
{
new Point { X = 1, Y = 0 },
new Point { X = -1, Y = 0 },
new Point { X = 0, Y = 1 },
new Point { X = 0, Y = -1 },
new Point { X = 0.01, Y = 1 }
};
Array.Sort(array, new ClockwiseComparer());
foreach (Point e in array)
Console.WriteLine("{0} {1}", e.X, e.Y);
}
Answer the question
In order to leave comments, you need to log in
You messed up something, Atan makes counterclockwise corners.
That's just the angle goes from -pi to pi, not from 0 to 2pi. If you want the first point to be {1, 0}, then you need to add 2pi to the negative angles before comparing.
This will work, but not very optimal. Atan is a slow thing. You can compare the signs of the coordinates first.
If one point has a positive y and the other has a negative one, the positive one comes first. If one of the points has y=0 or the signs are the same - compare signs by x. Above and below the OX axis - comparisons should give different conclusions (above the OX axis, positive x comes before negative ones, below the OX axis - vice versa).
Or for each point, depending on the two signs of the coordinates, you need to assign a quadrant from 1 to 4. And first sort by them.
If the points lie in the same quadrant (the signs are the same), then you can compare them using the cross product of vectors . Substitute the coordinates of two points there and, if the value is positive, then the first point lies before the second. Zero value means they are on the same corner. If negative, the first point lies later than the second.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question