Oops, my fault - wir brauchen ja den Richtungsvektor:Danke, ich habe die Funktion der Methode falsch verstanden... Das war jetzt ja wirklich nicht so schwierig.
return switchedTo.equals(passed) ? getStartPoint().directionTo(switchedTo) : switchedTo.directionTo(getStartPoint());
Das kann so nicht stimmen, oder?return switchedTo.equals(passed) ? getStartPoint().directionTo(switchedTo) : switchedTo.directionTo(getStartPoint());
public Point getDirectionTo(Point passed) {
return switchedTo.equals(passed) ? toDirection(switchedTo) : toDirection(getStartPoint());
}
Ich meine den Richtungsvektor start -> switch bzw. umgekehrt switch -> start.Das kann so nicht stimmen, oder?
Damit meinst du genau diese Methode, oder @mihe7 ?Der ist ja das Problem Fahr mal um eine Kurve, dann fährt die Lok z. B. nach rechts, während die Waggons noch nach oben fahren. getDirectionTo liefert sozusagen die Fahrtrichtung der Waggons auf dem Gleis.
Mhm, warum ist meine startTrack (1,1) -> (5,1)? Es müsste doch (5,1) -> (8,1) sein, oder nicht?Also, in #178 ist doch der Ablauf, an welcher Stelle unterscheidet sich Deiner denn davon?
Einfacher ist es, wenn Du mit dem Debugger durchgehst. Für (6,1), (1,0) müsste in den else-Zweig gesprungen werden. Evtl. gibt es noch ein Problem in isPassable.Könntest du hier bitte einmal drüberschauen
Sorry, das war etwas falsch ausgedrückt. Für length == 1 stimmt der Ablauf überein aber ab length == 2 ist er anders.while: length == 2 > 0, also wird der Schleifenrumpf ausgeführt
requiredTracks enthält currentTrack (1,1,5,1) nicht -> requiredTracks = {(5,1,8,1), (1,1,5,1)}
passed = (1,1)
length = length - position.distanceTo(passed) = length - 4 = -2
getConnection(passed, currentTrack) liefert null -> Fehler
Für mich macht da eigentlich gar nichts Sinn: getConnection müsste in der zweiten Iteration null liefern, die Richtung (1,1) ist totaler Quatsch. Da stimmt hinten und vorne nichts. Du musst Zeile für Zeile genau schauen, welche Werte Du erwartest und was tatsächlich rauskommt.Die zweite Iteration macht für mich noch Sinn und es scheint alles zu stimmen.
Weil es keinen Track mehr gibt?!?Aber wieso sollte getConnection in der zweiten iteration null liefern?
Ja, s. #215 und #172.Dann würde ja eine exception geworfen werden.
add track (1,1) -> (5,1)
add track (1,-3) -> (1,1)
create engine steam T3 Emma 3 false true
add train 1 T3-Emma
put train 1 at (1,1) in direction 1,0
Error, directions do not match
dir
hier alles...?Was hast du bei der getConnection abgeändert, das es bei dir geklappt hat?Danke, jetzt funktioniert zumindest dieser Ablauf. Bei folgendem Ablauf sieht das allerdings noch anders aus (wenn der Zug auf ein Eckpunkt gesetzt wird):
add track (1,1) -> (5,1) add track (1,-3) -> (1,1) create engine steam T3 Emma 3 false true add train 1 T3-Emma put train 1 at (1,1) in direction 1,0 Error, directions do not match
Hier wird ein Fehler ausgegeben, obwohl der Zug aufgegleist werden soll.
Der letzte Durchgang von getPassedPoint
Anhang anzeigen 13096
Stimmt mitdir
hier alles...?
Anhang anzeigen 13097
Nein. passed liegt auf dem Track, also muss eine Komponente von dir 0 sein.Stimmt mitdir
hier alles...?
Es liegt an getPassedPoint...Also, passed wird als(1,1)
übergeben
Anhang anzeigen 13098
und dann wird mittelscurrentTrack.getDirectionTo(passed)
(1,-1)
berechnet und dir zugewiesen
Anhang anzeigen 13099
Dann hapert es wohl an currentTrack und somit an getConnection, oder?? Ich blicke hier langsam nicht mehr durch ^^
Nein, es hapert an getDirectionTo.Dann hapert es wohl an currentTrack, oder??
public Point getDirectionTo(Point passed) {
return switchedTo.equals(passed) ? toDirection(getStartPoint()) : toDirection(switchedTo);
}
Ich glaube nicht. Mit der Methode sollte bei mir alles stimmen.Es liegt an getPassedPoint...
public CartesianPoint getDirectionTo(CartesianPoint passed) {
CartesianPoint directionVectorOfTracks = null;
if(startXCoordiante == passed.getXCoordinate()) {
if(startXCoordiante < passed.getXCoordinate()) {
directionVectorOfTracks = new CartesianPoint(-1, 0);
}
else {
directionVectorOfTracks = new CartesianPoint(1, 0);
}
}
else if(startYCoordiante == passed.getYCoordinate()) {
if(startYCoordiante < passed.getYCoordinate()) {
directionVectorOfTracks = new CartesianPoint(0, -1);
}
else {
directionVectorOfTracks = new CartesianPoint(0, 1);
}
}
return directionVectorOfTracks;
}
Nein, ich habe in #205 geschrieben, dass Du den Richtungsvektor von Startpunkt -> switchTo brauchst oder umgekehrt. Du normierst ja einfach nur den StartPunkt oder switchTo.Du hast den Code doch so bestätigt, oder nicht:
Aber ein Startpunkt kann ein Endpunkt sein und genauso gut auch umgekehrt. Wie soll man da auf eindeutige Richtungsvektoren kommen
Und wie mache ich das dann am besten? Irgendwie hiermit?Nein, ich habe in #205 geschrieben, dass Du den Richtungsvektor von Startpunkt -> switchTo brauchst oder umgekehrt. Du normierst ja einfach nur den StartPunkt oder switchTo.
int firstDirComp = getStartPoint().getFirstComponent() - switchedTo.getFirstComponent();
int secondDirComp = getStartPoint().getSecondComponent() - switchedTo.getSecondComponent();
...
public CartesianPoint getDirectionTo(CartesianPoint passed) {
CartesianPoint directionVectorOfTracks = null;
if(startXCoordiante == passed.getXCoordinate()) {
if(startXCoordiante < passed.getXCoordinate()) {
directionVectorOfTracks = new CartesianPoint(-1, 0);
}
else {
directionVectorOfTracks = new CartesianPoint(1, 0);
}
}
else if(startYCoordiante == passed.getYCoordinate()) {
if(startYCoordiante < passed.getYCoordinate()) {
directionVectorOfTracks = new CartesianPoint(0, -1);
}
else {
directionVectorOfTracks = new CartesianPoint(0, 1);
}
}
return directionVectorOfTracks;
}
Am besten spendierst Du Point ein paar Methoden, damit Du den Käse nicht an jeder Ecke neu schreiben musst:Und wie mache ich das dann am besten?
public Point vectorTo(Point p) {
return new Point(p.x - x, p.y - y);
}
public Point negate() {
return new Point(-x, -y);
}
public Point toDirection() {
return new Point((int)Math.signum(x), (int)Math.signum(y));
}
Point dir = getStartPoint().vectorTo(switchedTo).toDirection();
return passed.equals(switchedTo) ? dir : dir.negate();
Wie soll die zweite Bedingung jemals true werden?!? (weiter habe ich mir die Methode nicht angesehen)Oder doch in die Richtung?
Java:public CartesianPoint getDirectionTo(CartesianPoint passed) { CartesianPoint directionVectorOfTracks = null; if(startXCoordiante == passed.getXCoordinate()) { if(startXCoordiante < passed.getXCoordinate()) {
Hast Recht. Ich habe mich dazu verleiten lassen einen Beispiel case auf die Allgemeinheit anzuwenden und das ging richtig brutal nach hinten losWie soll die zweite Bedingung jemals true werden?!? (weiter habe ich mir die Methode nicht angesehen)
Auch nochmal vielen Dank von mirAm besten spendierst Du Point ein paar Methoden, damit Du den Käse nicht an jeder Ecke neu schreiben musst:
Java:public Point vectorTo(Point p) { return new Point(p.x - x, p.y - y); } public Point negate() { return new Point(-x, -y); }
Zusammen mit der hoffentlich bereits vorhandenen Methode aus #72 (Point#toDirection):
Java:public Point toDirection() { return new Point((int)Math.signum(x), (int)Math.signum(y)); }
kannst Du dann einfach schreiben:
Java:Point dir = getStartPoint().vectorTo(switchedTo).toDirection(); return passed.equals(switchedTo) ? dir : dir.negate();
Bearbeitung in Farbe
Immer noch denselben wie vorher.Welchen Fall prüfst du? Also welche Tracks, welchen Richtungsvektor, Punkt und welchen Zug mit welcher Länge
add track (1,1) -> (5,1)
add track (1,-3) -> (1,1)
create engine steam T3 Emma 3 false true
add train 1 T3-Emma
put train 1 at (1,1) in direction 1,0
Es Läuft auf jeden Fall etwas mit dem@mihe7
Die If-Abfrage hat das Problem behoben. Ist das so in Ordnung oder wird dadurch etwas anderes "zerstört"?Java:if (currentTrack != null) { dir = currentTrack.getDirectionTo(passed); }
getDirectionTo
schief, da es auf Horizontalen und Vertikalen Strecken funktioniert, also das Aufgleisen. Wird jedoch über eine Ecke versucht aufzugleisen, dann schmeißt er einen ErrorDas kann durchaus funktionieren, zeigt aber nicht die Idee dahinter. Es geht darum, dass die Länge an der Stelle 0 sein müsste, d. h. der ganze Block ab positioned=passed nicht mehr ausgeführt werden sollte (s. #172).Die If-Abfrage hat das Problem behoben. Ist das so in Ordnung oder wird dadurch etwas anderes "zerstört"?
dir = currentTrack.getDirectionTo(passed);
stimmt auch, weil der mir (0,-1) zurückgibt