Achim Winkelacker: GD: Schnittpunkte ermitteln

Hallo

Ich möchte gerne mittels der GD-Libary für PHP einen dreidimensionalen Raum mit zwei Fluchtpunkten zeichnen. Wir hatten letztens im Konstruirenden Zeichnen dieses Thema und ich dachte beim zeichnen darüber nach, dass es auch mittels GD möglich sein müsste dies zu skizzieren.

Das ziehen von Linien ist ja kein Problem. Auch das setzen der Punkte ist kein problem. Mein problem liegt allerdings darin zu sagen "Dort wo sich Linie A und B schneidet liegt Punkt N". Kann man das mittels GD-Libary abfragen?

Ich habe mir neben dem ZEichnen ein Protokoll mit 15 Punkten mitgeschrieben welche Positionen man setzen muss, welche wege halbieren muss usw. um den Raum zu konstruiren. Es mangelt eben (so denke ich) nurnoch an der bestimmung von der bestimmung zwei sich krezender linien.

Freu mich auf Hilfe.

Achim

PS: Es möchte das wirklich in PHP machen. PHP ist dafür eigentlich eher nicht gedacht, aber ich möchte später vllt. darauf aufbauen können.

  1. Tach.

    Das ziehen von Linien ist ja kein Problem. Auch das setzen der Punkte ist kein problem. Mein problem liegt allerdings darin zu sagen "Dort wo sich Linie A und B schneidet liegt Punkt N". Kann man das mittels GD-Libary abfragen?

    Die GD-Lib selbst kennt so etwas wie Linien, aus denen sich ein Bild zusammensetzt, nicht. Sobald Du mit den entsprechenden Funktionen ins Bild gezeichnet hast, sind das bloß Punkte unterschiedlicher Farbe in einer großen Matrix. Schnittpunkte könntest Du also höchstens nachträglich auf graphischem Wege bestimmen, und das ist nicht so praktisch.

    Viel einfacher: Da Du Deine Verläufe ja eh konstruierst, *berechnest* Du am besten die Schnittpunkte völlig unabhängig von der GD-Lib. Dazu stellst Du die Geraden in jeweils einer Geradengleichung dar und ermittelst den Schnittpunkt durch Gleichsetzen und Umformen dieser Gleichungen.

    --
    Once is a mistake, twice is Jazz.
    1. » Viel einfacher: Da Du Deine Verläufe ja eh konstruierst, *berechnest* Du am besten die Schnittpunkte völlig unabhängig von der GD-Lib. Dazu stellst Du die Geraden in jeweils einer Geradengleichung dar und ermittelst den Schnittpunkt durch Gleichsetzen und Umformen dieser Gleichungen.

      Hallo

      Danke für den Link. Ich dachte ich käme um den tiefergehende Mathematischen Teil herum. Aber du hast sicher recht dass es nicht so einfach sein kann wie ich es mir dachte.

      Hast du praktische Beispiele für den Einsatz?
      Weil das klingt jetzt albern aber solche formeln sagen mir absolut garnichts. Leider.

      "Schneidet die Gerade die x-Achse im Punkt (a | 0) und die y-Achse im Punkt (0 | b), so lässt sich die Gleichung der Geraden in der Form

      x/a + y/b = 1

      schreiben."

      was heisst x, was a? Wieso 1. Sowas sind für mich Welten in denen ich leider nicht drinstecke.

      Ich bin auch eher jemand der rückwärts besser lernt. Javscript und Actionscript habe ich mir damals quasi rekursiv (oder reverse engernering-mässig) beigebracht und durch modifikation verstanden. Gibt es also eine Art Tutorial für solche "Grundlegende" Mathematische formulierungen?

      Wenn ich eine Linie in einem Bild (100x100) von 0|0 starte und bei 100|100 enden lasse sowie eine zweite bei 100|0 starte und bei 0|100 enden lasse dann sollten die sich in 50|50 schneiden (Das bild ergäbe folglich ein X-symbol). Wie kann ich z.B: dieses Beispiel auf die Formel oben anwenden?

      grüsse

      1. @@Achim Winkelacker:

        "Schneidet die Gerade die x-Achse im Punkt (a | 0) und die y-Achse im Punkt (0 | b), so lässt sich die Gleichung der Geraden in der Form
             x/a + y/b = 1
        schreiben."
        was heisst x, was a? Wieso 1.

        x und y sind die Koordinaten aller Punkte (x | y).

        Was a ist, steht doch in „Schneidet die Gerade die x-Achse im Punkt (a | 0)“: a ist der x-Wert des Schnittpunktes der Geraden mit der x-Achse (dessen y-Wert ist 0).

        Entsprechend ist b der y-Wert des Schnittpunktes der Geraden mit der y-Achse (dessen x-Wert ist 0).

        Alle Punkte, die die Gleichung x/a + y/b = 1 erfüllen, liegen auf der Geraden. Alle Punkte, die sie nicht erfüllen, liegen nicht auf der Geraden.

        Wenn ich eine Linie in einem Bild (100x100) von 0|0 starte und bei 100|100 enden lasse

        Schlechtes Beispiel! ;-) Aber für diese Gerade sollte es dir nicht schwerfallen, eine Gleichung der Form y = ƒ(x) zu finden.

        sowie eine zweite bei 100|0 starte und bei 0|100 enden lasse

        Du erkennst hier a und b?

        Live long and prosper,
        Gunnar

        --
        „Das Internet ist ein großer Misthaufen, in dem man allerdings auch kleine Schätze und Perlen finden kann.“ (Joseph Weizenbaum)
      2. Tach.

        x/a + y/b = 1

        was heisst x, was a? Wieso 1. Sowas sind für mich Welten in denen ich leider nicht drinstecke.

        Da hast Du Dir genau die Darstellung rausgesucht, die Dich erstmal am wenigsten weiterbringt. Deswegen hatte ich Dir ja den anderen Part auf der Seite verlinkt. ;)

        Hmm, wenn Du mit der Mathematik dort nicht so viel anfangen kannst und an Beispielen besser lernst, zeig ich Dir, was ich mir (in Matlab) ausgeknobelt habe:

        Eine Gerade a, die durch die Punkte A1 und A2 geht.
        Eine Gerade b, die durch die Punkte B1 und B2 geht.

        Jeder Punkt wird jeweils durch Koordinaten x (horizontal) und y (vertikal) beschrieben.

        Eine Hilfsfunktion cr(), die zwei Punkte A und B übergeben bekommt.

        function cr (A, B) {
            return A.x * B.y - A.y * B.x;
        }

        Den Schnittpunkt der Geraden a und b kann man nun so berechnen:

        ((A2-A1)*cr(B1, B2) - (B2-B1)*cr(A1, A2)) / cr(A2-A1, B2-B1)

        Damit mußt Du nur aufpassen, wenn beide Gerade parallel verlaufen, sich also nicht schneiden. Dann gibt es nämlich eine Division durch Null. Diesen Fall also vorher abfangen, sonst geht Dein Programm krachen!

        --
        Once is a mistake, twice is Jazz.
        1. Hallo

          Hmm, wenn Du mit der Mathematik dort nicht so viel anfangen kannst und an Beispielen besser lernst, zeig ich Dir, was ich mir (in Matlab) ausgeknobelt habe:

          Das ist extrem nett. Ich spiel mal mit und versuche dein Theorem so nachzuvollziehen als würde ich laut reden:

          Eine Gerade a, die durch die Punkte A1 und A2 geht.

          z.b. von links oben nach rechts unten. A1 wäre startwert, wobei A2 der Endwert wäre.

          Eine Gerade b, die durch die Punkte B1 und B2 geht.

          Jeder Punkt wird jeweils durch Koordinaten x (horizontal) und y (vertikal) beschrieben.

          Also hiesse der Satz aufgelöst mit beispielzahlen:
          Eine Gerade a, die durch die Punkte 10|10 und 90|90 geht

          Eine Hilfsfunktion cr(), die zwei Punkte A und B übergeben bekommt.

          function cr (A, B) {
              return A.x * B.y - A.y * B.x;
          }

          Wie muss ich diese Synatx verstehen? Auf PHP gemünzt hiesse der . zwichen A.x eine verbindung und ergäbe z.B: "40x" als string. Oder dient es mir nur als hinweis darauf welchen A-Schlüssel ich brauche?

          Ich übergebe also A und B. A und B sind jeweils x|y Werte... Dies müssten dann z.B. Arrays sein. Ich übergebe also A=Array(10,10); und B=Array(90,90);

          Dann hiesse der Return:
          return A[0] * B[1] - A[1] * B[0];

          Mhh...

          Den Schnittpunkt der Geraden a und b kann man nun so berechnen:

          ((A2-A1)*cr(B1, B2) - (B2-B1)*cr(A1, A2)) / cr(A2-A1, B2-B1)

          Also ist das erste Fragment eine art:
          (A2-A1) = (Array(x,y) - Array(x,y))
          Aber das kann doch nicht so erreicht werden...

          Damit mußt Du nur aufpassen, wenn beide Gerade parallel verlaufen, sich also nicht schneiden. Dann gibt es nämlich eine Division durch Null. Diesen Fall also vorher abfangen, sonst geht Dein Programm krachen!

          Dies kann erreicht werden indem ich dies nur anwende bei Geraden von denen ich weiss dass sie einen Schnittpunkt generieren müssen.

          Kannst du mir noch etwas meine Gedankengänge zurechtrücken? Du siehst ja selber dass ich mehr stolper als zielstrebig durchgehe was soetwas angeht und es immer gleich auf praxis münzen möchte...

          Liebe grüsse aus Düsseldorf

          1. @@Achim Winkelacker:

            Eine Hilfsfunktion cr(), die zwei Punkte A und B übergeben bekommt.

            function cr (A, B) {
                return A.x * B.y - A.y * B.x;
            }
            Wie muss ich diese Synatx verstehen?

            „zwei Punkte A und B“ ist verständlich? A und B sind also Punkte (in der Ebene). Jeder Punkt hat eine x- und eine y-Koordinate. Was also wird A.x, A.y, B.x, B.y bedeuten?

            Live long and prosper,
            Gunnar

            --
            „Das Internet ist ein großer Misthaufen, in dem man allerdings auch kleine Schätze und Perlen finden kann.“ (Joseph Weizenbaum)
          2. Tach.

            Eine Gerade a, die durch die Punkte A1 und A2 geht.
            z.b. von links oben nach rechts unten. A1 wäre startwert, wobei A2 der Endwert wäre.

            Genau. Allerdings haben Geraden gar keine Start- oder Endpunkte. Aber da Du ja vermutlich eh Strecken zeichnest, geht das schon in Ordnung. ;)

            Jeder Punkt wird jeweils durch Koordinaten x (horizontal) und y (vertikal) beschrieben.

            Also hiesse der Satz aufgelöst mit beispielzahlen:
            Eine Gerade a, die durch die Punkte 10|10 und 90|90 geht

            Ja, zum Beispiel.

            Eine Hilfsfunktion cr(), die zwei Punkte A und B übergeben bekommt.

            function cr (A, B) {
                return A.x * B.y - A.y * B.x;
            }

            Wie muss ich diese Synatx verstehen? Auf PHP gemünzt hiesse der . zwichen A.x eine verbindung und ergäbe z.B: "40x" als string. Oder dient es mir nur als hinweis darauf welchen A-Schlüssel ich brauche?

            Letzteres. Es sollte kein PHP sein, sondern nur die Koordinaten der Punkte A und B bezeichnen.

            Ich übergebe also A und B. A und B sind jeweils x|y Werte... Dies müssten dann z.B. Arrays sein. Ich übergebe also A=Array(10,10); und B=Array(90,90);

            Dann hiesse der Return:
            return A[0] * B[1] - A[1] * B[0];

            Ja, richtig. Ob Du das nun als Array in PHP realisierst, Dir eine Klasse "Punkt" schreibst oder sonstwas, bleibt Dir überlassen.

            Also ist das erste Fragment eine art:
            (A2-A1) = (Array(x,y) - Array(x,y))
            Aber das kann doch nicht so erreicht werden...

            Wie gesagt: das war kein PHP-Code. Diese Subtraktion nun computerverständlich umzusetzen, ist Deine Aufgabe. :) Die x-Koordinate des einen Punktes von der x-Koordinate des anderen Punktes abziehen und analog für die y-Koordinaten.

            Damit mußt Du nur aufpassen, wenn beide Gerade parallel verlaufen, sich also nicht schneiden. Dann gibt es nämlich eine Division durch Null. Diesen Fall also vorher abfangen, sonst geht Dein Programm krachen!

            Dies kann erreicht werden indem ich dies nur anwende bei Geraden von denen ich weiss dass sie einen Schnittpunkt generieren müssen.

            Du könntest auch einfach den Nennerterm (unterm Bruchstrich) vorher ausrechnen und entsprechend reagieren, wenn er Null ist. Ansonsten berechnest Du den Zählerterm (überm Bruchstrich) und dividierst einfach duch den vorher ermittelten Wert.

            --
            Once is a mistake, twice is Jazz.
  2. Tach.

    Schade, daß hier jetzt Funktstille herrscht. Interessiert mich ja schon, ob Du Dein Ziel inzwischen erreicht hast ...

    --
    Once is a mistake, twice is Jazz.