Schnittpunkt zweier Kurven berechnen und darstellen

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
würmchen
User
Beiträge: 255
Registriert: Mittwoch 7. November 2007, 14:17

Hi Leute,
ich wurschtel mich gerade durch Module und was es nicht alles gibt. Ich hab zwei Messreihen mit Werten und ich will den ersten Schnittpunkt berechnen, wenn es einen gibt und das dann Grafisch darstellen.

Ich benutze normal matplotlib für Grafiken, denke auch nicht, dass das ein Problem darstellen wird.

Ich suche gerade nach geeigneten Funktionen bzw Modulen, die mir helfen den Schnittpunkt zu bestimmen und irgendwie fehlt mir eventuell der richtige Ansatz. Ich bin durch die Suche hier im Forum einmal auf interp von numpy gestoßen und zum anderen auf interpld von scipy.interpolate Paket.

Was ich ja eigentlich brauche ist die Interpolierte Formel die ich dann gleichsetzen würde, um den Schnittpunkt zu bekommen. Aber irgendwie fehlt mir da was bei den Funktionen.

Hat jemand eine Idee?
Zuletzt geändert von würmchen am Dienstag 16. November 2010, 10:43, insgesamt 1-mal geändert.
Benutzeravatar
DaMutz
User
Beiträge: 202
Registriert: Freitag 31. Oktober 2008, 17:25

Ich weiss nicht wie genau dein Resultat sein muss, aber du kannst doch für jedes x die y Werte der 2 Kurven vergleichen, und falls sich das Vorzeichen bei der Subtraktion der beiden y-Werte wechselt, dann bist du über dem Schnittpunkt. In diesem Fall kannst du annehmen, das zwischen dem letztem x-Wert und dem aktuellen x-Wert 2 Geraden sind. Also kannst du den Schnittpunkt relativ gut über die Steigung der beiden Geraden bestimmen.
Benutzeravatar
gkuhl
User
Beiträge: 600
Registriert: Dienstag 25. November 2008, 18:03
Wohnort: Hong Kong

@würmchen: Schau dir mal scipy.optimize an.

Grüße
Gerrit
würmchen
User
Beiträge: 255
Registriert: Mittwoch 7. November 2007, 14:17

Hallo DaMutz,
danke für Deine Antwort. Was ich bis jetzt zusammen gewurschtelt habe ist folgendes:

Code: Alles auswählen

#!/usr/bin/python
import matplotlib.pyplot as plt

x = [0, 0.003125, 0.00625, 0.009375, 0.0125, 0.015625, 0.01875, 0.021875,
        0.025, 0.028125, 0.03125, 0.034375, 0.0375, 0.040625, 0.04375,
        0.046875, 0.05, 0.053125, 0.05625, 0.059375, 0.0625, 0.065625,
        0.06875, 0.071875, 0.075]
y = [1, 0.999047, 0.999395, 0.998146, 0.998195, 0.995055, 0.991389, 0.986017,
        0.975712, 0.955083, 0.848445, 0.636692, 0.428856, 0.158032, 0.146217,
        0.060778, 0.064174, 0.037960, 0.045710, 0.132336, 0.049380, 0.069293,
        0.100474, 0.067792, 0.165866]
y2 = [1, 0.79122, 0.563579, 0.496913, 0.406382, 0.358591, 0.338419, 0.317536,
        0.302411, 0.279794, 0.275270, 0.267973, 0.258447, 0.251169, 0.246099,
        0.244383, 0.236381, 0.233057, 0.229762, 0.228531, 0.224678, 0.221502,
        0.220399, 0.218106, 0.216391]

def crossing(ay1,ay2,by1,by2):
    if ((ay1 > by1) & (ay2 <= by2)):
        print "Schneidet"
        return True
    else:
        return False

for i in range(len(y)-1):
    if crossing(y[i],y[i+1],y2[i],y2[i+1]):
        print y[i], x[i], "bis", y[i+1], x[i+1]
        print "Schnittpunkt zwischen", x[i], "und", x[i+1], "."

plt.plot(x,y,'o-',x,y2,'o-')
plt.show()
Ich weiß also jetzt wo der Schnittpunkt ungefähr liegt, zwischen zwei Messpunkten. Wollte jetzt heute versuchen über die Geradengleichung den Schnittpunkt genau zu berechnen, aber irgendwie bin ich mit der Lösung noch nicht zufrieden.

Die Messwerte für die zweite Kurve ist eigentlich eine Funktion, ich hab sie eben nur zum testen grob übernommen, aber eigentlich ist da schon eine Funktion vorhanden um die Werte zu erzeugen.

@gkuhl ich schau mir das Modul mal an, auch danke...

Wenn Jemand wie gesagt ne elegantere Idee hat um das zu lösen, hab ich ein offenes Ohr für :-)
würmchen
User
Beiträge: 255
Registriert: Mittwoch 7. November 2007, 14:17

Ok, also ich hab die Berechnung dann fertig. Ich denke dass man es eigentlich so lassen kann, weiß im Nachhinein nicht, ob da eine Interpolation so viel Sinn macht.

Code: Alles auswählen

#!/usr/bin/python
import matplotlib.pyplot as plt

x = [0, 0.003125, 0.00625, 0.009375, 0.0125, 0.015625, 0.01875, 0.021875,
        0.025, 0.028125, 0.03125, 0.034375, 0.0375, 0.040625, 0.04375,
        0.046875, 0.05, 0.053125, 0.05625, 0.059375, 0.0625, 0.065625,
        0.06875, 0.071875, 0.075]
y = [1, 0.999047, 0.999395, 0.998146, 0.998195, 0.995055, 0.991389, 0.986017,
        0.975712, 0.955083, 0.848445, 0.636692, 0.428856, 0.158032, 0.146217,
        0.060778, 0.064174, 0.037960, 0.045710, 0.132336, 0.049380, 0.069293,
        0.100474, 0.067792, 0.165866]
y2 = [1, 0.79122, 0.563579, 0.496913, 0.406382, 0.358591, 0.338419, 0.317536,
        0.302411, 0.279794, 0.275270, 0.267973, 0.258447, 0.251169, 0.246099,
        0.244383, 0.236381, 0.233057, 0.229762, 0.228531, 0.224678, 0.221502,
        0.220399, 0.218106, 0.216391]

def crossing(ay1,ay2,by1,by2):
    if ((ay1 > by1) & (ay2 <= by2)):
        return True
    else:
        return False

def twoPoint(x1,y1,x2,y2):
    m = (y2 - y1) / (x2 - x1)
    n = y1 - (y2 - y1) / (x2 - x1) * x1
    print m, "x +", n
    return (m, n)

def intersection(g1 ,g2):
    x = g2[0] - g1[0]
    n = g1[1] - g2[1]
    result = n / x
    print "Intersection x=", result
    print "Resolution =", 1/result, "A"


for i in range(len(y)-1):
    if crossing(y[i],y[i+1],y2[i],y2[i+1]):
        g1 = twoPoint(x[i],y[i],x[i+1],y[i+1])
        g2 = twoPoint(x[i],y2[i],x[i+1],y2[i+1])
        intersection(g1,g2)

plt.plot(x,y,'o-',x,y2,'o-')
plt.show()
Will jetzt noch den Schnittpunkt mit ner gestrichelten Linie nach X darstellen und auch die gemessenen Werte noch auf der Grafik ausgeben, aber ich denke das bekomme ich dann so hin.

@gkuhl, der Link hat mir nicht wirklich geholfen. Lag aber sicher an meiner komischen Fragestellung. Trotzdem danke.
BlackJack

@würmchen: Die `crossing()`-Funktion lässt sich kürzer schreiben wenn Du ``and`` statt ``&`` verwendest. Der ``&``-Operator ist für die logische Verknüpfung von Bits. Das funktioniert hier zwar zufällig, aber dir geht es ja um Wahrheitswerte. Ausserdem ist ``and`` auch ein wenig lesbarer.

Code: Alles auswählen

def crossing(ay1, ay2, by1, by2):
    return ay1 > by1 and ay2 <= by2
würmchen
User
Beiträge: 255
Registriert: Mittwoch 7. November 2007, 14:17

Hi Blackjack,
danke für den Hinweis, hatte erst and, dann hatte es aber nicht das gemacht was ich wollte... Beim Fehlersuchen war ich nicht sonderlich ausgeschlafen und hab einfach mal überall Klammern drum gemacht und das and mit einem & ersetzt.
Heute morgen ist mir dann mein Fehler aufgefallen, dass ich einfach by2 <= by2 vergleiche und das ist relativ oft wahr :-)

Danke Vielmals...
Antworten