У меня есть набор очков. Я хочу разделить их на 2 отдельных набора. Для этого я выбираю две точки ( a и b ) и провожу между ними воображаемую линию. Теперь я хочу, чтобы все точки, которые остались от этой линии, были в одном наборе, а те, которые находятся справа от этой линии, в другом наборе.
Как я могу определить для любой данной точки z , находится ли она в левом или правом наборе? Я попытался вычислить угол между азб - углы меньше 180 - с правой стороны, больше 180 - с левой стороны - но из-за определения ArcCos вычисленные углы всегда меньше 180 °. Есть ли формула для вычисления углов больше 180 ° (или любая другая формула для выбора правой или левой стороны)?
c#
math
geometry
convex-hull
Aaginor
источник
источник
Ответы:
Используйте знак определителя векторов
(AB,AM)
, гдеM(X,Y)
- точка запроса:Он находится
0
на линии, и+1
с одной стороны, и-1
с другой стороны.источник
positions
?Попробуйте этот код, в котором используется кросс-продукт :
Где а = точка линии 1; b = точка 2 на линии; c = точка для проверки.
Если формула равна 0, точки коллинеарны.
Если линия горизонтальна, то возвращается истина, если точка находится над линией.
источник
return (b.x - a.x)*(c.y - a.y) > (b.y - a.y)*(c.x - a.x);
, но компилятор, вероятно, все равно оптимизирует это.Вы смотрите на знак определителя
Он будет положительным для точек с одной стороны и отрицательным с другой (и нулевым для точек на самой линии).
источник
Вектор
(y1 - y2, x2 - x1)
перпендикулярен линии и всегда указывает вправо (или всегда указывает влево, если ориентация вашей плоскости отличается от моей).Затем вы можете вычислить скалярное произведение этого вектора и
(x3 - x1, y3 - y1)
определить, находится ли точка на той же стороне линии, что и перпендикулярный вектор (скалярный продукт>0
) или нет.источник
Используя уравнение для линии ab , получите координату x на линии с той же координатой y, что и точка, которую нужно отсортировать.
источник
Сначала проверьте, есть ли у вас вертикальная линия:
Затем рассчитайте уклон:
m = (y2-y1)/(x2-x1)
Затем создайте уравнение линии , используя точку формы откоса:
y - y1 = m*(x-x1) + y1
. Ради моего объяснения упростите его до формы перехвата наклона (не обязательно в вашем алгоритме):y = mx+b
.Теперь подключите
(x3, y3)
кx
иy
. Вот псевдокод с подробным описанием того, что должно произойти:источник
Я реализовал это на java и запустил модульный тест (источник ниже). Ни одно из вышеперечисленных решений не работает. Этот код проходит модульный тест. Если кто-то обнаружит, что модульный тест не прошел, дайте мне знать.
Код: ПРИМЕЧАНИЕ:
nearlyEqual(double,double)
возвращает истину, если два числа очень близки.Вот модульный тест:
источник
Предполагая, что точки равны (Ax, Ay) (Bx, By) и (Cx, Cy), вам необходимо вычислить:
(Bx - Ax) * (Cy - Ay) - (By - Ay) * (Cx - Ax)
Это будет равно нулю, если точка C находится на линии, образованной точками A и B, и будет иметь другой знак в зависимости от стороны. Какая это сторона, зависит от ориентации ваших координат (x, y), но вы можете вставить тестовые значения для A, B и C в эту формулу, чтобы определить, находятся ли отрицательные значения слева или справа.
источник
Я хотел предложить решение, вдохновленное физикой.
Представьте силу, приложенную вдоль линии, и вы измеряете крутящий момент силы вокруг точки. Если крутящий момент положительный (против часовой стрелки), то точка находится «слева» от линии, но если крутящий момент отрицательный, точка находится «справа» от линии.
Итак, если вектор силы равен размаху двух точек, определяющих линию
вы проверяете сторону точки
(px,py)
по знаку следующего тестаисточник
в основном, я думаю, что есть решение, которое намного проще и прямолинейно, для любого данного многоугольника, скажем, состоящего из четырех вершин (p1, p2, p3, p4), найти две крайние противоположные вершины в многоугольнике, в другом словами, найдите, например, самую верхнюю левую вершину (скажем, p1) и противоположную вершину, которая расположена в самом нижнем правом углу (скажем). Следовательно, учитывая вашу контрольную точку C (x, y), теперь вам нужно дважды проверить между C и p1 и C и p4:
если cx> p1x AND cy> p1y ==> означает, что C находится ниже и справа от p1, затем, если cx <p2x AND cy <p2y ==> означает, что C находится сверху и слева от p4
заключение, C находится внутри прямоугольника.
Спасибо :)
источник
@ Ответ AVB на рубине
Если
det
положительно - вверху, если отрицательно - внизу. Если 0, он на линии.источник
Вот версия, снова использующая логику кросс-продукта, написанная на Clojure.
Пример использования:
То есть точка (0, 10) находится слева от линии, определяемой (-3, -1) и (3, 1).
ПРИМЕЧАНИЕ. Эта реализация решает проблему, которой никто из других (пока) не занимается! Порядок имеет значение при выставлении точек, определяющих линию. То есть это в определенном смысле «направленная линия». Таким образом, с приведенным выше кодом этот вызов также дает результат
true
:Это из-за этого фрагмента кода:
Наконец, как и другие решения, основанные на перекрестных произведениях, это решение возвращает логическое значение и не дает третьего результата для коллинеарности. Но это даст результат, который имеет смысл, например:
источник
Альтернативный способ почувствовать решения, предлагаемые сетями, - это немного понять геометрические последствия.
Пусть pqr = [P, Q, R] - точки, образующие плоскость, разделенную на 2 стороны прямой [P, R] . Мы должны выяснить, есть ли две точки на pqr плоскости , A, B, на одной стороне.
Любую точку T на плоскости pqr можно представить двумя векторами: v = PQ и u = RQ, как:
T '= TQ = я * v + j * u
Теперь о геометрии:
i+j: <0 0 <1 =1 >1 ---------Q------[PR]--------- <== this is PQR plane ^ pr line
В основном,
Другие геометрические значения i и j (не связанные с этим решением):
Значение i, j можно получить, решив уравнения:
Итак, нам даны 2 точки A, B на плоскости:
A = a1 * v + a2 * u B = b1 * v + b2 * u
Если A, B находятся на одной стороне, это будет верно:
sign(a1+a2-1) = sign(b1+b2-1)
Обратите внимание, что это также относится к вопросу: находятся ли точки A, B с одной стороны от плоскости [P, Q, R]. , в которой:
Т = я * P + j * Q + k * R
и i + j + k = 1 означает, что T находится на плоскости [P, Q, R], а знак i + j + k-1 подразумевает его сторону. Отсюда получаем:
A = a1 * P + a2 * Q + a3 * R B = b1 * P + b2 * Q + b3 * R
и A, B находятся по одну сторону от плоскости [P, Q, R], если
sign(a1+a2+a3-1) = sign(b1+b2+b3-1)
источник