Задать вопрос
@artgor261
Студент РТУ МИРЭА

Сортировка точек против часовой стрелки?

У меня есть класс который реализует интерфейс IComparer, так же у меня есть массив который содержит в себе элементы созданного мною типа данных Point. Класс Point содержит два поля: абсциссу и ординату. Моя задача отсортировать точки в этом массиве по возрастанию против часовой стрелки начиная с точки (1, 0). Что я сделал: я определил градусную меру точек с помощью функции Math.Atan2(), затем с помощью функции CompareTo() я сравнил точки в массиве, но проблема в том что когда я прошел дебаггером по программе я обнаружил что Atan2() определяет градусную меру точки по часовой стрелке, то есть точка с координатами (1, 0) определяет как 180 градусов, а точка с координатами (-1, 0) как 0 градусов, хотя должно быть все наоборот.

Как должен быть отсортирован массив: (1, 0) (0.01, 1) (0, 1) (-1, 0) (0, -1)

Код:

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);
        }
  • Вопрос задан
  • 695 просмотров
Подписаться 1 Простой 1 комментарий
Пригласить эксперта
Ответы на вопрос 1
wataru
@wataru Куратор тега Математика
Разработчик на С++, экс-олимпиадник.
Вы что-то напутали, Atan вадает углы против часовой стрелки.

Вот только угол идет от -pi до pi, а не от 0 до 2pi. Если вы хотите, чтобы первая точка была {1, 0}, то надо к отрицательным углам прибавлять 2pi перед сравнением.

Это будет работать, но не очень оптимально. Atan - медленная штука. Можно сравнивать знаки координат сначала.

Если одна точка с положительным y, а другая с отрицательным - положительная идет раньше. Если одна из точек имеет y=0 или знаки одинаковые - сравнивайте знаки по x. Выше и ниже оси OX - сравнения должны давать разные выводы (выше оси OX, положительные x идут раньше отрицательных, ниже оси OX - наоборот).

Или для каждой точки в зависимости от двух знаков координат надо назначить квадрант от 1 до 4. И сначала сортировать по ним.

Если же точки лежат в одном квадранте (знаки одинаковые) то можно сравнивать их с помощью векторного произведения векторов. Подстовляете туда координаты двух точек и, если значение положительное, то первая точка лежит раньше второй. Нулевое значение - значит они на одном и том же углу. Если отрицательное - перовая точка лежит позже второй.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы