# Schnitt Geraden



## Nirvana (17. Jun 2012)

Schreibe eine Methode für den SChnitt zweier Geraden: Rückgabe entwder null oder ein Punkt2D.

Eine Klasse Vektor2D und Punkt2D hab ich mit diversen Methoden geschrieben.
Für die Klasse Gerade2D hab ich Felder und Konstruktoren programmiert.

Nun hab ich auch eine Methode, die überprüft ob zwei Geraden parallel sind.


```
private Punkt2D p;
    private Vektor2D v;

    public Gerade2D(Punkt2D p, Vektor2D v) {
        this.p = p;
        this.v= v;
    }

    public Gerade2D(Gerade2D g) {
        this.p = g.p;
        this.v = g.v;
```


```
public boolean parallel(Gerade2D other) {
        if (this.v.parallel(other.v)) { //Methode von Vektor2D, die Parallelität zweier Vektoren überprüft
            return true;
        } else {
            return false;
        }
    }
```

ABer wie mache ich das mit dem SChnittpunkt?
AUf den Zettel Setzte ich die beiden Geraden gleich und habe ein Gleichungssystem mit 2 Gleichungen wobei ich mir einen Parameter ausrechne und diesen dann in eine der Gleichungen einsetzte.
Ich komme aber nicht drauf wie ich mir in dem Fall die Paramter ausrechne, Hilfe wäre supa


----------



## njans (17. Jun 2012)

Anhand von 2 Punkten kannst du doch eine Gerade berechnen mx+b. Wenn du die hast, musst du nur in code gießen, was du auf dem Zettel machst


----------



## Nirvana (17. Jun 2012)

Wie eine Gerade berechnen?
Es sollen doch dann bei der ausführung, Punkt und Vektor der einen gerade und Punkt und Vektor der anderen gerade als Parameter eingetippt werden . Das Programm  dann null oder der Schnittpunkt ausgeben.

Ich eine Gerade: Punkt + t * Richtungsvektor
wobei t ein Parameter ist, aber wie programmiere ich das?


----------



## Nirvana (17. Jun 2012)

Das Poblem ist ja, das ich eine Unbekannte/Variable(die ich nicht initializiere) drinnen hab und damit kann das Pogramm nicht umgehen.
getb().. Methode dass die y-koordiante eines punktes zurückgibt
geta().. Methode dass die x-koordiante eines punktes zurückgibt

gety().. Methode dass die y-koordiante eines Vektors zurückgibt
getx().. Methode dass die x-koordiante eines Vektors zurückgibt


Ich poste mal mein falsches Programm: mit nicht initializierten t und nicht berücksichtigung der division durch 0.
Vlt gibt es auch eine viel bessere Art um das auszurechnen..

```
public Punkt2D Schnitt(Gerade2D g){
       if (this.parallel(g) == true){
            return null;
       }  else {
                 double t ;
                 double s =((this.p).geta() - (g.p).geta()+t*this.v.getx())/(g.v.getx());
                 t = (- this.p.getb() + g.p.getb()+s*g.v.gety())/(this.v.gety());
       
                double ko1 = this.p.geta() + t * this.v.getx();
                double ko2 = this.p.getb() + t * this.v.gety();
                Punkt2D Schnittpunkt = new Punkt2D(ko1,ko2);        
            return Schnittpunkt;
         }
```


----------



## AquaBall (17. Jun 2012)

Schreib mal, wie du das Schneiden 2er Geraden in Parameter-Schreibweise auf dem Papier machst, dann  sollte die Lösung nicht schwer fallen.

Edit: 
Du musst nicht 't' UND 's' berechnen,
aber 't' (oder 's') berechnen ist der korrekte Ansatz und geht wohl am einfachsten (standardisiert) mit der Substitutionsmethode.

Und am EINFACHSTEN wirds, wenn du ausschließlich symbolisch rechnest (logisch) bis zu beim Ergebnis bist t= ... (ohne Vektoren!).
Dann musst du nur noch schauen, welches Symbol welcher Variable in deinem Programm entspricht.


----------



## Nirvana (17. Jun 2012)

P(px//py)
Richtungsvektor g (gx//gy)
gerade 1 = P + t *g

Q(qx//qy)
Richtungsvektor h (hx//hy)
gerade 2 = Q + s *h

gerade 1 = gerade 2
in Komponentenschreibweise:
px + t gx = qx + s * hx
py + t hy = qy + s * hy

in I Gleichung:
(px + t gx - qx)/(hx) = s



und das setzte ich ein in II
py  + t hy = qy + (px + t gx - qx)/(hx) * hy
und löse nach t auf.

py hx + t hy hx = qy hx + (px + t gx - qx ) * hy
t =  (qy hx + (px - qx ) * hy - py hx)/ (hy hx - gx hy)

Mit den ganzen divisionen durch eventuell 0 hab ich aber ein problem


----------



## AquaBall (17. Jun 2012)

Na super!
Damit hast du ja die Lösung!
(Ich hab's übrigens nicht nachgeprüft, abder das (hy hy) erscheint mir verdächtig!)


Nirvana hat gesagt.:


> t =  (qy hx + (px - qx ) * hy - py hx)/ (hy hy - gx hy)


Musst du jetzt doch nur noch in Java-Form mit p.getX() ... bringen.

Und :


Nirvana hat gesagt.:


> Mit den ganzen divisionen durch eventuell 0 hab ich aber ein problem


"*Mit den ganzen *" ist wohl ein bisschen übertrieben!
Es gibt eine einzige?
Warum wohl? (Stichwort Parallelität!)
Die musst du halt davor abfangen! (bzw. Hast du das ja schon gemacht)

Der einzige Schritt, der noch fehlt, ist, dass du dieses 't' dann noch "anwenden" musst,
also in deine Gerade einsetzen. Dann bekommst du S(xS/yS), fertig!

PS: Man sieht, dass du's ja eh voll drauf hast!


----------



## AquaBall (17. Jun 2012)

Was ich noch vergessen habe: Beim Abfangen von "0": 
bedenke dass exakte Gleichheit mit Null im Computer bei double und float fast nie gegeben ist!

Du musst mit epsilon arbeiten!

(andererseits dürfte es eigentlich eh kein Problem (also nie eine Division durch Null) ergeben, wenn deine Parallelitäts-Prüfung korrekt arbeitet! Musst du aber trotzem absichern!)


----------



## Nirvana (17. Jun 2012)

Hallo 


SO ich hatte noch einen Berechnungsfehler in t jetzt passts.

Nochmal jetzt zur frage zurückkommend: Ich muss ja schauen, dass der Nenner nicht 0 wird.
Aber ich habe doch schon vorher Divisionen getätig, die hätte ich doch auch alle nicht machen düfen wenn einer der Nenner 0 ist. 

Der RICHTIGE nenner von t ist nun : gy hx - gx hy
Und dieser ist ja 0 wenn die richtungsvektoren parallel sind, also was ist da genau zu prüfen?


----------



## AquaBall (17. Jun 2012)

Ob du VOR der Parameterform Divisionen hattest ist nebensächlich.
(Das hängt von deinen Ausgangsdaten ab, in welcher Form, Aufgabenstellung ...)

Ab ParameterForm hast du ja nur eine einziges Division, und die kann nur null sein, wenn parallel.

Jetzt stellt sich also die Frage, 
a) wie du deinen Parallelität überprüfst.
oder b) den nenner vor der Division überprüfen 

```
Math.abs(gy hx - gx hy) > epsilon
```


(Natürlich musst du bei Parallelität noch unterscheiden, ob keine Lösung, oder unendlich viele!)
dürfte kein Problem für dich sein.


----------



## Nirvana (17. Jun 2012)

Hallo ich prüfe die Parallelität indem ich  die Richtungsvektoren anschaue, diese normiere und das Skalarprodukt ausrechne. Ist das 1 dann sind die Richtungsvektoren parallel wenn was anderes rauskommt dann nicht.

Mit wlechen Wert intialisierst du epislon?


----------



## AquaBall (18. Jun 2012)

Epsilon nach belieben 

Ich arbeite meist mit:

```
final  static double EPSILON=1e-10;
```
Das hat allerdings keinen erklärbaren Grund, und ich muss nie mit sehr hoher Genauigkeit rechnen.
'double' hat eine Genauigkeit von ca. 15 Stellen.
Wenn du mit Geldbeträgen rechnest, macht ein Epsilon < 0.01 keinen Sinn mehr.

Bei mir ist eher das Problem, dass ich mal im Pico- mal im Tera-Bereich rechne, aber selten mehr als 5 relevante Stellen brauche.
Dazu hab ich mir sogar eine recht komfortable RundungsMethode geschrieben, die nicht auf Komma-Stellen geht, sondern auf relevante Stellen.


----------

