/// <summary> /// we have three lanes per segments. the index should be 1,2,3. ONLY. /// </summary> /// <param name="lindex"></param> public void ChangeLaneRandomly() { Dispatcher.Invoke((Action) delegate { int lanConut = CurrentLane.MyRoadSegment.LanesCount; if (lanConut > 2) { RoadSegment rs = CurrentLane.MyRoadSegment; LaneUi prevLane = CurrentLane; LaneUi newlane = null; if (prevLane.LaneDirection == Direction.N) { newlane = rs.Lanes[LaneIndex.RandomLaneIndex.North(rs.LanesCount)]; prevLane.LaneVehicleAndQueue.RemoveFromLane(this); this.CurrentLane = newlane; this.Margin = new Thickness(newlane.MyCenterLeft, this.Margin.Top, 0, 0); this.SetVehicleDirection(Direction.N); } else if (prevLane.LaneDirection == Direction.S) { newlane = rs.Lanes[LaneIndex.RandomLaneIndex.South(rs.LanesCount)]; prevLane.LaneVehicleAndQueue.RemoveFromLane(this); this.CurrentLane = newlane; this.Margin = new Thickness(newlane.MyCenterLeft, this.Margin.Top, 0, 0); this.SetVehicleDirection(Direction.S); } else if (prevLane.LaneDirection == Direction.E) { newlane = rs.Lanes[LaneIndex.RandomLaneIndex.East(rs.LanesCount)]; prevLane.LaneVehicleAndQueue.RemoveFromLane(this); this.CurrentLane = newlane; this.Margin = new Thickness(this.Margin.Left, newlane.MyCenterTop, 0, 0); this.SetVehicleDirection(Direction.E); } else if (prevLane.LaneDirection == Direction.W) { newlane = rs.Lanes[LaneIndex.RandomLaneIndex.West(rs.LanesCount)]; prevLane.LaneVehicleAndQueue.RemoveFromLane(this); this.CurrentLane = newlane; this.Margin = new Thickness(this.Margin.Left, newlane.MyCenterTop, 0, 0); this.SetVehicleDirection(Direction.W); } // change my speed to random. double instanceSpeed = Computations.GetTimeIntervalInSecond(Computations.RandomSpeedkmh(CurrentLane.MyRoadSegment)); // slow the speed. InstantaneousSpeed = instanceSpeed; // display: prevLane._MainWindow.Dispatcher.Invoke(new Action(() => prevLane.lbl_info.Text = prevLane.LaneVehicleAndQueue.CountInLane.ToString()), DispatcherPriority.Send); } }); }
double AllowToChangeLaneDistance = 25; // when the distance to the junction is x, then its not allowed to change the lane. /// <summary> /// move the vechile. /// </summary> public void StartMove() { Dispatcher.Invoke((Action) delegate { VehicleUi infrontVehicle = CurrentLane.LaneVehicleAndQueue.GetMyFrontVehicle(this); // get in the front. showInfo(Settings.Default.DisplayInfoFlag); // show flage. // info which should be disply. double headingDistance = RemianDistanceToHeadingJunction; // to north: if (VehicleDirection == Direction.N) { if (headingDistance > 0) { double marTop = this.Margin.Top; marTop -= 1; Dispatcher.Invoke(new Action(() => Margin = new Thickness(Margin.Left, marTop, 0, 0)), DispatcherPriority.Send); // start decrease the speed according to the heading distance toward the jucntion. if (headingDistance <= SlowDownDistance) { double instanceSpeed = Computations.GetTimeIntervalInSecond(headingDistance); // slow the speed. InstantaneousSpeed = instanceSpeed; } // if has vechile in front: the behind vehicle should change the speed to or change the lane if possible. if (infrontVehicle != null) { //: if still allowed to change the lane then go ahead. if not then the behind vechile should lower its speed. if (headingDistance > AllowToChangeLaneDistance) { ChangeLaneRandomly(); } else { // not allowd to change the lane. // double fronVspeed = 5; InstantaneousSpeed = infrontVehicle.InstantaneousSpeed * SpeedDisPercentage; } } // change the lane randomnlly when v is in the middlel of the segment. if (marTop < CurrentLane.MyRoadSegment.Midpoint) { double half = CurrentLane.MyRoadSegment.Height / 2; if (headingDistance > half) { if (!ChangeLaneFlage) { ChangeLaneRandomly(); ChangeLaneFlage = true; } } } if (headingDistance < LineUpInJunctionDistance) { CurrentLane.LaneVehicleAndQueue.Enqueue(this); // add to the queue. } } } else if (VehicleDirection == Direction.S) { if (headingDistance > 0) { double marTop = this.Margin.Top; marTop += 1; // Margin = new Thickness(Margin.Left, marTop, 0, 0); Dispatcher.Invoke(new Action(() => Margin = new Thickness(Margin.Left, marTop, 0, 0)), DispatcherPriority.Send); if (headingDistance <= SlowDownDistance) { double instanceSpeed = Computations.GetTimeIntervalInSecond(headingDistance); // slow the speed. InstantaneousSpeed = instanceSpeed; } if (infrontVehicle != null) { //: if still allowed to change the lane then go ahead. if not then the behind vechile should lower its speed. if (headingDistance > AllowToChangeLaneDistance) { ChangeLaneRandomly(); } else { InstantaneousSpeed = infrontVehicle.InstantaneousSpeed * SpeedDisPercentage; } } if (marTop > CurrentLane.MyRoadSegment.Midpoint) { double half = CurrentLane.MyRoadSegment.Height / 2; if (headingDistance > half) { if (!ChangeLaneFlage) { ChangeLaneRandomly(); ChangeLaneFlage = true; } } } if (headingDistance < LineUpInJunctionDistance) { CurrentLane.LaneVehicleAndQueue.Enqueue(this); // add to the queue. } } } else if (VehicleDirection == Direction.E) { if (headingDistance > 0) { double marLeft = Margin.Left; double marTop = Margin.Top; marLeft += 1; // Margin = new Thickness(marLeft, marTop, 0, 0); Dispatcher.Invoke(new Action(() => Margin = new Thickness(marLeft, marTop, 0, 0)), DispatcherPriority.Send); if (headingDistance <= SlowDownDistance) { double instanceSpeed = Computations.GetTimeIntervalInSecond(headingDistance); // slow the speed. InstantaneousSpeed = instanceSpeed; } if (infrontVehicle != null) { //: if still allowed to change the lane then go ahead. if not then the behind vechile should lower its speed. if (headingDistance > AllowToChangeLaneDistance) { ChangeLaneRandomly(); } else { InstantaneousSpeed = infrontVehicle.InstantaneousSpeed * SpeedDisPercentage; } } if (marLeft > CurrentLane.MyRoadSegment.Midpoint) { double half = CurrentLane.MyRoadSegment.Width / 2; if (headingDistance > half) { if (!ChangeLaneFlage) { ChangeLaneRandomly(); ChangeLaneFlage = true; } } } if (headingDistance < LineUpInJunctionDistance) { CurrentLane.LaneVehicleAndQueue.Enqueue(this); // add to the queue. } } } else if (VehicleDirection == Direction.W) { if (headingDistance > 0) { double marLeft = Margin.Left; double marTop = Margin.Top; marLeft -= 1; // Margin = new Thickness(marLeft, marTop, 0, 0); Dispatcher.Invoke(new Action(() => Margin = new Thickness(marLeft, marTop, 0, 0)), DispatcherPriority.Send); if (headingDistance <= SlowDownDistance) { double instanceSpeed = Computations.GetTimeIntervalInSecond(headingDistance); // slow the speed. InstantaneousSpeed = instanceSpeed; } if (infrontVehicle != null) { //: if still allowed to change the lane then go ahead. if not then the behind vechile should lower its speed. if (headingDistance > AllowToChangeLaneDistance) { ChangeLaneRandomly(); } else { InstantaneousSpeed = infrontVehicle.InstantaneousSpeed * SpeedDisPercentage; } } if (marLeft < CurrentLane.MyRoadSegment.Midpoint) { double half = CurrentLane.MyRoadSegment.Width / 2; if (headingDistance > half) { if (!ChangeLaneFlage) { ChangeLaneRandomly(); ChangeLaneFlage = true; } } } if (headingDistance < LineUpInJunctionDistance) { CurrentLane.LaneVehicleAndQueue.Enqueue(this); // add to the queue. } } } }); }