Nun kommt das eigentlich interessante. Die folgende Zeile beschreibt den Knopf oben links im Flash-Script, mit welchem sich die Fahrzeuge zurücksetzen lassen. Das interessanteste an dieser Zeile ist das Attribut click=”reset()” – es sorgt dafür, dass beim Klicken des Buttons die Funktion reset aufgerufen wird (deren Beschreibung folgt in der nächsten Datei):

            <s:Button label="Fahrzeuge zurücksetzen" click="reset()" />

Diese Zeile ist vergleichsweise langweilig und fügt nur den Text “Mindestabstand:” in das Script ein:

            <s:Label text="Mindestabstand:"/>

Diese Zeile ist nun wieder interessanter; sie generiert den Schieberegler mit seinen verschiedenen Informationen wie Minimalwert (minimum), Maximalwert (maximum), Schrittweite (stepSize) und Anfangswert (value). Das Attribut change=”reset()” sorgt, ähnlich wie beim oben beschriebenen Button, dafür, dass bei Änderungen am Schieberegler die Methode reset aufgerufen wird. Wichtig ist auch id=”dist”, denn hiermit wird dem Schieberegler ein Name (nämlich dist) gegeben, über welchen er später wieder angesprochen und sein Wert abgefragt werden kann:

            <s:HSlider id="dist" minimum="5" maximum="50" stepSize="5"
                 value="20" change="reset()" />

Auch diese Zeile ist eher langweilig und definiert einen weiteren Textbereich. Einigermaßen interessant ist hier vor allem das Attribut text=”{dist.value}” – es besagt, dass der anzuzeigende Text genau dem Wert des Schiebereglers entsprechen soll (wir erinnern uns: der Schieberegler trägt den Namen dist, welcher wiederum über ein Attribut value verfügt):

            <s:Label text="{dist.value}" />

Diese Zeile beendet lediglich die horizontale Gruppe.

        </s:HGroup>

Das zweite Element der vertikalen Gruppe ist ein sogenannter BorderContainer; damit ist im Grunde eine umrahmte Fläche ohne einen genau spezifizierten Anwendungszweck gemeint. Der BorderContainer verfügt über eine Breite (width) und Höhe (height), beides jeweils mit dem Wert 400, ebenso wieder über einen Namen (diesmal “panel“). Interessant sind auch die letzten beiden Attribute: mit addedToStage=”reset()” wird angegeben, dass zu Beginn der Anwendung wieder einmal die reset-Funktion aufgerufen wird; noch wichtiger ist das Attribut enterFrame=”update()” – es bewirkt, dass in jedem Frame (also jedem zu zeichnenden Bild – wir erinnern uns) die Methode update aufgerufen wird (was sie tut, werden wir auch gleich noch sehen):

        <s:BorderContainer id="panel" width="400" height="400"
                  addedToStage="reset()" enterFrame="update()" />

Der Rest der Datei ist langweilig, denn er beendet nur die vertikale Gruppe…

    </s:VGroup>

…und die Anwendung an sich:

</s:Application>

Die nächste Datei wurde bereits erwähnt; sie enthält die für die Anwendung relevante Logik, beschreibt also, was wir genau tun wollen (nämlich die Fahrzeuge auf den Bildschirm malen). Und so sieht sie aus:

Main.as:

private var radius:int = 180;
private var perimeter:int = 2 * Math.PI * radius;

private var cars:Vector.<Car> = new Vector.<Car>();

public function reset() : void {
    var car:Car;

    for each ( car in cars )
        panel.removeElement( car );

    var numCars:int = perimeter / ( dist.value + 10 );
    var degreeInc:Number = 360 / numCars;
    
    cars = new Vector.<Car>();
    
    for ( var i:int = 0; i < numCars; ++i ) {
        car = new Car();
        car.rotation = degreeInc * i;

        panel.addElement( car );        
        cars.push( car );
    }
}

public function update() : void {
    for ( var i:int = 0; i < cars.length; ++i ) {
        var car:Car = cars[i];
        var nextCar:Car =
                ( i < cars.length - 1 ) ? cars[i + 1] : cars[0];

        car.rotation += car.calcSpeed( nextCar, dist.value * 0.9 );

        var circleRot:Number = car.rotation * Math.PI / 180;
        
        car.x = 200 + Math.cos( circleRot ) * -radius;
        car.y = 200 + Math.sin( circleRot ) * -radius;
    }
}

Gehen wir auch hier die Zeilen im einzelnen durch. In den ersten drei Zeilen werden drei globale (das heißt, überall verfügbare) Variablen definiert. Die ersten beiden dienen der Visualisierung und beschreiben den Radius des Kreisen, den wir zeichnen wollen, sowie den Umfang ebenjenen Kreises (der sich, wie wir alle wissen, zu u = 2 * π * r berechnet); die dritte Variable ist schließlich eine Menge von Fahrzeugen (im Informatik-Bereich als Vector bezeichnet – bitte nicht mit dem Vektor aus der Mathematik verwechseln, denn obschon eine gewisse Ähnlichkeit der beiden Konzepte besteht, hat der Informatik-Vektor einen entscheidenden Vorteil: seine Größe ist änderbar). Was genau ein Fahrzeug (im Code mit Car bezeichnet) ist, werden wir in der nächsten Datei noch sehen:

1 / 2 / 3 / 4 / 5 / 6 / 7

Kommentare (18)

  1. #1 Dr. W
    November 18, 2012

    Überschriften sind auch wichtig.

    MFG
    Dr. W (der ein wenig mit der netten Simulation gespielt hat, nicht schlecht wäre noch eine Maßangabe das allgemeine Fortkommen betreffend)

  2. #2 MartinB
    November 18, 2012

    Schön.
    Den Titel solltest du nochmal ändern…

  3. #3 Marcus Frenkel
    November 18, 2012

    Mist. Der alte Informatiker-Fehler…Copy&Paste. Danke.

    @Dr. W
    Alle Maßangaben sind in Pixel bzw. PixelGrad pro Frame.

  4. #4 Dr. W
    November 18, 2012

    Eine Maßangabe das allgemeine Fortkommen betreffend wäre hilfreich.

    Danke für diesen schönen Artikel!

    MFG
    Dr. W

  5. #5 Marcus Frenkel
    November 18, 2012

    Was heißt “das allgemeine Fortkommen betreffend”?

  6. #6 Dr. W
    November 18, 2012

    Das Verhältnis von idealerweise zurückzulegender Strecke, wenn alle synchron fahren, zur allgemein tatsächlich zurückgelegten Strecke, den Mindestabstand und die (nicht konfigurierbare) Stabilität der Einzelgeschwindigkeiten betreffend.

    Ist anfänglich 1 und kann nur zunehmen.

  7. #7 Marcus Frenkel
    November 18, 2012

    Ah, gemeint sind angezeigte Angaben in der Simulation, also der durchschnittlich zurückgelegte Weg usw.

    Könnte man noch hinzufügen, ja; zwecks einfacherer Erklärung habe ich es in der hier veröffentlichten Version nicht integriert. Wenn Interesse besteht: die Entwicklungsumgebung ist verlinkt, der Code verfügbar, die Änderungen sind eine Sache von Minuten und auf Grund der im Blog veröffentlichten Artikel sollten hoffentlich genug Kenntnisse da sein, um das hinzubekommen. 😉

  8. #8 Dr. W
    November 18, 2012

    Loge!, der Schreiber dieser Zeilen macht das gerne selbst. BTW: Ist die Überschrift einmal verhunzt, dankt WordPress das durch Unabänderlichkeit die URL betreffend, Der wichtigste Satz somit immer der Erste. Umleitungen Pustekuchen.

  9. #9 Marcus Frenkel
    November 18, 2012

    Die URL ließe sich schon noch ändern, aber das lasse ich lieber, da ich nicht weiß, was dann alles kaputt geht…

  10. #10 haempf daempf
    Aalen
    November 19, 2012

    Ich finde die Motivation fuer dein Modell gut, und auch das Modell sieht sehr gut und plausibel aus. Aber! Ich vermisse eine Beschreibung des Modells, ohne technische Details. Mit Formeln waere das gut! Ich hab mir nur das Applet angeschaut, das ich sehr gut finde!
    Die Implementation interessiert mich nur am Rande, waer als Anhang nett.

  11. #11 libre
    Salzburg
    November 19, 2012

    Danke für den schönen Artikel.
    Zu deiner Frage bezüglich Programmkode: Ja unbedingt weiter so inklusive Erklärungen. Ermöglicht ja eigene Erweiterungen und Simulationen.

  12. #12 dd
    November 19, 2012

    Sehr schöner Artikel, weiter so und vielen Dank!
    Ich würde auch den Code dabei lassen, es ist anschaulicher (finde ich).
    Und gerade, wer das liest, dürfte an Programmiertechniken interessiert sein.

  13. #13 Dr. W
    November 21, 2012

    @Frenkel
    Aus dem Gedächtnis: WP hat keine Verwaltung der internen Verweise, d.h. es geht was kaputt. – Also: schlau!

  14. #14 miesepeter3
    November 21, 2012

    Hab ich das richtig verstanden? Wenn man die Straße sperrt, hat man wahrscheinlich keinen Stau???

  15. #15 Marcus Frenkel
    November 21, 2012

    @haempf daempf
    In Ordnung, mal sehen, ob ich im nächsten Artikel ein paar mehr Formeln unterbringen kann.

    @miesepeter3
    Die Gedankenkette zu diesem logischen Schluss muss einmal erklärt werden.

  16. #16 miesepeter3
    November 22, 2012

    @Marcus Frenkel

    Kommt darauf an, ob die Sperrung erfolgt, bevor ein Stau entsteht oder ob die Sperrung erfolgt, um den Stau nicht noch größer werden zu lassen.

    Spaß beiseite.
    Für ein störungsfreien Bewegungsablauf mit mehreren Beteiligten gibt es ein schönes Beispiel aus der Schwarmforschung. Wenn eine große Menge durch einen Engpaß muß, kommt es nicht zum Stau, wenn ein bestimmter Mindesbstand zu jedem Nachbarn eingehalten wird. Bei Menschen ist das “einmal Armeslänge”.
    Wird dieser Abstand unterschritten, gibt es den Stau und es kann Panik ausbrechen, bei der dann viele Tote und Verletzte zu beklagen sind. Hat in Versuchen mit großen Menschenmengen (z.B. Feuerschutzübungen in großen Gebäuden) bisher gut geklappt. Wurde bei der Beobachtung von großen Fisch-und Vogelschwärmen festgestellt. Hat ja irgendwie Ähnlichkeit mit Deiner Ausarbeitung.

  17. #17 Marcus Frenkel
    November 22, 2012

    @miesepeter3
    Genau. Die Wichtigkeit des Mindestabstandes wurde auch mit dem Kreisfahr-Experiment gezeigt (und in der Simulation noch einmal bestätigt).

    Übrigens gibt es noch einen zweiten Faktor, der für die Stauentstehung wichtig ist, und zwar die Reaktionsfähigkeit. Wenn man es schafft, immer exakt die Geschwindigkeit des Vordermannes einzuhalten, und zwar verzögerungsfrei, entsteht ein Stau auch nicht. Lässt sich auch in der Simulation einfach überprüfen, wenn nämlich jedes Fahrzeug exakt die Geschwindigkeit des Vorausfahrenden übernimmt – logischerweise entstehen dann keine Staus mehr. Selbst, wenn ein Fahrzeug bremsen muss, ist das kein Problem; zwar werden dann kurzfristig alle langsamer oder bleiben sogar kurz stehen, aber sobald das Hindernis beseitigt ist, geht es für alle auch gleich weiter (deswegen ist es im Stau z.B. auch wichtig, nicht nur zu schauen, was der unmittelbare Vordermann macht, sondern auch die Person 2, 3 Autos weiter vorn).

    Leider hat aber der Mensch nun einmal Reaktionszeiten oberhalb des Nanosekundenbereiches, wodurch das leider nicht zur Stauvermeidung genutzt werden kann. 😉

  18. #18 Dr. W
    November 22, 2012

    Wenn eine große Menge durch einen Engpaß muß, kommt es nicht zum Stau, wenn ein bestimmter Mindesbstand zu jedem Nachbarn eingehalten wird. Bei Menschen ist das “einmal Armeslänge”.

    Hat man ja auch unter anderem – sogar durch Handauflegen – beim Militär geübt. Und in der Tat könnte ein derartiges “Handauflegen” auch für den Verkehrsfluss nützlich sein – wenn auch ein eher IT-unterstütztes Handauflegen.

    Sicherlich werden sich Menschen wie Herr Frenkel hier irgendwann den Nutzen betreffend einbringen.

    MFG
    Dr. W (der bzgl. möglicher Fehlfunktionen eines derartigen Dienstes eher wenig Sorge hat)