Prüfen, ob sich ein Punkt auf Line befindet

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Cleo_DaVinci
User
Beiträge: 6
Registriert: Samstag 3. Juli 2021, 11:55

Hi,
ich möchte gerne überprüfen, ob sich ein Punkt auf einer Linie befindet. Man erstellt die Linie zuerst durch Angabe zweier Punkte im zweidimensionalen KoSy.
Dann gibt man einen Punkt als Parameter in eine Funktion ein, die dann prüfen soll, ob sich der Punkt auf der Linie befindet. Ich habe einen Ansatz dafür, aber man kann bei mir leider nur die Steigung und den y-Abschnitt der Geraden eingeben. Ich verstehe leider nicht, wie man die Funktion umschreibt, sodass man nur einen Punkt statt der Steigung m und des y-Achsenschnittpunktes c eingeben muss.

Code: Alles auswählen

def solve(m, b, point):
   if point[1] == (m * point[0]) + b: 
      return True
   return False
      

__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Deine Abkürzung von KoSy ist unüblich. Warum machst du das?

Zu deiner Frage: das problem allgemein (also auch bei einer geraden, die senkrecht ist) zu lösen, kenne ich nur die Bildung des Skalarprodukts mit der Normalen auf der Geraden. Der Punkt liegt auf der Geraden, wenn das 0 (=senkrecht zur Normalen) ist.

Realistischerweise würde man wohl ein epsilon bestimmen, bei dem eine kleinerer, aber nicht-null Abstand auch als “drauf” gilt, weil das sonst numerisch schwierig wird.

Wenn du also zwei Punkte A und B hast, dann bestimmst du erstmal den Richtungsvektor R als (B-A). Den rotierst du um 90 grad (Koordinaten vertauschen und die neue x-Koordinate negieren), normalisierst den auf Länge 1, und bildest das skalarprodukt mit dem Vektor (P-A), wenn P dein Punkt den du prüfen willst, ist.

Davon nimmst du den Betrag und wenn der kleiner als epsilon ist, dann ist der Punkt auf der Linie.
Sirius3
User
Beiträge: 17797
Registriert: Sonntag 21. Oktober 2012, 17:20

Eingerückt wird immer mit 4 Leerzeichen Pro Ebene, nicht 3. Da die if-Bedingung schon ein Wahrheitswert ist, kann man die Funktion kürzer schreiben:

Code: Alles auswählen

def solve(m, b, point):
    return point[1] == (m * point[0]) + b
Wenn Du die Formel mit y-Abschnitt und Steigung kennst, dann mußt Du doch nur die zwei Geradenpunkte in diese Form umrechnen.
Benutzeravatar
__blackjack__
User
Beiträge: 13199
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Cleo_DaVinci: Anmwerkungen zum Quelltext: Eingerückt wird mit vier Leerzeichen pro Ebene.

Der Vergleich in der ``if``-Bedingung liefert schon Wahr oder Unwahr, das heisst man braucht kein ``if`` sondern kann direkt das Ergebnis des Vergleichs als Ergebnis liefern:

Code: Alles auswählen

def solve(m, b, point):
    return point[1] == m * point[0] + b
Das ganze funktioniert nur zuverlässig solange man hier nur ganze Zahlen verwendet. Bei Gleitkommazahlen darf man weger der eventuellen Ungenauigkeiten die das Format mit sich bringt, nicht auf ``==`` testen, sondern muss testen ob die Werte nahe genug liegen um sie als gleich ansehen zu können. Das `math`-Modul hat eine Funktion dafür:

Code: Alles auswählen

import math


def solve(m, b, point):
    return math.isclose(point[1], m * point[0] + b)
“There will always be things we wish to say in our programs that in all known languages can only be said poorly.” — Alan J. Perlis
Benutzeravatar
NoPy
User
Beiträge: 158
Registriert: Samstag 28. Dezember 2013, 12:39

Hallo Cleo,

das klingt nach Mathe- oder Informatik- Hausaufgabe. Wenn ich Dich richtig verstehe, dann suchst Du eine Funktion der Art

Code: Alles auswählen

def liegt_punkt_auf_geraden(P1, P2, PX):
    #P1, P2 = Endpunkte der Geraden, PX = gesuchter Punkt
Alles, was die anderen Forenteilnehmer gesagt haben, ist auf alle Fälle zu beachten, ich zähle es noch einmal kurz auf:
  • Einrückungen um 4 Leerzeichen (pythonspezifische Festlegung)
  • Punkte, die senkrecht übereinander liegen, bekommst Du mit Deinem Ansatz mx+n nicht, da m dann unendlich wäre
  • wenn Du mit reellen Zahlen arbeitest, dann ist 1.5 * 1.5 eben nicht genau 2.25. Das liegt daran, dass die interne Repräsentation einer Zahl irgendwo Schluss machen muss. Pi ist ja auch nicht 3,14 oder 3,14159265 sondern viel länger. Du kannst also streng genommen nur einen Punkt finden, der dicht genug an der Geraden liegt.

Jetzt zum Mathematischen Teil:
Bleiben wir mal bei dem der Version y = mx + n, dann steht die Frage, wie man das m und n aus zwei Punkten herausbekommt.
Ich habe die x- bzw. y- Werte hier mal mit P1x, P1y, P2x, P2y bezeichnet

m ist der Anstieg, wenn Du Dir die beiden Punkte aufmalst, wirst Du leicht erkennen, dass m = (P2y-P1y)/(P2x-P1x) ist. Hier wird auch klar, warum das nicht funktioniert, wenn P2x und P1x identisch sind. Du musst also in Deine Funktion in eine entsprechende Fallunterscheidung einbauen, die diesen Fall gesondert prüft.

n ist Dein y- Abschnitt.
Da Du ja m inzwischen kennst, kannst Du einen der beiden bekannten Punkte einsetzen, beispielsweise P1, dann gilt P1y = m * P1x + n
Das musst Du nun nach n umstellen und hättest das auch.

Jetzt solltest Du alle Bausteine haben, um Deine Funktion anpassen zu können. Versuch es bitte aus eigener Kraft, sonst lernst Du ja nichts. Aber wenn Du weitere Fragen hast, dann stelle sie ruhig.

ps: Fast hätte ich es vergessen: Was genau heißt auf der Linie liegen? Auf der geraden durch die beiden Punkte oder auf der Strecke zwischen den beiden Punkten? Im letzteren Fall musst Du auch noch ausschließen, dass der Punkt zwar auf der Geraden liegt, aber eben nicht zwischen den beiden Punkten.
Antworten