Beispiel #1
0
        /// <summary>
        /// Gibt eine Liste mit allen Schnittpunkten von nc mit anderen existierenden NodeConnections
        /// </summary>
        /// <param name="nc">zu untersuchende NodeConnection</param>
        /// <param name="tolerance">Toleranz (maximale Kantenlänge der Boundingboxen)</param>
        /// <returns>Eine Liste mit Intersection Objekten die leer ist, falls keine Schnittpunkte existieren</returns>
        private List<Intersection> CalculateIntersections(NodeConnection nc, double tolerance)
        {
            List<Intersection> toReturn = new List<Intersection>();

            foreach (NodeConnection nc2 in connections)
                {
                if (nc != nc2)
                    {
                    if (   (nc.startNode.networkLayer == nc.endNode.networkLayer && (nc2.startNode.networkLayer == nc.startNode.networkLayer || nc2.endNode.networkLayer == nc.endNode.networkLayer))
                        || (nc.startNode.networkLayer != nc.endNode.networkLayer && (   nc2.startNode.networkLayer == nc.startNode.networkLayer
                                                                                     || nc2.startNode.networkLayer == nc.endNode.networkLayer
                                                                                     || nc2.endNode.networkLayer == nc.startNode.networkLayer
                                                                                     || nc2.endNode.networkLayer == nc.endNode.networkLayer)))
                        {
                        // Zeitparameterpaare ermitteln
                        List<Pair<double>> intersectionTimes = CalculateIntersections(nc.lineSegment, nc2.lineSegment, 0d, 1d, 0d, 1d, tolerance, nc.lineSegment, nc2.lineSegment);
                        if (intersectionTimes != null)
                            {
                            // Intersections erstellen
                            foreach (Pair<double> p in intersectionTimes)
                                {
                                toReturn.Add(new Intersection(nc, nc2, p.Left, p.Right));
                                }
                            }
                        }
                    }
                }

            return toReturn;
        }
Beispiel #2
0
        /// <summary>
        /// Standardkonstruktor
        /// Erstellt ein neues Intersection Objekt
        /// Die Parameter sollten so gewählt sein, dass _aConnection.lineSegment.AtTime(_aTime) ~ _bConnection.lineSegment.AtTime(_bTime)
        /// </summary>
        /// <param name="_aConnection">NodeConnection A</param>
        /// <param name="_bConnection">NodeConnection B</param>
        /// <param name="_aTime">Zeitpunkt des Schnittpunktes an NodeConnection A</param>
        /// <param name="_bTime">Zeitpunkt des Schnittpunktes an NodeConnection B</param>
        public Intersection(NodeConnection _aConnection, NodeConnection _bConnection, double _aTime, double _bTime)
        {
            this._aConnection = _aConnection;
            this._bConnection = _bConnection;
            this._aTime = _aTime;
            this._bTime = _bTime;

            const double stepSize = 8;
            double distance = 0;
            double aPos = aArcPosition - distance;
            double bPos = bArcPosition - distance;

            while (   Vector2.GetDistance(_aConnection.lineSegment.AtPosition(aPos), _bConnection.lineSegment.AtPosition(bPos)) < 22
                   && aPos > 0 && bPos > 0)
                {
                aPos -= stepSize;
                bPos -= stepSize;
                distance += stepSize;
                }
            _frontWaitingDistance = distance;

            distance = 0;
            aPos = aArcPosition + distance;
            bPos = bArcPosition + distance;
            while (Vector2.GetDistance(_aConnection.lineSegment.AtPosition(aPos), _bConnection.lineSegment.AtPosition(bPos)) < 22
                   && aPos < _aConnection.lineSegment.length && bPos < _bConnection.lineSegment.length)
                {
                aPos += stepSize;
                bPos += stepSize;
                distance += stepSize;
                }
            _rearWaitingDistance = distance;
        }
Beispiel #3
0
        /// <summary>
        /// Aktualisiert die NodeConnection ncToUpdate
        /// (Bezierkurve neu berechnen, etc.)
        /// </summary>
        /// <param name="ncToUpdate">zu aktualisierende NodeConnection</param>
        public void UpdateNodeConnection(NodeConnection ncToUpdate)
        {
            ncToUpdate.lineSegment = null;
            ncToUpdate.lineSegment = new LineSegment(0, ncToUpdate.startNode.position, ncToUpdate.startNode.outSlopeAbs, ncToUpdate.endNode.inSlopeAbs, ncToUpdate.endNode.position);
            FindIntersections(ncToUpdate);

            if (ncToUpdate.enableIncomingLineChange)
                {
                // TODO:	diese Lösung ist viel zu unperformant! Da muss was anderes her.

                /*
                RemoveLineChangePoints(ncToUpdate, false, true);
                foreach (NodeConnection nc in m_connections)
                    {
                    if (nc.enableOutgoingLineChange)
                        {
                        FindLineChangePoints(nc, Constants.maxDistanceToLineChangePoint, Constants.maxDistanceToParallelConnection);
                        }
                    }*/
                }
            else
                {
                // TODO: überlegen, ob hier wirklich nichts gemacht werden muss
                }

            if (ncToUpdate.enableOutgoingLineChange && (ncToUpdate.carsAllowed || ncToUpdate.busAllowed))
                {
                RemoveLineChangePoints(ncToUpdate,true, false);
                FindLineChangePoints(ncToUpdate, Constants.maxDistanceToLineChangePoint, Constants.maxDistanceToParallelConnection);
                }
            else
                {
                // TODO: überlegen, ob hier wirklich nichts gemacht werden muss
                }

            InvalidateNodeBounds();
        }
Beispiel #4
0
			/// <summary>
			/// erstellt eine SpecificPosition mittels NodeConnection und Zeitparameter
			/// </summary>
			/// <param name="nc">NodeConnection</param>
			/// <param name="time">Zeitparameter auf der NodeConnection</param>
			public SpecificPosition(NodeConnection nc, double time)
				{
				this.nc = nc;
				this.time = time;
				this.arcPosition = nc.lineSegment.TimeToArcPosition(time);
				}
Beispiel #5
0
		/// <summary>
		/// entfernt alle LineChangePoints und LineChangeIntervals zur NodeConnection nc
		/// </summary>
		/// <param name="nc">Ziel-NodeConnection der zu löschenden LineChangePoints</param>
		public void RemoveAllLineChangePointsTo(NodeConnection nc)
			{
			for (int i = 0; i < _lineChangePoints.Count; i++)
				{
				if ((_lineChangePoints[i].otherStart.nc == nc) || (_lineChangePoints[i].target.nc == nc))
					{
					_lineChangePoints.RemoveAt(i);
					i--;
					}
				}

			_lineChangeIntervals.Remove(nc.endNode.hashcode);
			_viaLineChangeReachableNodes.Remove(nc.endNode);
			}
Beispiel #6
0
        /// <summary>
        /// Berechnet alle Schnittpunkte von nc mit anderen existierenden NodeConnections und meldet sie an
        /// </summary>
        /// <param name="nc">zu untersuchende NodeConnection</param>
        public void FindIntersections(NodeConnection nc)
        {
            // erstmal bestehende Intersections dieser NodeConnections zerstören
            for (int i = 0; i < intersections.Count; i++)
                {
                if ((intersections[i]._aConnection == nc) || (intersections[i]._bConnection == nc))
                    {
                    intersections[i].Dispose();
                    intersections.RemoveAt(i);
                    i--;
                    }
                }

            // jetzt können wir nach neuen Intersections suchen und diese anmelden
            List<Intersection> foundIntersections = CalculateIntersections(nc, 0.25d);
            foreach (Intersection i in foundIntersections)
                {
                i._aConnection.AddIntersection(i);
                i._bConnection.AddIntersection(i);
                intersections.Add(i);
                }
        }
Beispiel #7
0
        /// <summary>
        /// Entfernt alle LineChangePoints, die von nc ausgehen und evtl. eingehen
        /// </summary>
        /// <param name="nc">NodeConnection dessen ausgehende LineChangePoints gelöscht werden</param>
        /// <param name="removeOutgoingLineChangePoints">ausgehende LineChangePoints löschen</param>
        /// <param name="removeIncomingLineChangePoints">eingehende LineChangePoints löschen</param>
        public void RemoveLineChangePoints(NodeConnection nc, bool removeOutgoingLineChangePoints, bool removeIncomingLineChangePoints)
        {
            if (removeOutgoingLineChangePoints)
                {
                nc.ClearLineChangePoints();
                }

            if (removeIncomingLineChangePoints)
                {
                foreach (NodeConnection otherNc in _connections)
                    {
                    otherNc.RemoveAllLineChangePointsTo(nc);
                    }
                }
        }
Beispiel #8
0
 /// <summary>
 /// Gibt den Zeitpunkt des Schnittpunktes an der NodeConnection nc an
 /// </summary>
 /// <param name="nc">NodeConnection dessen Schnittpunkt-Zeitparameter zurückgegeben werden soll</param>
 /// <returns>_aTime/_bTime falls nc=_aConnection/nc=_bConnection, sonst Exception</returns>
 public double GetMyTime(NodeConnection nc)
 {
     if (_aConnection == nc)
         return _aTime;
     else if (_bConnection == nc)
         return _bTime;
     else
         throw new Exception();
 }
Beispiel #9
0
 /// <summary>
 /// Gibt die andere an der Intersection teilhabende NodeConnection zurück
 /// </summary>
 /// <param name="nc">NodeConnection die nicht zurückgegeben werden soll</param>
 /// <returns>Die NodeConnection, die sich in dieser Intersection mit nc schneidet oder null, wenn nc nicht an der Intersection teilnimmt</returns>
 public NodeConnection GetOtherNodeConnection(NodeConnection nc)
 {
     if (_aConnection == nc)
         {
         return _bConnection;
         }
     else if (_bConnection == nc)
         {
         return _aConnection;
         }
     else
         {
         return null;
         }
 }
Beispiel #10
0
 /// <summary>
 /// Gibt Bogenlängenposition des Schnittpunktes an der NodeConnection nc an
 /// </summary>
 /// <param name="nc">NodeConnection dessen Bogenlängenposition zurückgegeben werden soll</param>
 /// <returns>aArcPosition/bArcPosition falls nc=_aConnection/nc=_bConnection, sonst Exception</returns>
 public double GetMyArcPosition(NodeConnection nc)
 {
     if (_aConnection == nc)
         return aArcPosition;
     else if (_bConnection == nc)
         return bArcPosition;
     else
         throw new Exception();
 }
Beispiel #11
0
 /// <summary>
 /// Gibt den ListNode des Schnittpunktes an der NodeConnection nc an
 /// </summary>
 /// <param name="nc">NodeConnection dessen ListNode zurückgegeben werden soll</param>
 /// <returns>_aListNode/_bListNode falls nc=_aConnection/nc=_bConnection, sonst Exception</returns>
 public LinkedListNode<Intersection> GetMyListNode(NodeConnection nc)
 {
     if (_aConnection == nc)
         return _aListNode;
     else if (_bConnection == nc)
         return _bListNode;
     else
         throw new Exception();
 }
Beispiel #12
0
        /// <summary>
        /// Returns the CrossingVehicleTimes data of the given vehicle.
        /// </summary>
        /// <param name="v">Vehicle to search for (must already be registered!).</param>
        /// <param name="nc">NodeConnection the vehicle is going to use (must participate on this Intersection!).</param>
        /// <returns>The CrossingVehicleTimes data of the given vehicle.</returns>
        public CrossingVehicleTimes GetCrossingVehicleTimes(IVehicle v, NodeConnection nc)
        {
            Debug.Assert(nc == _aConnection || nc == _bConnection);

            if (nc == _aConnection)
                {
                Debug.Assert(aCrossingVehicles.ContainsKey(v));
                return aCrossingVehicles[v];
                }
            else
                {
                Debug.Assert(bCrossingVehicles.ContainsKey(v));
                return bCrossingVehicles[v];
                }
        }
Beispiel #13
0
 /// <summary>
 /// prüft ob die NodeConnection nc an der Intersection teilnimmt
 /// </summary>
 /// <param name="nc">zu prüfende NodeConnection</param>
 /// <returns>(nc == _aConnection) || (nc == _bConnection)</returns>
 public bool ContainsNodeConnection(NodeConnection nc)
 {
     return (nc == _aConnection) || (nc == _bConnection);
 }
Beispiel #14
0
        /// <summary>
        /// Calculates all interfering vehicles from registered vehicles.
        /// </summary>
        public List<CrossingVehicleTimes> CalculateInterferingVehicles(IVehicle v, NodeConnection nc)
        {
            Debug.Assert(nc == _aConnection || nc == _bConnection);

            // hopefully these are references... ;)
            List<CrossingVehicleTimes> toReturn = new List<CrossingVehicleTimes>();
            Dictionary<IVehicle, CrossingVehicleTimes> myCrossingVehicles = (nc == _aConnection ? aCrossingVehicles : bCrossingVehicles);
            Dictionary<IVehicle, CrossingVehicleTimes> otherCrossingVehicles = (nc == _aConnection ? bCrossingVehicles : aCrossingVehicles);
            CrossingVehicleTimes myCvt = myCrossingVehicles[v];

            if (_aConnection.startNode != _bConnection.startNode || (_frontWaitingDistance < aArcPosition && _frontWaitingDistance < bArcPosition))
                {
                // check each vehicle in aCrossingVehicles with each in bCrossingVehicles for interference
                foreach (KeyValuePair<IVehicle, CrossingVehicleTimes> ocv in otherCrossingVehicles)
                    {
                    if (   (!ocv.Value.willWaitInFrontOfIntersection || ocv.Value.remainingDistance < 0)
                        && myCvt.blockingTime.IntersectsTrue(ocv.Value.blockingTime))
                        {
                        toReturn.Add(ocv.Value);
                        }
                    }
                }

            return toReturn;
        }
Beispiel #15
0
 /// <summary>
 /// setzt nextNodes und prevNodes bei den an nc teilnehmenden LineNodes
 /// </summary>
 /// <param name="nc">NodeConnections die angemeldet werden soll</param>
 private void TellNodesTheirConnection(NodeConnection nc)
 {
     nc.startNode.nextConnections.Add(nc);
     nc.endNode.prevConnections.Add(nc);
 }
Beispiel #16
0
        /// <summary>
        /// Registers that the given vehicle is going to cross this intersection via the given NodeConnection.
        /// </summary>
        /// <param name="v">Vehicle to cross intersection (must not be registered yet!).</param>
        /// <param name="nc">NodeConnection the vehicle is going to use (must participate on this Intersection!).</param>
        /// <param name="distance">Current distance of the vehicle to the Intersection</param>
        /// <param name="currentTime">current world time.</param>
        public void RegisterVehicle(IVehicle v, NodeConnection nc, double distance, double currentTime)
        {
            Debug.Assert(nc == _aConnection || nc == _bConnection);
            // TODO: add some safety space before and behind
            double blockingStartTime = currentTime + CalculateArrivingTime(v, distance - (_frontWaitingDistance / 2)) - v.SafetyTime/8;
            double blockingEndTime = currentTime + CalculateArrivingTime(v, distance + v.length) + v.SafetyTime/8;
            double originalArrivingTime = currentTime + v.GetTimeToCoverDistance(distance, false);

            if (nc == _aConnection)
                {
                    //if (aCrossingVehicles.ContainsKey(v))
                    //{
                        aCrossingVehicles.Add(v, new CrossingVehicleTimes(originalArrivingTime, distance, new Interval<double>(blockingStartTime, blockingEndTime), false));
                   // }
                }
            else
                {
            //                     if (bCrossingVehicles.ContainsKey(v))
            //                     {
                        bCrossingVehicles.Add(v, new CrossingVehicleTimes(originalArrivingTime, distance, new Interval<double>(blockingStartTime, blockingEndTime), false));
                /*    }	*/
                }
        }
Beispiel #17
0
        /// <summary>
        /// stellt eine NodeConnection von from nach to her
        /// </summary>
        /// <param name="from">LineNode von dem die NodeConnection ausgehen soll</param>
        /// <param name="to">LineNode zu der die NodeConnection hingehen soll</param>
        /// <param name="priority">Priorität der Linie</param>
        /// <param name="targetVelocity">Target velocity on the NodeConnection</param>
        /// <param name="carsAllowed">Flag, ob Autos auf dieser NodeConnection erlaubt sind</param>
        /// <param name="busAllowed">Flag, ob Busse auf dieser NodeConnection erlaubt sind</param>
        /// <param name="tramAllowed">Flag, ob Straßenbahnen auf dieser NodeConnection erlaubt sind</param>
        /// <param name="enableIncomingLineChange">Flag, ob eingehende Spurwechsel erlaubt sind</param>
        /// <param name="enableOutgoingLineChange">Flag, ob ausgehende Spurchwechsel erlaubt sind</param>
        public void Connect(LineNode from, LineNode to, int priority, double targetVelocity, bool carsAllowed, bool busAllowed, bool tramAllowed, bool enableIncomingLineChange, bool enableOutgoingLineChange)
        {
            NodeConnection nc = new NodeConnection(from, to, null, priority, targetVelocity, carsAllowed, busAllowed, tramAllowed, enableIncomingLineChange, enableOutgoingLineChange);

            TellNodesTheirConnection(nc);
            UpdateNodeConnection(nc);
            ResetAverageVelocities(nc);

            connections.Add(nc);
        }
Beispiel #18
0
        /// <summary>
        /// Unregisters the given vehicle from this intersection.
        /// </summary>
        /// <param name="v">Vehicle to unregister (must already be registered!).</param>
        /// <param name="nc">NodeConnection the vehicle is going to use (must participate on this Intersection!).</param>
        public void UnregisterVehicle(IVehicle v, NodeConnection nc)
        {
            Debug.Assert(nc == _aConnection || nc == _bConnection);

            if (nc == _aConnection)
                {
                Debug.Assert(aCrossingVehicles.ContainsKey(v));
                aCrossingVehicles.Remove(v);
                }
            else
                {
                Debug.Assert(bCrossingVehicles.ContainsKey(v));
                bCrossingVehicles.Remove(v);
                }
        }
Beispiel #19
0
        /// <summary>
        /// Berechnet alle Spurwechselstellen der NodeConnection nc mit anderen NodeConnections
        /// </summary>
        /// <param name="nc">zu untersuchende NodeConnection</param>
        /// <param name="distanceBetweenChangePoints">Distanz zwischen einzelnen LineChangePoints (quasi Genauigkeit)</param>
        /// <param name="maxDistanceToOtherNodeConnection">maximale Entfernung zwischen zwei NodeConnections zwischen denen ein Spurwechsel stattfinden darf</param>
        public void FindLineChangePoints(NodeConnection nc, double distanceBetweenChangePoints, double maxDistanceToOtherNodeConnection)
        {
            nc.ClearLineChangePoints();

            double currentArcPosition = distanceBetweenChangePoints/2;
            double delta = distanceBetweenChangePoints / 4;

            /*
             * TODO: Spurwechsel funktioniert soweit so gut. Einziges Manko ist der Spurwechsel über LineNodes hinweg:
             *
             * Zum einen, können so rote Ampeln überfahren werden und zum anderen, kommt es z.T. zu sehr komischen Situationen, wo
             * das spurwechselnde Auto irgendwie denkt es sei viel weiter vorne und so mittendrin wartet und erst weiterfährt, wenn
             * das Auto 20m weiter weg ist.
             *
             * Als workaround werden jetzt doch erstmal Spurwechsel kurz vor LineNodes verboten, auch wenn das eigentlich ja gerade
             * auch ein Ziel der hübschen Spurwechsel war.
             *
             */

            // nur so lange suchen, wie die NodeConnection lang ist
            while (currentArcPosition < nc.lineSegment.length - distanceBetweenChangePoints/2)
                {
                Vector2 startl = nc.lineSegment.AtPosition(currentArcPosition - delta);
                Vector2 startr = nc.lineSegment.AtPosition(currentArcPosition + delta);

                Vector2 leftVector = nc.lineSegment.DerivateAtTime(nc.lineSegment.PosToTime(currentArcPosition - delta)).RotatedClockwise.Normalized;
                Vector2 rightVector = nc.lineSegment.DerivateAtTime(nc.lineSegment.PosToTime(currentArcPosition + delta)).RotatedCounterClockwise.Normalized;

                // Faule Implementierung:	statt Schnittpunkt Gerade/Bezierkurve zu berechnen nutzen wir vorhandenen
                //							Code und Berechnen den Schnittpunkt zwischen zwei Bezierkurven.
                // TODO:	Sollte das hier zu langsam sein, muss eben neuer optimierter Code her für die Berechnung
                //			von Schnittpunkten Gerade/Bezierkurve
                LineSegment leftLS = new LineSegment(0, startl, startl + 0.25 * maxDistanceToOtherNodeConnection * leftVector, startl + 0.75 * maxDistanceToOtherNodeConnection * leftVector, startl + maxDistanceToOtherNodeConnection * leftVector);
                LineSegment rightLS = new LineSegment(0, startr, startr + 0.25 * maxDistanceToOtherNodeConnection * rightVector, startr + 0.75 * maxDistanceToOtherNodeConnection * rightVector, startr + maxDistanceToOtherNodeConnection * rightVector);

                foreach (NodeConnection nc2 in _connections)
                    {
                    if (nc2.enableIncomingLineChange && (nc2.carsAllowed || nc2.busAllowed) && nc != nc2 && nc.startNode.networkLayer == nc2.startNode.networkLayer && nc.endNode.networkLayer == nc2.endNode.networkLayer)
                        {
                        // LINKS: Zeitparameterpaare ermitteln
                        List<Pair<double>> intersectionTimes = CalculateIntersections(leftLS, nc2.lineSegment, 0d, 1d, 0d, 1d, 8, leftLS, nc2.lineSegment);
                        if (intersectionTimes != null)
                            {
                            // Startposition
                            NodeConnection.SpecificPosition start = new NodeConnection.SpecificPosition(currentArcPosition - delta, nc);

                            // LineChangePoints erstellen
                            foreach (Pair<double> p in intersectionTimes)
                                {
                                // Winkel überprüfen
                                if (Vector2.AngleBetween(nc.lineSegment.DerivateAtTime(nc.lineSegment.PosToTime(currentArcPosition - delta)), nc2.lineSegment.DerivateAtTime(p.Right)) < Constants.maximumAngleBetweenConnectionsForLineChangePoint)
                                    {
                                    NodeConnection.SpecificPosition otherStart = new NodeConnection.SpecificPosition(nc2, p.Right);

                                    // Einfädelpunkt des Fahrzeugs bestimmen und evtl. auf nächste NodeConnection weiterverfolgen:
                                    double distance = (nc.lineSegment.AtPosition(currentArcPosition - delta) - nc2.lineSegment.AtTime(p.Right)).Abs;

                                    // Einfädelpunkt:
                                    double arcPositionTarget = nc2.lineSegment.TimeToArcPosition(p.Right) + 3 * distance;

                                    if (arcPositionTarget <= nc2.lineSegment.length)
                                        {
                                        NodeConnection.SpecificPosition target = new NodeConnection.SpecificPosition(arcPositionTarget, nc2);
                                        nc.AddLineChangePoint(new NodeConnection.LineChangePoint(start, target, otherStart));
                                        }
                                    else
                                        {
                                        double diff = arcPositionTarget - nc2.lineSegment.length;
                                        foreach (NodeConnection nextNc in nc2.endNode.nextConnections)
                                            {
                                            if (   (diff <= nextNc.lineSegment.length)
                                                && (nextNc.enableIncomingLineChange && (nextNc.carsAllowed || nextNc.busAllowed))
                                                && (nc != nextNc))
                                                {
                                                NodeConnection.SpecificPosition target = new NodeConnection.SpecificPosition(diff, nextNc);
                                                nc.AddLineChangePoint(new NodeConnection.LineChangePoint(start, target, otherStart));
                                                }
                                            }
                                        }

                                    break;
                                    }
                                }
                            }

                        // RECHTS: Zeitparameterpaare ermitteln
                        intersectionTimes = CalculateIntersections(rightLS, nc2.lineSegment, 0d, 1d, 0d, 1d, 8, leftLS, nc2.lineSegment);
                        if (intersectionTimes != null)
                            {
                            // Startposition
                            NodeConnection.SpecificPosition start = new NodeConnection.SpecificPosition(currentArcPosition + delta, nc);

                            // LineChangePoints erstellen
                            foreach (Pair<double> p in intersectionTimes)
                                {
                                // Winkel überprüfen
                                if (Vector2.AngleBetween(nc.lineSegment.DerivateAtTime(nc.lineSegment.PosToTime(currentArcPosition + delta)), nc2.lineSegment.DerivateAtTime(p.Right)) < Constants.maximumAngleBetweenConnectionsForLineChangePoint)
                                    {
                                    NodeConnection.SpecificPosition otherStart = new NodeConnection.SpecificPosition(nc2, p.Right);

                                    // Einfädelpunkt des Fahrzeugs bestimmen und evtl. auf nächste NodeConnection weiterverfolgen:
                                    double distance = (nc.lineSegment.AtPosition(currentArcPosition + delta) - nc2.lineSegment.AtTime(p.Right)).Abs;

                                    // Einfädelpunkt:
                                    double arcPositionTarget = nc2.lineSegment.TimeToArcPosition(p.Right) + 3 * distance;

                                    if (arcPositionTarget <= nc2.lineSegment.length)
                                        {
                                        NodeConnection.SpecificPosition target = new NodeConnection.SpecificPosition(arcPositionTarget, nc2);
                                        nc.AddLineChangePoint(new NodeConnection.LineChangePoint(start, target, otherStart));
                                        }
                                    else
                                        {
                                        double diff = arcPositionTarget - nc2.lineSegment.length;
                                        foreach (NodeConnection nextNc in nc2.endNode.nextConnections)
                                            {
                                            if ((diff <= nextNc.lineSegment.length)
                                                && (nextNc.enableIncomingLineChange && (nextNc.carsAllowed || nextNc.busAllowed))
                                                && (nc != nextNc))
                                                {
                                                NodeConnection.SpecificPosition target = new NodeConnection.SpecificPosition(diff, nextNc);
                                                nc.AddLineChangePoint(new NodeConnection.LineChangePoint(start, target, otherStart));
                                                }
                                            }
                                        }

                                    break;
                                    }
                                }
                            }
                        }
                    }

                currentArcPosition += distanceBetweenChangePoints;
                }
        }
Beispiel #20
0
        /// <summary>
        /// Updates the already registered vehicle v crossing on nc. 
        /// </summary>
        /// <param name="v">Vehicle to update (must already be registered!).</param>
        /// <param name="nc">NodeConnection the vehicle is going to use (must participate on this Intersection!).</param>
        /// <param name="distance">Current distance of the vehicle to the Intersection</param>
        /// <param name="currentTime">current world time.</param>
        public void UpdateVehicle(IVehicle v, NodeConnection nc, double distance, double currentTime)
        {
            Debug.Assert(nc == _aConnection || nc == _bConnection);
            // TODO: add some safety space before and behind
            double blockingStartTime = currentTime + CalculateArrivingTime(v, distance - (_frontWaitingDistance / 2)) - v.SafetyTime / 8;
            double blockingEndTime = currentTime + CalculateArrivingTime(v, distance + v.length) + v.SafetyTime / 8;

            if (nc == _aConnection)
                {
                Debug.Assert(aCrossingVehicles.ContainsKey(v));
                CrossingVehicleTimes cvt = aCrossingVehicles[v]; // CrossingVehicleTimes is a Value-Type!
                cvt.remainingDistance = distance;
                cvt.blockingTime.left = blockingStartTime;
                cvt.blockingTime.right = blockingEndTime;
                aCrossingVehicles[v] = cvt;
                }
            else
                {
                Debug.Assert(bCrossingVehicles.ContainsKey(v));
                CrossingVehicleTimes cvt = bCrossingVehicles[v]; // CrossingVehicleTimes is a Value-Type!
                cvt.remainingDistance = distance;
                cvt.blockingTime.left = blockingStartTime;
                cvt.blockingTime.right = blockingEndTime;
                bCrossingVehicles[v] = cvt;
                }
        }
Beispiel #21
0
 /// <summary>
 /// Resets the average velocities array of the given NodeConnection.
 /// </summary>
 /// <param name="nc">The NodeConection to reset</param>
 public void ResetAverageVelocities(NodeConnection nc)
 {
     int numBuckets = (int)(GlobalTime.Instance.cycleTime * GlobalTime.Instance.ticksPerSecond);
     nc.ResetStatistics(numBuckets);
 }
Beispiel #22
0
        /// <summary>
        /// Updates the already registered vehicle v crossing on nc. 
        /// </summary>
        /// <param name="v">Vehicle to update (must already be registered!).</param>
        /// <param name="nc">NodeConnection the vehicle is going to use (must participate on this Intersection!).</param>
        /// <param name="willWaitInFrontOfIntersection">Set true if vehicle will wait before intersection (and thus not cross it in the meantime).</param>
        public void UpdateVehicle(IVehicle v, NodeConnection nc, bool willWaitInFrontOfIntersection)
        {
            Debug.Assert(nc == _aConnection || nc == _bConnection);

            if (nc == _aConnection)
                {
                Debug.Assert(aCrossingVehicles.ContainsKey(v));
                CrossingVehicleTimes cvt = aCrossingVehicles[v]; // CrossingVehicleTimes is a Value-Type!
                cvt.willWaitInFrontOfIntersection = willWaitInFrontOfIntersection;
                aCrossingVehicles[v] = cvt;
                }
            else
                {
                Debug.Assert(bCrossingVehicles.ContainsKey(v));
                CrossingVehicleTimes cvt = bCrossingVehicles[v]; // CrossingVehicleTimes is a Value-Type!
                cvt.willWaitInFrontOfIntersection = willWaitInFrontOfIntersection;
                bCrossingVehicles[v] = cvt;
                }
        }
Beispiel #23
0
			/// <summary>
			/// erstellt eine SpecificPosition mittels NodeConnection und Bogenlängenposition
			/// </summary>
			/// <param name="arcPosition">Bogenlängenposition</param>
			/// <param name="nc">NodeConnection</param>
			public SpecificPosition(double arcPosition, NodeConnection nc)
				{
				this.nc = nc;
				this.arcPosition = arcPosition;
				this.time = nc.lineSegment.PosToTime(arcPosition);
				}
Beispiel #24
0
        /// <summary>
        /// Teilt die NodeConnection nc in zwei einzelne NodeConnections auf.
        /// Dabei wird in der Mitte natürlich auch ein neuer LineNode erstellt
        /// </summary>
        /// <param name="nc">aufzuteilende NodeConnection</param>
        public void SplitNodeConnection(NodeConnection nc)
        {
            LineNode startNode = nc.startNode;
            LineNode endNode = nc.endNode;

            // Mittelknoten erstellen
            LineNode middleNode = new LineNode(nc.lineSegment.subdividedFirst.p3, nc.startNode.networkLayer, false);
            middleNode.inSlopeAbs = nc.lineSegment.subdividedFirst.p2;
            middleNode.outSlopeAbs = nc.lineSegment.subdividedSecond.p1;
            nodes.Add(middleNode);

            // Anfangs- und Endknoten bearbeiten
            startNode.outSlopeAbs = nc.lineSegment.subdividedFirst.p1;
            endNode.inSlopeAbs = nc.lineSegment.subdividedSecond.p2;

            // Alte Connections lösen
            Disconnect(startNode, endNode);

            // Neue Connections bauen
            Connect(startNode, middleNode, nc.priority, nc.targetVelocity, nc.carsAllowed, nc.busAllowed, nc.tramAllowed, nc.enableIncomingLineChange, nc.enableOutgoingLineChange);
            Connect(middleNode, endNode, nc.priority, nc.targetVelocity, nc.carsAllowed, nc.busAllowed, nc.tramAllowed, nc.enableIncomingLineChange, nc.enableOutgoingLineChange);
        }
Beispiel #25
0
 /// <summary>
 /// Prüfe, ob ich auf der NodeConnection nc fahren darf
 /// </summary>
 /// <param name="nc">zu prüfende NodeConnection</param>
 /// <returns>nc.carsAllowed</returns>
 public override bool CheckNodeConnectionForSuitability(NodeConnection nc)
 {
     return nc.carsAllowed;
 }
Beispiel #26
0
 /// <summary>
 /// Standardkonstruktor
 /// </summary>
 /// <param name="nc">NodeConnection</param>
 /// <param name="i">Intersection, die an nc liegt</param>
 public SpecificIntersection(NodeConnection nc, Intersection i)
 {
     nodeConnection = nc;
     intersection = i;
 }