Существует ли такой алгоритм сортировки массива 2D точек по часовой стрелке?
Я конкретно имею дело с прямоугольным треугольником в моем случае, поэтому только 3 балла.
Однако мне интересно знать, существует ли такой алгоритм, если нет, то каков простой способ вернуть 3 точки моего треугольника по часовой стрелке?
Редактировать: я пытаюсь вычислить точки по часовой стрелке относительно центра тяжести многоугольника, который является выпуклым.
Обновление: это реализация, которую я в конечном итоге использовал, основываясь на выбранном ответе, она не критична для производительности и происходит только время от времени, поэтому она работает.
ArrayList<PVector> pointList = new ArrayList<PVector>();
pointList.add(A);
pointList.add(B);
pointList.add(C);
Collections.sort( pointList, new TriangleVectorComparator(origin) );
return pointList;
// Comparator
package triangleeditor;
import java.util.Comparator;
import processing.core.PVector;
public class TriangleVectorComparator implements Comparator<PVector> {
private PVector M;
public TriangleVectorComparator(PVector origin) {
M = origin;
}
public int compare(PVector o1, PVector o2) {
double angle1 = Math.atan2(o1.y - M.y, o1.x - M.x);
double angle2 = Math.atan2(o2.y - M.y, o2.x - M.x);
//For counter-clockwise, just reverse the signs of the return values
if(angle1 < angle2) return 1;
else if (angle2 < angle1) return -1;
return 0;
}
}
2d
mathematics
algorithm
onedayitwillmake
источник
источник
Ответы:
Ваш вопрос недостаточно точен. Массив точек находится только «по часовой стрелке» или «против часовой стрелки» относительно контрольной точки. В противном случае любой массив из трех точек всегда может быть либо CW, либо CCW. Смотрите следующую картинку: слева точки расположены по часовой стрелке; справа точно такие же точки расположены против часовой стрелки.
В вашем случае, я считаю, что использование барицентра точек в качестве ориентира целесообразно.
Хорошим методом для неизвестного количества точек может быть следующий:
P[0], P[1], ... P[n-1]
быть список точек для сортировкиa[0], a[1], ... a[n-1]
, чтобыa[i] = atan2(P[i].y - M.y, P[i].x - M.x);
a
значения, используя,qsort
например.Однако вы можете быть уверены, что хороший алгоритм сортировки будет работать плохо с тремя входными значениями по сравнению со специальным методом. Использование
atan2
все еще действует, но просто не используйтеqsort
.источник
qsort
здесь крошечный по сравнению сatan2
.Я считаю, что то, о чем вы на самом деле спрашиваете здесь, это порядок наматывания треугольника, который на самом деле довольно просто проверить.
Поскольку в вашем треугольнике есть только три точки, ваш треугольник уже находится в порядке по часовой стрелке или против часовой стрелки, и поэтому все, что вам нужно сделать, это проверить, какой из этих двух он является, и изменить порядок индексов при намотке. не тот, который вы хотите.
Вот общая идея, предполагая, что три вершины треугольника - это a , b и c , и что у вас есть простая операция вычитания вектора:
Обратите внимание, что в зависимости от того, каким образом вы ориентировали ось + y (вверх или вниз), случаи «по часовой стрелке» и «против часовой стрелки» могут быть изменены на противоположные тому, как я их пометил в комментариях в этом примере кода.
источник
Можете ли вы дать больше информации? Вам нужен порядок точек CCW, но какой пункт должен быть центром порядка?
Если у вас есть только треугольник (3 точки) на плоскости, вы можете вычислить определитель из матрицы, где линии - это координаты точек (3-я координата равна 1). Если определитель> 0, точки расположены в порядке CCW. Если нет, вы можете использовать, например, последние два пункта, и вы получите заказ CCW.
Если у вас есть точки A, B, C, то ваша матрица выглядит так:
Определитель: xA * yB + xB * yC + xC * yA - yB * xC - yC * xA - yA * xB. Тогда вы можете сравнить это с нуля. Если это> 0, вернуть точки A, B, C, если нет, вернуть A, C, B.
Если у вас есть набор точек и вы знаете, что они образуют выпуклый многоугольник (все являются частью выпуклой оболочки) и хотите получить их порядок, вы можете использовать сканирование Грэма или марш Джарвиса (это алгоритмы для поиска выпуклой оболочки из многих точек, но здесь тоже должно работать :))
источник