Как я могу определить, находится ли точка рядом с определенной линией? - PullRequest
6 голосов
/ 26 мая 2009

Я спрашивал " Как я могу узнать, принадлежит ли точка определенной линии? " раньше, и я нашел подходящий ответ, так что большое спасибо.

Теперь я хотел бы знать, как определить, находится ли определенная точка рядом с моей линией.

Ответы [ 7 ]

26 голосов
/ 26 мая 2009

Вам необходимо рассчитать расстояние под прямым углом до линии. Затем вы должны определить, что такое «близко», и проверить, находится ли оно в пределах этого расстояния.

Уравнение, которое вы хотите:

d=|v^^·r|=(|(x_2-x_1)(y_1-y_0)-(x_1-x_0)(y_2-y_1)|)/(sqrt((x_2-x_1)^2+(y_2-y_1)^2)).

2 голосов
/ 24 марта 2014

@ Alan Jackson ответ почти идеален - но его первый (и наиболее одобренный) комментарий предполагает, что конечные точки обрабатываются неправильно. Чтобы убедиться, что точка находится на сегменте, просто создайте прямоугольник, где сегмент является диагональю, а затем проверьте, содержится ли точка внутри. Вот псевдокод :

Заданная линия ab, состоящая из точек a и b и рассматриваемой точки p:

int buffer = 25;//this is the distance that you would still consider the point nearby
Point topLeft = new Point(minimum(a.x, b.x), minimum(a.y, b.y));
Point bottomRight = new Point(maximum(a.x, b.x), maximum(a.y, b.y));
Rect box = new Rect(topLeft.x - buffer, topLeft.y - buffer, bottomRight.x + buffer, bottomRight.y + buffer);
if (box.contains(p))
{
    //now run the test provided by Alan
    if (test)
        return true;
}
return false;
0 голосов
/ 18 ноября 2017

Вот функция Python, которая делает свое дело. Он должен работать в 2 или 3 измерениях (или более) и обрабатывать вертикальные и горизонтальные линии без особых случаев. Если для clipToSegment установлено значение true, возвращаемая точка обрезается до конца, если спроецированная линия выходит за пределы предоставленного отрезка.

def nearestPointOnLine(pt, r0, r1, clipToSegment = True):
    r01 = r1 - r0           # vector from r0 to r1 
    d = np.linalg.norm(r01) # length of r01
    r01u = r01 / d          # unit vector from r0 to r1
    r = pt - r0             # vector from r0 to pt
    rid = np.dot(r, r01u)   # projection (length) of r onto r01u
    ri = r01u * rid         # projection vector
    lpt = r0 + ri           # point on line

    if clipToSegment:       # if projection is not on line segment
        if rid > d:         # clip to endpoints if clipToSegment set
            return r1
        if rid < 0:
            return r0 

    return lpt

Использование: (расстояние точки [4,5] от отрезка от [2,4] до [4,6])

r0 = np.array([2,4])
r1 = np.array([4,6])
rpt = np.array([4,5])
pt = nearestPointOnLine(rpt, r0, r1, True)

dist = np.linalg.norm(rpt-pt)
print('dist', dist)
0 голосов
/ 21 июня 2015

Рассчитайте точку на вашей линии, ближайшую к этой точке.

Предполагая, что отрезок прямой - это a и b, а точка - p.

float vAPx = p.x - a.x;
float vAPy = p.y - a.y;
float vABx = b.x - a.x;
float vABy = b.y - a.y;
float sqDistanceAB = a.distanceSq(b);
float ABAPproduct = vABx*vAPx + vABy*vAPy;
float amount = ABAPproduct / sqDistanceAB;
if (amount > 1) amount = 1;
if (amount < 0) amount = 0;

Что дает вам «количество», как далеко через отрезок линии вы находитесь между A и B (правильно ограничены).

    float nx = (amount * (b.x - a.x)) + a.x;
    float ny = (amount * (b.y - a.y)) + a.y;

Дает вам очко (nx, ny).

if (p.distance(nx,ny) > threshold) reject;

Это будет правильно работать после конца отрезка, так как «количество» будет находиться в диапазоне от 0 до 1.

Если вам не нужен ограниченный отрезок, избавьтесь от границ суммы. Остальная часть кода будет по-прежнему работать, вычисляя позиции за и до A и за B.

Был еще один вопрос, который утверждал, что этот вопрос был дубликатом, но он требует другого, поэтому мое решение решает положение точки, а затем просто решает евклидово расстояние (которое фактически решает оба вопроса).

a.distanceSq (b) также можно сделать как vABx vABx + vABy vABy, поскольку мы уже сделали это.

0 голосов
/ 26 мая 2009

Как близко рядом?

Некоторая геометрия даст вам нужный ответ, вам просто нужно знать о следующих шагах.

Предполагая, что ваш лайк имеет форму y = mx + b, кратчайшим расстоянием до вашей точки будет линия, перпендикулярная вашей стартовой линии (m1 = -1 / m), пересекающая вашу точку.

Отсюда вы вычисляете расстояние между точкой пересечения и рассматриваемой точкой.

0 голосов
/ 26 мая 2009

По сути, вы хотите найти обычную линию, то есть линию, перпендикулярную вашей линии, которая пересекает вашу точку и линию, а затем вычислить расстояние вдоль этой линии.

0 голосов
/ 26 мая 2009

Google - ваш друг: Расстояние между точками и линиями (двухмерное) . Вы можете просто использовать уравнение внизу, и вы идете.

...