Abstand Punkt zur Linie



  • Für ein Programm muss ich überprüfen ob ein Klick
    auf einer Linie ist, bzw. auf welcher.
    Weil der User nicht immer daneben klicken soll,
    brauch ich auch einen gewissenspielraum,
    so das mir eine ja/nein Aussage nicht weiterhilft,
    ich brauche schon den Abstand vom Punkt zur Linie
    im rechten Winkel, oder etwas ähnliches, womit sich
    dies Abschätzen lässt.

    Ich nenn jetzt einfach mal die beiden Punkte, die
    die Linie ergeben, A und B. Den Punkt, der geklickt
    wurde, P.
    Folgende Formel verwende ich zur Zeit:
    (P.x - A.x)(B.x-A.x)+(P.y - A.y)(B.y - A.y) /
    sqrt(B.x-A.x) + sqrt(B.y - A.y)

    Sie funktioniert, und liefert brauchbare ergebnisse.
    Ich wollte nun nur wissen, ob man das noch Optimieren
    kann, bzw. es einen besseren Weg gibt.

    phlox

    edit: [wur] funktioniert wohl nicht :p



  • Wir hatten ne ähnliche Aufgabe, bei der einfach nur der Abstand des Punktes zur Geraden berechnet werden sollte. Die meisten incl. mir verwendeten deine Formel.
    Unser Prof. hat dann in seiner Lösung auch diese Formel gebracht.



  • Für ein Programm muss ich überprüfen ob ein Klick
    auf einer Linie ist,

    Wurzel ziehen - bist du wahnsinnig? Skalarprodukt!



  • Vertexwahn schrieb:

    Für ein Programm muss ich überprüfen ob ein Klick
    auf einer Linie ist,

    Wurzel ziehen - bist du wahnsinnig? Skalarprodukt!

    wasn das ?
    Bin Mathe mässig nicht so gebildet 😉



  • Du hast 2 Vektoren a(xa,ya,za) und b(xb,yb,zb). Das Skalarprodukt von a*b (* ist hier mein Skalar) ist dann die Summe von ai*bi von i=1 bis n.

    Sorry, bin in LaTex nicht so gebildet. :p 😃



  • Griffin schrieb:

    Du hast 2 Vektoren a(xa,ya,za) und b(xb,yb,zb). Das Skalarprodukt von a*b (* ist hier mein Skalar) ist dann die Summe von ai*bi von i=1 bis n.

    Sorry, bin in LaTex nicht so gebildet. :p 😃

    versteh ich noch weniger *g*

    Bisher ist die Lösung von mir recht schnell,
    und nun läuft nun sogar auf meinem Koordinatensystem
    richtig.

    phlox







  • hm die magntude funktion hat aber ne wurzel.
    ich geh mal davon aus, dass sich ne Line seltener ändert, als das man den Abstand testen mag. und da ist nen Test mit 2xmmulti und 1xplus schon schneller



  • Ja, wenn der Benutzer mal mehrere tausend mit hunderttausend Klicks pro Sekunde absetzt ist das bestimmt spürbar!



  • Dummerweise benutz ich den GCC, so das ich die MSDLL nicht nutzen kann.
    Meine Formel oben ist auch leicht falsch, wie ich jetzt herausgefunden habe,
    aber die eigentlich richtige liefert immer noch ein Falsches ergebnis :
    (c.x - a.x)(b.x-a.x)+(c.y-a.y)(b.y-a.y)/sqrt((b.x -a.x)²+(b.y-a.y)²).

    Es testet i.d.R. eine ganz andere Gerade.
    Welche aber wieder in einer Beziehung
    zu der eigentlichen steht.

    phlox



  • Bin jetzt weiter gekommen.
    Das Problem liegt an meinen Koordinaten, diese sind teilweise
    verschoben, bzw. deren Position, wenn ich nun die korrekten
    koordinaten ermittel, klapp es, bis auf einen Sonderfall.

    In meinem Steuerelment sind Kreise gleichmässig an einem
    Kreis aufgereit. z.Z. sind es 8 Kreise, immer wenn die
    Linie 2 Gegenüberliegende Kreise verbindet, wird statt
    der distanz zu Linie, die distanz zur Tangenten des Kreises
    am Ausgangspunkt ermittelt...

    ... welches dann direkt auch einen Lösungsansatz bietet.
    Man konstruiert einfach ein 2. Dreieck aus A P und der länge
    zwischen Tangente von A zu P. Damit lassen sich dann b und c,
    ermitteln, welches wiederum es ermöglicht a auszurechnen, welches
    die die Distanz von P zu Geraden A-B ist.

    So siehts dann in code aus:

    int consize = connections.size();
    wxPoint a,b,c,temp;
    bool beqa = false;
    for(int i =1; i < consize;i++)// go through every connection we have.
    {
            a = connectors[connections[i].x];//coordinaten ermitteln
            int Y = connections[i].y-4;//don't ask *g*
            if(Y < 0)
                    Y += numcells;
            b = connectors[Y];
            c.x = click.x;
            c.y = click.y;
            if(b == a)
            {
                    beqa = true;
                    b = connectors[connections[i].y];
            }
            //wxMessageBox(wxString::Format("c.x %i c.y %i a.x %i a.y %i b.x %i b.y %i",c.x,c.y,a.x,a.y,b.x,b.y));
            int p2line = ((c.x-a.x)*(b.x-a.x)+(c.y-a.y)*(b.y-a.y))/sqrt(((b.x-a.x)*(b.x-a.x)+(b.y-a.y)*(b.y-a.y)));
            if(beqa)
            {
                    // calculate the hight of the triangle a - c - ? we have the length of b (p2line), and get the length of c.
                    float lc =sqrt((c.x-a.x)*(c.x-a.x)+(c.y-a.y)*(c.y-a.y));
                    p2line = sqrt((lc*lc)-(p2line*p2line));
                    beqa = false;
            }
            if(p2line < 0)
                                    p2line *=-1;
            if(p2line < 15)//accurance, wouldn't hit anything with <5
                                    ::wxMessageBox(wxString::Format("connection %i clicked\nDistance %i",i,p2line));
    }
    

    phlox



  • Sein A und B die Endpunkte der Linie/Strecke. M die Position des Mausklicks

    Der Vektor AB und AM und der Vektor BA und BM müssen beide einen Spitzen Winkel haben also Skalarprodukt > 0

    <AB, AM> > 0 && <BA, BM> > 0 - dann gilt Mausklick fand über bzw. unter der Strecke statt.

    Jetzt rechnest die Fläche des Parallelogramms aus das die Vektoren AB und AM aufspannen (Determinante)

    ist |det(AB;AM)| < l*e so wurde auf die linie geklickt

    l ist die Länge der Linie (die berechnest du mit der Wurzel, aber nur wenn sich die länge der linie ändert, du merkst dir einfach die länge der linie und berechnest sie nicht immer neu)

    e ist ca. der Abstand in Pixel in welchem der Benutzer daneben klicken darf



  • demoprogramm gewünscht? 😉



  • Vertexwahn schrieb:

    demoprogramm gewünscht? 😉

    ja 😉

    Für mich ist es wichtig das es funktioniert, und der rechner
    dahinter kann ruhig schwitzen, GUI ist halt nicht unbedingt auf
    Schnelligkeit aus. Solange es der User nicht bemerkt *g*

    phlox



  • mmmh finde momentan keine Zeit das zu schreiben - tut mir leid - muss mein Angebot zurück nehmen

    wenns dich aber trozdem interessiert: besorg dir das Buch Mathematik für Informatiker vom Hartmann - da steht das drin 😉


Anmelden zum Antworten