Я изменил последний ответ на этот вопрос.
Определите новый класс для Point
:
class Point {
private long x, y;
Point(long x, long y) {
this.x = x;
this.y = y;
}
Point() {
x = 0;
y = 0;
}
public long getX() {
return x;
}
public long getY() {
return y;
}
}
Определить новую функцию для вычисления перекрестного произведения двух векторов:
public long cross(long x1, long y1, long x2, long y2) {
return x1 * y2 - x2 * y1;
}
Предположим, что initial
- это Point
с самой низкой координатой Y. Также предположим, что List<Point> points
- это список со всеми остальными доступными точками, но он НЕ содержит точку initial
.
Для сортировки списка мы можем использовать Collections.sort
с компаратором:
Collections.sort(points, (a, b) -> {
long cr = cross(a.getX() - initial.getX(), a.getY() - initial.getY(), b.getX() - initial.getX(), b.getY() - initial.getY());
if (cr > 0)
return 1;
else
return -1;
});
В этом решении мы использовали перекрестное произведение, чтобы проверить, расположены ли два вектора по часовой или против часовой стрелки.
Это решение имеет два преимущества:
- Более ценно, когда наши координаты являются целыми числами. Когда мы вычисляем углы в других решениях, мы можем иметь некоторые ошибки в вычислениях с плавающей запятой.
- В других решениях мы можем иметь «деление на ноль», но у нас нет этой проблемы здесь.