Schnittpunkt von kanten berechnen

F.S.WhiTeY

Bekanntes Mitglied
Hallo Com. ,
Ich hab ein dringendes Problem. Ich muss eine Laboraufgabe fertigstellen, welche mir den Schnittpunkt von N Kanten über einen Scannlinealgorithmus ermittelt.

Der Scannline ansatz als solches ist kein Problem, allerdings das Testen ob ein Schnittpunkt vorliegt und das berechnen macht mir Sorgen.

Ich finde den Fehler nicht, wenn ihr also mal einen Blick auf meinen Ansatz werfen könntet?

Um das Programm zu verstehen, hier die Datentypen Punkt und Kante, welche die Strecke in der 2D-Ebene Repräsentieren:

Wie sieht ein Punkt aus ?
Java:
public class Punkt {

    //Ein Punkt mit X- und Y-Ordinate
    private Kante kante;
    private int x;
    private int y;

    public Punkt(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int getX() {
        return this.x;
    }

    public int getY() {
        return this.y;
    }

    public void setKante(Kante kante) {
        this.kante = kante;
    }

    public Kante getKante() {
        return this.kante;
    }
}

Wie sieht eine Kante aus ?
Java:
//Kante mit sortierten Punkten nach X-Wert
public class Kante {

    private Punkt rechterPunkt;
    private Punkt linkerPunkt;
    private int name;

    public Kante(Punkt eins, Punkt zwei, int name) {
        this.name = name;
        if (eins.getX() < zwei.getX()) {
            this.linkerPunkt = eins;
            this.rechterPunkt = zwei;
        } else {
            this.rechterPunkt = eins;
            this.linkerPunkt = zwei;
        }
    }

    public Punkt getLinks() {
        return this.linkerPunkt;
    }

    public Punkt getRechts() {
        return this.rechterPunkt;
    }

    public int gename() {
        return name;
    }
}

Hier der Test ob ein Schnittpunkt vorliegt:

Java:
public boolean schnittpunktTest(Kante p, Kante q) {
        boolean schnitt = false;
        int o1 = ccw(p.getLinks(), p.getRechts(), q.getLinks());
        int o2 = ccw(p.getLinks(), p.getRechts(), q.getRechts());
        int o3 = ccw(q.getLinks(), q.getRechts(), p.getLinks());
        int o4 = ccw(q.getLinks(), q.getRechts(), p.getRechts());

        if (((o1 * o2) <= 0) && ((o3 * o4) <= 0)) {
            schnitt = true;
        }
        return schnitt;
    }

    public int ccw(Punkt a, Punkt b, Punkt c) {

        int u1 = b.getX() - a.getX();
        int u2 = b.getY() - a.getY();
        int v1 = c.getX() - a.getX();
        int v2 = c.getY() - a.getY();

        int det = (u1 * v2) - (u2 * v1);
        if (det > 0) {
            return 1;
        } else if (det < 0) {
            return -1;
        } else if ((u1 * v1 < 0) || (u2 * v2 < 0)) {
            return -1;
        } else if ((u1 * u1 + u2 * u2) >= (v1 * v1 + v2 * v2)) {
            return 0;
        }
        return 1;
    }

Hier nun der Ansatz zum Berechnen des Schnittpunktes:


Java:
    public Punkt schnittpunktTest2(Kante a, Kante b) {

        Punkt schnitt = null;
        int x1 = a.getLinks().getX();
        int x2 = a.getRechts().getX();
        int x3 = b.getLinks().getX();
        int x4 = b.getRechts().getX();
        int y1 = a.getLinks().getY();
        int y2 = a.getRechts().getY();
        int y3 = b.getLinks().getY();
        int y4 = b.getRechts().getY();

        //Die Determinante berechnen und schauen ob sie Ungleich 0 ist
        // Ist die Determinante der Kanten 0 , so liegt ein Sonderfall vor
        double determinante = (((y4 - y3) * (x2 - x1)) - ((x4 - x3) * (y2 - y1)));

        if (determinante == 0) {
            System.err.println("Determinante = 0 ! Parallelen, Kollinär oder übelappend! ");
            return null;
        }

         //Hier geht es nach folgendem Mathematischen Ansatz weiter:
         //Pa = P1 + alpha  * ( P2 - P1  )
         //Pb = P3 + betah * ( P4 - P3 ) 
         //Ein Schnittpunkt liegt vor, wenn Pa == Pb
         // Daraus folgt: 
         //x1 + alpha (x2 - x1) = x3 + betha (x4 - x3)
         //y1 + alpha (y2 - y1) = y3 + betha (y4 - y3) 
         //wenn wir umstellen erhalten wir : 
            
        double alpha = ((x4 - x3) * (y1 - y3)) - ((y4 - y3) * (x1 - x3))/determinante;
        double betah =(((x2 - x1) * (y1 - y3)) - ((y2 - y1) * (x1 - x3)))/determinante;
         
         //damit können wir einsetzen und erhalten die Punkte:
         
        int xa = (int) (x1 + (alpha * (x2 - x1)));
        int ya = (int) (y1 + (alpha * (y2 - y1)));

        int xb = (int) (x3 + (betah * (x4 - x3)));
        int yb = (int) (y3 + (betah * (y4 - y3)));

            schnitt = new Punkt(xa, yb);

        return schnitt;
    }

Der Scannline Algorithmus, Aufruf wird Durchgereicht:

Java:
.....

private void scann() {
        Iterator<Punkt> it = sortX.iterator();
        while (it.hasNext() && kanten.size() > 1) {
            Punkt akt = it.next();
            if (akt == akt.getKante().getLinks()) {

                int index = kanten.indexOf(akt.getKante());
                Kante a = kanten.get(index);
                Kante b = null;
                Kante c = null;

                if (index + 1 < kanten.size()) {
                    b = kanten.get(index + 1);
                }
                if(index-1>=0){
                    c=kanten.get(index - 1);
                }

                if (b != null&&schnitt.schnittpunktTest(a, b) ) {
                    System.out.println("ich mache was");
                    Punkt temp = schnitt.schnittpunktTest2(a, b);
                    if(temp!=null)
                    schnittpunkte.add(temp);
                }
                if (c!=null&&schnitt.schnittpunktTest(a, c)) {
                    System.out.println("ich mache was");
                    Punkt temp = schnitt.schnittpunktTest2(a, c);
                    if(temp!=null)
                    schnittpunkte.add(temp);
                }


            } else if (akt == akt.getKante().getRechts()) {

                int index = kanten.indexOf(akt.getKante());
                Kante a = kanten.get(index);
                Kante b = null;
                Kante c = null;

                if (index + 1 < kanten.size()) {
                    b = kanten.get(index + 1);
                }
                if(index-1>=0){
                    c=kanten.get(index - 1);
                }

                if (b != null&&schnitt.schnittpunktTest(a, b) ) {
                    System.out.println("ich mache was");
                    Punkt temp = schnitt.schnittpunktTest2(a, b);
                    if(temp!=null)
                    schnittpunkte.add(temp);
                }
                if (c!=null&&schnitt.schnittpunktTest(a, c)) {
                    System.out.println("ich mache was");
                    Punkt temp = schnitt.schnittpunktTest2(a, b);
                    if(temp != null)
                    schnittpunkte.add(temp);
                }
                kanten.remove(akt.getKante());
            } else {
                System.err.print("SCANNLINE ALGORITHMUS <WEDER LINKES NOCH RECHTES OBJEKT!!!>");
            }
        }
    }

......
 
S

SlaterB

Gast
meine Güte, wer soll das alles testen?
mindestens musst du noch ein Hauptprogrogramm (main-Methode) dazu liefern,
mit z.B. zwei einfachen Kanten, die sich schneiden, und auf den Papier den Schnittpunkt ausrechnen, wirst du ja sicher eh kennen,

dann doch wenigstens ein bisschen beschreiben in welcher Reihenfolge dein Code dabei drankommt, was genau er alles macht,
paar Kommentare hast du schon, hab jetzt nicht genau geschaut was alles schon klar und was noch unklar ist,
ich überlasse vorher noch dir, das zu überdenken,
aber welchen Sinn hat z.B. die lange Methode scann()? wenn die gar nicht für EINE Schnittpunktberechnung benötigt wird,
kann die dann nicht (vorerst) wegfallen?
kannst du das Testprogramm nicht auf eine bestimmte Zeile einschränken oder so?

wenn du die Berechnungen und ihren Ablauf so ungefähr verfolgst, dann könntest du eigentlich auch idealerweise jede einzelne Berechnung per System.out.println() loggen und so selber sehen, ab wann es von deiner Papierrechnung abweicht ;)
aber muss auch nicht sein, bisschen kannst du auch anderen überlassen
 

Landei

Top Contributor
Wenn du zwei Kanten (x0,y0) nach (x1,y1) und von (x2,y2) nach (x3,y3) hast, dann rechnest du (Berechnung natürlich nicht in int sondern in double, Divisor vorher auf 0 testen):

p = ((x1-x0)*(y2-y0)-(x3-x2)*(y1-y0))/((x3-x2)*(y1-y0)-(x1-x0)*(y3-y2))
q = ((x2-x0)+p*(x3-x2))/(x1-x0)
bzw. (wenn x1-x0 == 0 ist):
q = ((y2-y0)+p*(y3-y3))/(y1-y0)

Falls p und q jeweils zwischen 0 und 1 liegen, schneiden sich die Kanten.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
I Schnittpunkt zweier Geraden berechnen Java Basics - Anfänger-Themen 25
U Best Practice Graphen Tiefensuche Klassifizierung von Kanten "B","C","F" Java Basics - Anfänger-Themen 2
X Minimax-Algorithmus über alle Kanten möglich? - Kanten darstellen Java Basics - Anfänger-Themen 1
F Kanten in Graph Java Basics - Anfänger-Themen 3
B Finden gemeinsamer Kanten: welche Datenstruktur ? Java Basics - Anfänger-Themen 9
M OOP Brüche nicht richtig berechnen Java Basics - Anfänger-Themen 3
V Durchschnittliche Volatility in Prozent für 4 Stunden berechnen Java Basics - Anfänger-Themen 14
T Fibonacci mit einer Hilfsmethode berechnen Java Basics - Anfänger-Themen 10
laxla123 Quersumme berechnen Java Basics - Anfänger-Themen 1
I For Schleife Summe berechnen Java Basics - Anfänger-Themen 13
S Vollmond berechnen und ausgeben Java Basics - Anfänger-Themen 12
S Vollkommene Zahl berechnen und ausgeben Java Basics - Anfänger-Themen 16
A Berechnen Moor Nachbarschaft Java Basics - Anfänger-Themen 5
E Geburtstag im Schaltjahr berechnen Java Basics - Anfänger-Themen 24
Lion.King Schaltjahr berechnen Java Basics - Anfänger-Themen 31
E Alter (Laufzeit) berechnen Java Basics - Anfänger-Themen 11
I Zuschläge berechnen Java Basics - Anfänger-Themen 15
L mit Fakultät mathematische Formel berechnen Java Basics - Anfänger-Themen 5
TanTanIsTrying Durschnitt berechnen von eingegebener Zahl bis 1 heruntergezählt Java Basics - Anfänger-Themen 9
L Präfix berechnen Java Basics - Anfänger-Themen 33
F Abstand zwischen zwei Objekten berechnen wie? Java Basics - Anfänger-Themen 1
Aemulit Java Schaltjahr berechnen Code Java Basics - Anfänger-Themen 7
Poppigescorn Quersumme Berechnen mit einer While Schleife Java Basics - Anfänger-Themen 13
I Potenz berechnen mit for-Schleife Java Basics - Anfänger-Themen 3
A Standardabweichung in Java berechnen Java Basics - Anfänger-Themen 10
H Gesamtabweichung mit Array berechnen Java Basics - Anfänger-Themen 2
G Java Rabatt berechnen Java Basics - Anfänger-Themen 8
V Rückgeld berechnen Java Basics - Anfänger-Themen 6
eleonori Durchschnitt aller Werte eines Baums berechnen Java Basics - Anfänger-Themen 5
Ianatrix Zahlen von a bis b berechnen Java Basics - Anfänger-Themen 7
L Max, min, Summe und Durchschnitt berechnen Java Basics - Anfänger-Themen 4
L Anhalteweg berechnen Java Basics - Anfänger-Themen 6
Aeon Erste Schritte Preise berechnen mit do-while Java Basics - Anfänger-Themen 9
M Quadratwurzel berechnen Java Basics - Anfänger-Themen 8
V Wachstum berechnen und in Ist-Formel verwenden Java Basics - Anfänger-Themen 5
N Variable aus anderen Variablen in statischer Klasse berechnen/abspeichern? Java Basics - Anfänger-Themen 4
M Abschreibungsplan berechnen Java Basics - Anfänger-Themen 23
V Gehalt berechnen in Java Java Basics - Anfänger-Themen 6
justemii Gehalt berechnen - Aufgabe Java-Programm Java Basics - Anfänger-Themen 9
L Anzahl der benachbarten Minen berechnen und setzen Java Basics - Anfänger-Themen 15
J Array Speicherplatz berechnen Java Basics - Anfänger-Themen 35
H Eingabedaten berechnen Java Basics - Anfänger-Themen 9
B Tranportkosten berechnen mit unterschiedlichen MwSt Java Basics - Anfänger-Themen 9
L Anzahl der Paare deren Summe = 0 ergibt berechnen Java Basics - Anfänger-Themen 0
V Erste Schritte Berechnen von Sinus; sin(x) ohne Math.* Java Basics - Anfänger-Themen 1
J Hilfe bei Java Aufgabe (Restschuld berechnen) Java Basics - Anfänger-Themen 11
N Ein Datum berechnen Java Basics - Anfänger-Themen 3
T Sparplan berechnen Java Basics - Anfänger-Themen 4
F Abstand zum Durchschnitt von 5 Zahlen berechnen... Java Basics - Anfänger-Themen 16
B java.util.Date berechnen Java Basics - Anfänger-Themen 11
P Mittelwert Arrayelemente berechnen Fehler Java Basics - Anfänger-Themen 5
CptK Best Practice Schussparabel berechnen Java Basics - Anfänger-Themen 3
T Modulo / Pow berechnen Java Basics - Anfänger-Themen 4
E Statistische Kennzahlen berechnen Java Basics - Anfänger-Themen 2
F Switch Case Modulo berechnen Java Basics - Anfänger-Themen 12
B mehrere Werte mit scanner und while schleife einlesen, max berechnen bzw addieren Java Basics - Anfänger-Themen 2
C Preis berechnen mit Java Java Basics - Anfänger-Themen 4
B Zahl in String abspeichern und später berechnen Java Basics - Anfänger-Themen 15
N Best Practice Image recognition fuzzy Superhash berechnen Java Basics - Anfänger-Themen 1
Dawinartor Erste Schritte Schaltjahr berechnen Java Basics - Anfänger-Themen 1
L Pi berechnen Java Basics - Anfänger-Themen 1
CptK Term (als String) berechnen und ausgeben Java Basics - Anfänger-Themen 10
L Den Winkel zwischen zwei Vektoren berechnen! Java Basics - Anfänger-Themen 2
J Variablen arithmetischen Mittelwert berechnen Java Basics - Anfänger-Themen 5
K Matrixen berechnen nach Worker Master Paradigma mit Threads Java Basics - Anfänger-Themen 4
R Winkel berechnen bzw. Geraden sortieren Java Basics - Anfänger-Themen 33
M Erste Schritte Mittelwert berechnen -> Methode in der Methode? Java Basics - Anfänger-Themen 14
S Compiler-Fehler Schaltjahr berechnen Java Basics - Anfänger-Themen 5
B Fakultätsfunktion Rekursiv Berechnen aber mit Array Java Basics - Anfänger-Themen 10
S Durchschnitt berechnen aus zwei Textfeldern Java Basics - Anfänger-Themen 21
D Summe berechnen mit verändertem Wert aus Schleife Java Basics - Anfänger-Themen 1
R Liga Berechnen Java Basics - Anfänger-Themen 1
P Klassen Berechnen mehrerer Map-Werte Java Basics - Anfänger-Themen 13
R Fussballtabellen berechnen Java Basics - Anfänger-Themen 12
J Fibonacci -Folge rekursiv berechnen Java Basics - Anfänger-Themen 18
J Durchschnitt jeder Zeile und und Spalte in einem 2D Arrays berechnen Java Basics - Anfänger-Themen 6
F ISBN Prüfziffer berechnen Java Basics - Anfänger-Themen 17
F Die Teilersumme einer Eingabe berechnen Java Basics - Anfänger-Themen 11
S Negafibonacci Folge berechnen Java Basics - Anfänger-Themen 24
G Array Mittelwert berechnen, wie? Java Basics - Anfänger-Themen 8
S Primzahlen berechnen funktioniert nicht richtig Java Basics - Anfänger-Themen 1
N Mit LocalDate alter berechnen Java Basics - Anfänger-Themen 3
J Laufzeit berechnen/Laufzeitanalyse Java Basics - Anfänger-Themen 2
N Arrays mit Zufallzahlen füllen und Statistiken berechnen Java Basics - Anfänger-Themen 5
A Wochentag berechnen Java Basics - Anfänger-Themen 10
Ste3et_C0st Vectoren berechnen Java Basics - Anfänger-Themen 8
L Durchschnitt in der Schleife berechnen Java Basics - Anfänger-Themen 11
A Kreisumfang/-Fläche vom Kreis berechnen Java Basics - Anfänger-Themen 39
L Wochentag berechnen Java Basics - Anfänger-Themen 5
L Rekursive Methode a * b berechnen Java Basics - Anfänger-Themen 2
B OOP Summe aus verschiedenen Instanzen einer Klasse berechnen Java Basics - Anfänger-Themen 2
N Dauer zwischen zwei LocalDateTime Objekten berechnen? Java Basics - Anfänger-Themen 4
P Ausdrücke berechnen Java Basics - Anfänger-Themen 2
V Mittelwert berechnen Java Basics - Anfänger-Themen 31
H Datentypen Tage zwischen zwei Datums berechnen Java Basics - Anfänger-Themen 4
P Quadrate berechnen Java Basics - Anfänger-Themen 3
S OOP Datumsunterschied in Tagen berechnen Java Basics - Anfänger-Themen 3
M Methoden Aus Timestamp das Datum berechnen Java Basics - Anfänger-Themen 3
B Schaltjahre berechnen! Java Basics - Anfänger-Themen 1
A werte in einem String berechnen Java Basics - Anfänger-Themen 3

Ähnliche Java Themen

Neue Themen


Oben