Пример #1
0
        /// <summary>
        /// Makes the car approach the target and slow down.
        /// </summary>
        /// <param name="velocity">Current velocity of the car</param>
        /// <param name="yaw">Current relative yaw of the car</param>
        /// <param name="addedRotation">Amount of rotation (in degrees) to add</param>
        /// <param name="distanceToDestination">Distance to the destination</param>
        public void HandleApproachTarget(ref Vector velocity, ref double yaw, ref double addedRotation, ref double distanceToDestination)
        {
            // Get the current speed and rotation of the car.
            var speed    = velocity.Length;
            var rotation = MathUtil.VelocityToRotation(velocity);

            // Check if we're going too fast, have passengers or are near the destination.
            if (speed > maxTurningSpeed / 2d || Car.PassengerCount > 0 || distanceToDestination < 20)
            {
                // Check if we need to drop passengers off.
                if (Car.PassengerCount > 0 && /*speed < 0.05 && */ speed > 0)
                {
                    var distance = Car.DistanceTraveled - Car.PassengersBoardDistance;
                    var price    = GPSSystem.CalculatePrice(distance);
                    App.Console.Print($"[C{Car.Id}] Charged €{price:F2} for {distance:F1} units", Colors.Blue);

                    App.Console.Print($"[C{Car.Id}] Dropping customers", Colors.Blue);
                    var passenger = Car.Passengers[0];
                    TripEnd?.Invoke(this, new TripEventArgs(passenger.Group, passenger.Building.Location, Car.Location, Car));
                    Car.Passengers.Clear();
                    MainScreen.AILoop.Unsubscribe(Update);
                }

                // Slow down the car.
                velocity = speed > 0.05
                    ? Vector.Add(velocity, CalculateDeccelerationVector(velocity))
                    : new Vector();
            }

            // Get the target and current location.
            var destination = Car.Destination.Location;
            var location    = Car.Location;

            // Calculate the angle between the car and the target.
            var sub = new Vector(
                destination.X - location.X,
                destination.Y - location.Y
                );

            sub.Normalize();
            var angle = Vector.AngleBetween(rotation, sub);

            // If we need to go to the right and are able to, do so.
            if (angle > 0)
            {
                if (yaw > -maxInLaneRotation)
                {
                    addedRotation -= rotationSpeed;
                }
            }
            // If we need to go to the left and are able to, do so.
            else
            {
                if (yaw < maxInLaneRotation)
                {
                    addedRotation += rotationSpeed;
                }
            }
        }
Пример #2
0
        /*
         * All the Handle functions take references to variable from the Update function.
         * They will modify these variables to change behaviour of the car. The value of
         * these variables shouldn't be overwritten, but only changed (adding, multiplying, etc)
         */

        /// <summary>
        /// Makes the car turn on an intersection towards the target.
        /// </summary>
        /// <param name="velocity">Current velocity of the car</param>
        /// <param name="yaw">Current relative yaw of the car</param>
        /// <param name="addedRotation">Amount of rotation (in degrees) to add</param>
        public void HandleTurn(ref Vector velocity, ref double yaw, ref double addedRotation)
        {
            // Get the current speed and rotation of the car.
            var speed        = velocity.Length;
            var rotation     = MathUtil.VelocityToRotation(velocity);
            var intersection = Car.CurrentIntersection;

            // If we're going too fast to turn, slow down.
            if (speed > maxTurningSpeed)
            {
                velocity = Vector.Add(velocity, CalculateDeccelerationVector(velocity));
            }

            // If we're not on the intersection yet, just keep driving straight.
            if (intersection == null)
            {
                HandleStayInLane(ref velocity, ref yaw, ref addedRotation);
                return;
            }

            // Get the target and current location.
            var target   = Car.CurrentTarget;
            var location = Car.Location;

            // Calculate the angle between the car and the target.
            var targetAngle = new Vector(
                target.X - location.X,
                target.Y - location.Y
                );
            var angle = Vector.AngleBetween(rotation, targetAngle);

            if (angle < 0)
            {
                angle += 360;
            }

            // If the angle is more than 225 degrees (-90 - 45), rotate to the left.
            if (angle > 225 && angle < 315)
            {
                // If we're not turning around, slowly turn left.
                if (!flipping)
                {
                    addedRotation += rotationSpeed * 0.8;
                }
                // If we are turning around, keep steering steeply left.
                else
                {
                    addedRotation += rotationSpeed * 6;
                }
            }
            // If the angle is more than 135 degrees (180 - 45), turn around.
            else if (angle > 135 && angle < 315)
            {
                if (!flipping)
                {
                    flipping = true;
                    App.Console.Print($"[C{Car.Id}] Initiating turn-around", Colors.Blue);
                }

                addedRotation += rotationSpeed * 6;
            }
            // If the angle is more than 45 degrees (90 - 45), rotate to the right.
            else if (angle > 45 && angle < 315)
            {
                addedRotation -= rotationSpeed * 6;
            }
            // Otherwise, keep going straight.
            else
            {
                addedRotation = yaw < 0 ? rotationSpeed : -rotationSpeed;
            }
        }
Пример #3
0
 public static double Angle(Vector v1, Vector v2)
 {
     return(Vector.AngleBetween(v1, v2));
 }