Как вычислить положение точки относительно выпуклого четырехугольника Java?
Нужен код, который позволит рассчитать положение точки относительно выпуклого четырехугольника в двумерном пространстве именно на Java. Может кто подскажет с чего хотя бы начать, а то совсем что то идей никаких.
Ответы (1 шт):
Так как многоугольник выпуклый, достаточно проверить, что точка лежит в каждом из углов многоугольника. То есть пусть у вас N вершин, тогда вы должны пройти по каждой из них и проверить, что точка X лежит в угле A[i - 1]_A[i]_A[i + 1], где A - массив координат вершин вашего многоугольника по порядку.
Чтобы проверить, что точка лежит в угле, можно использовать псевдоскалярное произведение векторов. Псевдоскалярное (косое) произведение векторов A и B - это число, равное |A| * |B| * sin(alpha), где alpha - угол вращения против часовой стрелки от A до B. То есть для нахождения alpha вы можете построить данные вам вектора от одной точки и найти ориентированный(!) угол от A до B.
Также это прекрасное произведение очень просто вычисляется и без всяких измерений углов с помощью одних лишь координат: A ^ B = Ax * By - Bx * Ay. Получается, теперь, зная координаты, мы можем узнать и кое-какие сведения об угле, а именно - точное значение его синуса.
В прочем, в нашем случае точное значение нам не пригодится, а важен будет лишь знак. Заметим, что:
sin(x) > 0=>0 < x < 180(градусов).sin(x) = 0=>x = 0илиx = 180.sin(x) < 0=>180 < x < 360.
При этом псевдоскалярное произведение по знаку полностью совпадает со знаком синуса, а значит, что:
A ^ B > 0=> B левее A.A ^ B = 0=> B коллинеарен с A.A ^ B < 0=> B правее A.
На этом вся польза от псевдоскалярного произведения на данный момент кончается, и мы можем перейти к самой задаче.
Примерный код алгоритма выглядит так:
double vectorMultiple(Vector a, Vector b)
return a.x * b.y - b.x * a.y;
bool pointInAngle(Vector a, Vector b, Vector p)
if (vectorMultiple(a, b) < 0)
return (vectorMultiple(a, p) < 0) && (vectorMultiple(p, b) < 0);
return (vectorMultiple(b, p) < 0) && (vectorMultiple(p, a) < 0);
bool pointInAngle(Point a, Point b, Point c, Point p) // Point P in angle ABC
Vector ba = Vector(b, a); // Vector AB = {B.x - A.x, B.y - A.y}
Vector bc = Vector(b, c);
Vector bp = Vector(b, p);
return pointInAngle(ba, bc, bp);
bool pointInPolygon(Point[] poly, Point p)
for (int i = 0; i < poly.length; i++)
if (!pointInAngle(p, poly[i], poly[(i + 1) % poly.length], poly[(i + 2) % poly.length])
return false;
return true;
Также стоит отметить, что существует более быстрый алгоритм, работающий за O(logN), прочитать о котором можно, например, тут: https://neerc.ifmo.ru/wiki/index.php?title=принадлежность_точки_выпуклому_и_невыпуклому_многоугольникам
Однако, учитывая, что вам требуется решения только для четырехугольника, то используя данный алгоритм вы скорее всего даже потеряете в производительности, так что использовать его смысла нет.
