/// <summary>
        /// Ermittelt, wie weit wir uns vertikal entlang einer Seite des getroffenen Hindernisses 
        /// bewegen können.
        /// </summary>
        /// <param name="kollision">Das aktuelle Hindernis, das wir an der Seite getroffen haben.</param>
        /// <returns>Der vertikale Abstand, den wir uns noch bewegen dürfen.</returns>
        private GenaueZahl ErstesVertikalesHindernisFinden( Hindernis kollision )
        {
            // Die vertikale Achse am Ende der aktuellen Bewegung
            var schritt = kollision.SchrittweiteBisZurKollision.Value;
            var achse = Bereich.Erzeugen( schritt.Breite, schritt.Höhe, GenaueZahl.Null, VolleStrecke.Höhe );

            // Mit Ausnahme des bereits bekannten Hindernisses alle Hindernisse, die diese Achse schneiden
            var hindernisseAufDerAchse =
                m_hindernisse
                    .Where( hindernis => !ReferenceEquals( hindernis, kollision ) )
                    .Where( hindernis => hindernis.Bereich.ÜberschneidetSichMit( achse ) );

            // Wir wollen uns maximal bis zum Ende des Hindernisses bewegen
            var vertialesEndeDesHindernisses = kollision.Bereich.GrößteVertikalePosition;

            // Wenn nichts im Weg steht, verwenden wir diesen Abstand
            var erstesHindernisAufDerAchse = BestesHindernisFinden( hindernisseAufDerAchse, hindernis => hindernis.Bereich.KleinsteVertikalePosition );
            if (erstesHindernisAufDerAchse == null)
                return vertialesEndeDesHindernisses;

            // Wenn etwas im Weg steht und wir eher darauf treffen, so wird der freie Weg entsprechend reduziert
            var vertikalesEnde = erstesHindernisAufDerAchse.Bereich.KleinsteVertikalePosition;
            if (vertikalesEnde < vertialesEndeDesHindernisses)
                return vertikalesEnde;

            // Ansonsten bleibt alles beim Alten
            return vertialesEndeDesHindernisses;
        }
        /// <summary>
        /// Nachdem ein Hindernis an der Unterseite getroffen wurde kann die Bewegung horizontal
        /// maximal bis zum Ende des Hindernisses fortgesetzt werden.
        /// </summary>
        /// <param name="kollision">Dieses Hindernis haben wir von unten getroffen.</param>
        /// <returns>Die horizontale Bewegung, die wir noch ausführen können.</returns>
        private GenaueZahl ErstesHorizontalesHindernisFinden( Hindernis kollision )
        {
            // Die horizontale Achse am Auftreffpunkt
            var schritt = kollision.SchrittweiteBisZurKollision.Value;
            var achse = Bereich.Erzeugen( schritt.Breite, schritt.Höhe, VolleStrecke.Breite, GenaueZahl.Null );

            // Mit Ausnahme des bereits bekannten Hindernisses alle Hindernisse, die diese Achse schneiden
            var hindernisseAufDerAchse =
                m_hindernisse
                    .Where( hindernis => !ReferenceEquals( hindernis, kollision ) )
                    .Where( hindernis => hindernis.Bereich.ÜberschneidetSichMit( achse ) );

            // Geplant ist es, an dem Hindernis vorbei zu ziehen
            var horizontalesEndeDerBewegung = kollision.Bereich.GrößteHorizontalePosition;

            // Wenn nichts im Weg steht machen wir das so
            var erstesHindernisAufDerAchse = BestesHindernisFinden( hindernisseAufDerAchse, hindernis => hindernis.Bereich.KleinsteHorizontalePosition );
            if (erstesHindernisAufDerAchse == null)
                return horizontalesEndeDerBewegung;

            // Liegt das Hindernis näher als das geplante Ende der Bewegung, so müssen wir früher aufhören
            var horizontalesEnde = erstesHindernisAufDerAchse.Bereich.KleinsteHorizontalePosition;
            if (horizontalesEnde < horizontalesEndeDerBewegung)
                return horizontalesEnde;

            // Wir können den vollen Weg wie geplant nutzen
            return horizontalesEndeDerBewegung;
        }