2009-05-26 12 views

Odpowiedz

25

Trzeba calculate the right angle distance do linii. Następnie musisz określić, czym jest "blisko" i sprawdzić, czy znajduje się on w tej odległości.

Równanie chcesz to:

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)).

+9

Uwaga: Jeśli mamy do czynienia z odcinków (czyli nieskończenie długich linii), może to dawać błędne wyniki: Punkt może być daleki od punktów końcowych segmentu, a mimo to mieć niewielką normalną odległość ... – MartinStettner

+0

Należy również pamiętać, że jeśli zamierzasz odwrócić i porównać d do D, bardziej efektywne będzie porównywanie | (x2 - x1) x (x1 - x0) |^2 do D^2 | x2 - x1 |^2, oszczędzając dwa pierwiastki kwadratowe i podział na koszt mnożenia . – Dave

+0

Dziękuję Mr.Alan Ale link nie działa !. Próbowałem równania, które podałeś wcześniej, ale to daje mi odległość między nowym punktem a pierwszym punktem linii, a nie linii otworów. Przepraszam za mój wulgaryzm. Sincerly, Wahid –

0

Zasadniczo to, co chcesz zrobić, to znaleźć normalną linię - czyli linię prostopadłą do linii - która przecina twój punkt i linię, a następnie obliczyć odległość wzdłuż tej linii.

+0

Tak, Sir, ale jestem bardzo słaby w matematyce, więc proszę pomóż mi i daj mi równanie. –

+1

Zobacz w pierwszej. Wszystko tam jest. –

0

Jak blisko jest blisko?

Niektóre geometria daje odpowiedź trzeba, po prostu trzeba zdawać sobie sprawę z następujących etapów.

Przyjmując, że podobne jest w postaci y = mx + b, najkrótszą odległością od punktu będzie linia prostopadła do linii początkowej (m1 = -1/m), przecinająca dany punkt.

Stamtąd można obliczyć odległość między punktem przecięcia a punktem, o którym mowa.

+0

lekka ważna korekta Ian, nachylenie linii 2 to ujemna odwrotność linii nachylenia 1 (m1 = -1/m) - –

+0

Mój błąd ... Nigdy nie dobrze sprawdzam mojej pracy :-) –

2

@Alan Jackson „s odpowiedź jest prawie idealny - ale jego pierwszą (i najbardziej up-głosowanie) komentarz sugeruje, że punkty końcowe nie są prawidłowo obsługiwane. Aby upewnić się, że punkt znajduje się w segmencie, po prostu utwórz pole, w którym segment jest przekątny, a następnie sprawdź, czy punkt jest zawarty w tym segmencie. Oto pseudo-kod:

danej linii AB, składa się z punktów A i B, a punkt P, w pytaniu:

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

Dziękuję za Ciebie :) –

0

obliczyć punkt na linii, która jest najbliżej tego punktu .

Zakładając, że segment linii to aib, a punktem jest 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; 

Który daje "kwotę", jak daleko w segmencie linii jesteś między A i B (odpowiednio ograniczone).

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

Daje punkt (nx, ny).

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

ten będzie działał poprawnie poza koniec odcinka linii, ponieważ utrzymuje „ilość” pomiędzy 0 a 1.

Jeśli nie chcesz to odcinek ograniczonym pozbyć granicach za kwotę. Reszta kodu nadal będzie działać, obliczając pozycje poza i przed A i poza B.

Było jeszcze jedno pytanie, które twierdziło, że to pytanie było duplikatem, ale prosi o coś innego, dlatego moje rozwiązanie rozwiązuje pozycję punktu, a następnie rozwiązuje dystans euklidesowy (który faktycznie rozwiązuje oba pytania).

a.distanceSq (b) może być również wykonane jako vABx vABx + vABy vABy, ponieważ już to zrobiliśmy.

0

Oto funkcja Pythona, która rozwiązuje problem. Powinien działać w 2 lub 3 wymiarach (lub więcej) i obsługuje pionowe i poziome linie bez specjalnych przypadków. Jeśli ustawisz clipToSegment na true, zwrócony punkt zostanie przycięty do końców, jeśli rzutowana linia wykracza poza podany segment linii.

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 

Zastosowanie: (odległość od punktu [4,5] z odcinkiem linii z [2,4] do [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) 
Powiązane problemy