Tom's Bahnhof-Basteleien

Willkommen in der Transport Fever Community

Wir begrüßen euch in der Fan-Community zu den Spielen Transport Fever und Train Fever, den Wirtschaftssimulatoren von Urban Games. Die Community steht euch kostenlos zur Verfügung damit ihr euch über das Spiel austauschen und informieren könnt. Wir pflegen hier einen freundlichen und sachlichen Umgang untereinander und unser Team steht euch in allen Fragen gerne beiseite.

 

Die Registrierung und Nutzung ist selbstverständlich kostenlos.

 

Wir wünschen euch viel Spaß und hoffen auf rege Beteiligung.

Das Team der Transport-Fever Community


  • Wobei das Gameplay in "TPF" nur Chaos ist (Ballance = 0) während man in "TF" noch überlegen musste.

    Jetzt muss man halt überlegen, ob man den Bahnhof mit m oder n genug gedreht hat, um zwei "Hosenträger" nebeneinander zu haben:


    Bau nicht möglich!


    Der untere einmal mehr ge-"m"-t:



    Selbstverständlich geht bei der oberen, roten "Drehposition" der doppelte Hosenträger an den jeweils
    äußeren Gleisen, nur die Mitte halt nicht ?(


    Ganz doof läuft es, wenn man einen doppelten Hosenträger schon vor dem Bauen wählt:



    Dann grüßt der Desktop und es gibt:

    Code
    ../../src/Lib/model/edge_geometry_util.cpp:122: transport::EdgeGeometry transport::MakeSplineEdge(const CVec3f&, const CVec3f&, const CVec3f&, const CVec3f&, float): Assertion `result.length > .0f' failed.


    Wtf! Sehr motivierend... :thumbdown:

  • Das sieht danach aus das ein Edge Definition nicht richtig ist.
    D.h. nach der Berechnung eine Länge nahe 0 herauskommt. (wenn man dann dreht ist es 0).
    Entweder kommen sich zwei Punkte zu nahe, ein Richtungsvektor deiner Gleis Konstruktion ist nahe 0 oder hat komplett falschen Orientierung.

  • @eis_os, ich behaupte mal für alles nein bis auf nahe Zero.


    Der per Script gebaute Hosenträger hat die selben Kanten wie ein per Maus gebauter gleicher Länge.


    Da gibt es zwar sehr kurze Stückchen, die haut aber TpF selbst hinein. Habe keinen Einfluss darauf.
    Die Stückchen werden aber auch beim Bau per Maus produziert.


    Es gibt Drehungen/Kombinationen, die funktionieren immer.
    Es gibt selbige, die funktionieren nur per Aufrüstung nach dem Bau.
    Es gibt selbige, die "funktionieren" nur mit dem Absturz aus meinem letzten Post.


    Was das nahe 0 betrifft: vielleicht sollte UG da lieber mit (long) double statt mit float rechnen. Gebe dafür gern
    ein paar FPS während des Bauvorgangs her und ertrage da auch ruckeln.
    Bauen eines Bahnhofs mit Weichen ist sonst reine Glücksache X(


    PS: Im Anhang was zum spielen...

  • @Tom
    Wenn es wirklich an den Ungenauigkeiten beim rechnen mit floats liegt, bringt es nicht all zu viel double oder long double zu verwenden. Es erhöht höchstens die Warscheinlichkeit, dass zwei Punkte die identisch sein sollten auch identisch sind. Viel mehr würde es bringen zu prüfen, ob ein Punkt so in etwa da liegt wo ein anderer iegt. Geometrisch betrachtet prüft man also nicht, ob zwei Punkte übereinstimmen, sondern ob zwei kleine Kreise oder Quadrate, jenachdem wie man es implementiert, sich schneiden.
    float, double, long float teilen sich alle die gleichen Probleme bei berechnungen. Das liegt daran, dass für die darauf definierten Rechenoperationen (+,*) weder das Assoziativ- noch das Distributiv- und nichtmals das Kommutativgesetzt gelten.


    Das heißt, dass im allgemeinen gilt nicht:
    1. (a+b)+c = a+(b+c)
    2. a*b+a*c = a*(b+c)


    Das liegt einfach daran, dass Gleitkommazahlen nur endlich viele Bits zum speichern des Wertes haben und nach jeder Operation gerundet werden muss.


    Einfaches Beispiel:
    Wir können maximal 4 Stellen Aufschreiben und rechnen:


    (1/3)*3=0,333*3=0,999
    Aber!
    1/(3*3)=1/1=1
    Da ist es auch vollkommen egal wie viele Nachkommastellen wir zum rechnen nehmen, Die Ergebnisse werden sich immer unterscheiden!
    Im Rechner würde die Rechnung natürlich etwas anders aussehen, das Prinzip bleibt aber das Selbe.

    Dieser Beitrag wurde bereits ∞ mal editiert, zuletzt von Freahk (Vor π Minuten)

  • @Freahk, ich wollte für die unbedarften nicht auf die ganze Problematik der Fließkomma-Arithmetik und wie man sie
    "korrekt" betreibt eingehen. Sollte nur ein Hinweis sein, dass "ungenau" gerechnet und verglichen wird.


    Womit ich aber ein Problem bei der Weichengeschichte habe:
    Einen Hosenträger kann man bauen wie man möchte.
    Bei zweien aber, wobei egal ist ob sie direkt aneinander liegen oder nicht, gibt es Probleme.
    Wobei auch noch zwischen gebautem Zustand mit Aufrüstung oder Neubau unterschieden werden muss.


    So ganz kann ich das nicht bei der phösen Fließkomma-Arithmetik verorten.
    Werden da unterschiedliche Code-Pfade genutzt... ?(

  • Wirklich wissen wird es nur UG selbst... Ich wüsste aber keinen anderen Grund Gleitkommafehler dafür, dass je je nach Rotation mal geht und mal nicht.
    Btw. glaube ich auch nicht, dass UG zwei floats mit == vergleicht aber vielleicht haben die einfach nur das epsilon zu klein gewählt.
    Das Problem scheint aber jedenfalls bei der Kollisionserkennung zu liegen und nicht beim verbinden der nodes.
    Selbst wenn man sich also die tatsächlich berechneten Punkte und Reichtungsvektoren ausgeben lassen könnte, wobei ich nicht weiß ob das geht, kann es gut sein, dass alle Punkte und Richtungsvektoren korrekt sind.

    Dieser Beitrag wurde bereits ∞ mal editiert, zuletzt von Freahk (Vor π Minuten)

  • dass je je nach Rotation mal geht und mal nicht.

    Es ist nicht nur die Rotation. Bei der aktuellen Version des Standard-Plus (kommt gleich in die Webdisk für das Selbststudium) kann man
    wählen, wo die Hosenträger hinkommen (erste, mittlere, letzte Bahnsteige - ein oder zwei Stück).
    Da kann es vorkommen, dass an den letzten beide zusammen nicht gehen, jeder einzeln aber schon.


    Ich kann es drehen und wenden, wie ich will - ich entdecke keine Logik...

  • Als UG würde ich einfach eine "IF" -Abfrage einbauen und wenn dann irgendwo eine "0" auftaucht würde ich die durch den kleinsten zulässigen Wert ersetzen.
    Geht natürlich zu Lasten der Performance und ob das wirklich so einfach wäre kann ich auch nicht beurteilen weil ich den Quellcode von UG natürlich nicht kenne.

  • Durch 0 kann man nicht dividieren, das führt zum Absturz. Wenn also irgendwo eine 0 herauskommt bei einer Variable die später im Quellcode in einem Bruch auftaucht, sollte man das abfangen. Das geht z.B. mit einer Bedingungsabfrage (z.B. "if"). TPF fängt das offenbar ab, indem eine Kollisionsmeldung ausgibt - das geht aber vielleicht auch anders.
    Nur Spekulation - ich kenne den Quellcode von UG natürlich nicht).

  • Dann sollte man eine Division durch 0 aber wohl doch lieber an der entsprechenden Stelle abfangen und nicht so pauschal einfach alles was 0 ist auf einen Wert nahe 0 setzen.
    Welcher Wert nahe 0 soll das überhaupt sein? Die positive oder die negative Variante der betragsmäßig kleinsten Zahl?

    Dieser Beitrag wurde bereits ∞ mal editiert, zuletzt von Freahk (Vor π Minuten)

BlueBrixx