コード例 #1
0
        public bool IsTowardTrafficLight(Car c)
        {
            RectangleF  rect         = GetRectangle();
            Rectangle4P r4p          = new Rectangle4P(rect);
            PointF      nearestPoint = r4p.GetNearestPointInEdge(c.Position);
            //
            double radErrMargin = Calc.DegreeToRadians(ErrorMargin);
            double angC_SB      = Calc.NormalizeRadian(Calc.GetAngleOfLineBetweenTwoPoints(c.Position, nearestPoint));

            //
            if (Calc.IsInRange(angC_SB - (radErrMargin / 2), angC_SB + (radErrMargin / 2), Calc.NormalizeRadian(c.Angle)))
            {
                return(true);
            }
            return(false);
        }
コード例 #2
0
        public bool IsAlligned(Car c)
        {
            RectangleF  rect         = GetRectangle();
            Rectangle4P r4p          = new Rectangle4P(rect);
            PointF      nearestPoint = r4p.GetNearestPointInEdge(c.Position);
            //
            double radErrMargin = Calc.DegreeToRadians(ErrorMargin);
            double angSB_C      = Calc.NormalizeRadian(Calc.GetAngleOfLineBetweenTwoPoints(nearestPoint, c.Position));
            double tAngle       = Calc.NormalizeRadian(Calc.DegreeToRadians(Angle));
            double iAngle       = Calc.NormalizeRadian(Calc.DegreeToRadians(Angle) - Math.PI);

            //
            if (Calc.IsInRange(tAngle - (radErrMargin / 2), tAngle + (radErrMargin / 2), angSB_C) ||
                Calc.IsInRange(iAngle - (radErrMargin / 2), iAngle + (radErrMargin / 2), angSB_C))
            {
                return(true);
            }
            return(false);
        }
コード例 #3
0
        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            Graphics GOut = e.Graphics;

            GOut.Clear(Color.Black);

            if (CLogic == null)
            {
                return;
            }

            foreach (PathGroup pg in CLogic.PathGroups)
            {
                Point lastBegin = new Point(0, 0);
                Point lastEnd   = new Point(0, 0);
                bool  first     = true;
                foreach (Path p in pg.Paths)
                {
                    // Draw the Path
                    GOut.DrawLine(new Pen(Color.White, 3), ProjectPoint(p.P1),
                                  ProjectPoint(p.P2));

                    // Draw the direction
                    PointF cArrow       = new PointF(p.P1.X, p.P1.Y);
                    double dirSE        = Calc.GetAngleOfLineBetweenTwoPoints(p.P1, p.P2);
                    Color  lineColor    = Color.FromArgb(100, 255, 255, 255);
                    double inverseAngle = dirSE;
                    if (p.Direction == true)
                    {
                        inverseAngle -= Math.PI;
                    }
                    float diffAngle = 20.00f; // IN DEGREE
                    float lineSize  = 20.00f;
                    float distSE    = Calc.Modulus(Calc.Magnitude(p.P1, p.P2));
                    float distMagn  = 30.0f;
                    while (true)
                    {
                        if (Calc.Modulus(Calc.Magnitude(cArrow, p.P1)) > distSE)
                        {
                            break;
                        }
                        //
                        double angleP1 = inverseAngle - Calc.DegreeToRadians(diffAngle);
                        double angleP2 = inverseAngle + Calc.DegreeToRadians(diffAngle);
                        PointF p1      = new PointF((float)(cArrow.X - (Math.Cos(angleP1) * lineSize)),
                                                    (float)(cArrow.Y - (Math.Sin(angleP1) * lineSize)));
                        PointF p2 = new PointF((float)(cArrow.X - (Math.Cos(angleP2) * lineSize)),
                                               (float)(cArrow.Y - (Math.Sin(angleP2) * lineSize)));
                        //
                        GOut.DrawLine(new Pen(lineColor), ProjectPoint(Point.Round(cArrow)), ProjectPoint(Point.Round(p1)));
                        GOut.DrawLine(new Pen(lineColor), ProjectPoint(Point.Round(cArrow)), ProjectPoint(Point.Round(p2)));
                        //
                        cArrow.X += (float)(Math.Cos(dirSE) * distMagn);
                        cArrow.Y += (float)(Math.Sin(dirSE) * distMagn);
                    }

                    // Draw the line that belongs the pathgroup
                    if (first)
                    {
                        first = false;
                    }
                    else
                    {
                        GOut.DrawLine(new Pen(Color.Gray), ProjectPoint(lastBegin),
                                      ProjectPoint(p.P1));
                        GOut.DrawLine(new Pen(Color.Gray), ProjectPoint(lastEnd),
                                      ProjectPoint(p.P2));
                    }
                    //
                    lastBegin = p.P1;
                    lastEnd   = p.P2;
                }
            }

            foreach (SpeedBump sb in CLogic.SpeedBumps)
            {
                GOut.FillRectangle(new SolidBrush(Color.Orange), ProjectRectangle(Rectangle.Round(sb.GetRectangle())));
            }

            foreach (TrafficLightGroup tlg in CLogic.TrafficLights)
            {
                foreach (TrafficLight tl in tlg.TLs)
                {
                    GOut.FillRectangle(new SolidBrush(tl.GetColor()), ProjectRectangle(Rectangle.Round(tl.GetRectangle())));
                }
            }

            foreach (PathIntersectionData pid in CLogic.PathIntersections)
            {
                if (pid.IntersectionData.Intersects)
                {
                    GOut.FillPie(new SolidBrush(Color.Red), new Rectangle(ProjectPoint(new Point((int)(pid.IntersectionPoint.X - 3), (int)(pid.IntersectionPoint.Y - 3))), new Size(6, 6)), 0, 360);
                }
            }

            foreach (Car c in CLogic.Cars)
            {
                // Draw the rectangle
                Point     projectedPoint = ProjectPoint(Point.Round(c.Position));
                Size      projectedSize  = ProjectSize(c.Size);
                Rectangle carRect        = new Rectangle((int)(projectedPoint.X - (projectedSize.Width / 2)),
                                                         (int)(projectedPoint.Y - (projectedSize.Height / 2)),
                                                         projectedSize.Width, projectedSize.Height);
                GOut.FillRectangle(new SolidBrush(c.Color), carRect);

                // Draw the FOV
                float  lineSize     = 30.0f;
                double halfAngleRad = Calc.DegreeToRadians(c.FOV / 2);
                double p1Angle      = c.Angle - halfAngleRad;
                double p2Angle      = c.Angle + halfAngleRad;
                PointF p1Rad        = new PointF((float)(c.Position.X + (Math.Cos(p1Angle) * lineSize)), (float)(c.Position.Y + (Math.Sin(p1Angle) * lineSize)));
                PointF p2Rad        = new PointF((float)(c.Position.X + (Math.Cos(p2Angle) * lineSize)), (float)(c.Position.Y + (Math.Sin(p2Angle) * lineSize)));
                GOut.DrawLine(new Pen(Color.FromArgb(100, 255, 255, 255)), ProjectPoint(Point.Round(c.Position)), ProjectPoint(Point.Round(p1Rad)));
                GOut.DrawLine(new Pen(Color.FromArgb(100, 255, 255, 255)), ProjectPoint(Point.Round(c.Position)), ProjectPoint(Point.Round(p2Rad)));

                // Draw the Id
                Font  idFont     = new System.Drawing.Font("Consolas", 12);
                SizeF stringSize = GOut.MeasureString(c.Id.ToString(), idFont);
                GOut.DrawString(c.Id.ToString(), idFont, new SolidBrush(Color.White),
                                new PointF(carRect.X + ((carRect.Width / 2) - (stringSize.Width / 2)), carRect.Y - stringSize.Height));
            }
        }
コード例 #4
0
ファイル: Car.cs プロジェクト: felipedurar/TrafficSimulator
        public virtual void Update()
        {
            // Decrease Car Speed
            Speed -= 0.01f;
            if (Speed < 0.00f)
            {
                Speed = 0.00f;
            }

            // Secure Speed Distance
            SecureDistance = (Speed * SDRatio) + MSecureDistance;

            // Position Changes
            PointF IPos = new PointF(0.00f, 0.00f);

            ObjectiveSpeed = MaximumSpeed;

            // AI
            if (!UserControl)
            {
                IPos = DoAI();
            }

            // User Control
            double       UpAngleRad   = Calc.DegreeToRadians(270);
            const double _90degreeRad = (Math.PI / 2);

            if (UserControl)
            {
                if (Control.IsSomeButtonPressed())
                {
                    SetObjectiveSpeed(MaximumSpeed);
                }
                else
                {
                    SetObjectiveSpeed(0.00f);
                }
                //
                if (Control.Up)
                {
                    double angNormalized = Calc.NormalizeRadian(UpAngleRad);
                    IPos.X += (float)(Math.Cos(angNormalized) * Speed);
                    IPos.Y += (float)(Math.Sin(angNormalized) * Speed);
                }
                if (Control.Right)
                {
                    double angNormalized = Calc.NormalizeRadian(UpAngleRad + _90degreeRad);
                    IPos.X += (float)(Math.Cos(angNormalized) * Speed);
                    IPos.Y += (float)(Math.Sin(angNormalized) * Speed);
                }
                if (Control.Down)
                {
                    double angNormalized = Calc.NormalizeRadian(UpAngleRad + (2 * _90degreeRad));
                    IPos.X += (float)(Math.Cos(angNormalized) * Speed);
                    IPos.Y += (float)(Math.Sin(angNormalized) * Speed);
                }
                if (Control.Left)
                {
                    double angNormalized = Calc.NormalizeRadian(UpAngleRad + (3 * _90degreeRad));
                    IPos.X += (float)(Math.Cos(angNormalized) * Speed);
                    IPos.Y += (float)(Math.Sin(angNormalized) * Speed);
                }
            }

            // Car Operations
            for (int C = 0; C < CLogic.Cars.Count; C++)
            {
                if (CLogic.Cars[C].Id != Id)
                {
                    // Current Car
                    Car cCar = CLogic.Cars[C];

                    // Test Colisions
                    if (GetRectangle().IntersectsWith(cCar.GetRectangle()))
                    {
                        Kill();
                    }
                }
            }

            // Speed Balance
            if (Speed < ObjectiveSpeed)
            {
                SpeedUp();
            }
            else if (Speed > ObjectiveSpeed)
            {
                Break();
            }

            // Work?
            if (!Working)
            {
                IPos = new PointF(0, 0);
            }

            // Increase Pos
            Position.X += IPos.X;
            Position.Y += IPos.Y;

            // Calc Angle
            if (Point.Round(LastPosition) != Point.Round(Position))
            {
                Angle = Calc.GetAngleOfLineBetweenTwoPoints(LastPosition, Position);
            }

            // Store the last position
            LastPosition = new PointF(Position.X, Position.Y);
        }
コード例 #5
0
ファイル: Car.cs プロジェクト: felipedurar/TrafficSimulator
        public PointF DoAI()
        {
            // IPos
            PointF IPos = new PointF(0.00f, 0.00f);

            // Immediate Tasks
            bool hasImmediate = ImmediateTasks.Count != 0;

            if (hasImmediate)
            {
                Task   t    = ImmediateTasks.Peek();
                PointF diff = DoTask(t);
                IPos.X += diff.X;
                IPos.Y += diff.Y;
            }


            // Solve Tasks Queue
            if (TasksQueue.Count > 0 && !hasImmediate)
            {
                Task   t    = TasksQueue.Peek();
                PointF diff = DoTask(t);
                IPos.X += diff.X;
                IPos.Y += diff.Y;
            }

            // Nomadic Mode
            if (Nomadic)
            {
                Path cp = GetBelongingPath();
                if (cp != null)
                {
                    if (TasksQueue.Count == 0 && !hasImmediate)
                    {
                        PointF endOfPath = cp.GetPathCornerBasedOnDirection();
                        float  dist      = Calc.Modulus(Calc.Magnitude(endOfPath, Position));
                        if (dist < cp.ErrorMargin)
                        {
                            Path   ip            = cp.ParentPathGroup.GetWayWithDir(!cp.Direction);
                            PointF nearestCorner = ip.GetNearestCorner(Position);
                            Task   t             = CreateTask(nearestCorner, TaskType.Queue);
                            EnqueueTask(t);
                        }
                        else
                        {
                            //Task t = CreateTask(endOfPath, TaskType.Immediate);
                            //ImmediateTasks.Push(t);
                            //
                            Task t = CreateTask(endOfPath, TaskType.Queue);
                            EnqueueTask(t);
                        }
                    }
                }
            }

            // Path Info
            Path cCarPath = GetBelongingPath();
            int  cCarPId  = cCarPath != null ? cCarPath.ID : -1;

            // Speed Bump
            foreach (SpeedBump sb in CLogic.SpeedBumps)
            {
                if (sb.IsAlligned(this))
                {
                    if (sb.IsTowardSpeedBump(this))
                    {
                        float dist = sb.DistanceOfCar(this);
                        //
                        if (dist < SecureDistance)
                        {
                            SetObjectiveSpeed(sb.DesiredSpeed);
                        }
                    }
                }
            }

            ////////////////////////////////////////// IT'S NOT WORKING CORRECTLY! //////////////////////////////////////////////////////
            // Change Way (if there's another free way)
            if (cCarPath != null)
            {
                Car cNearest = cCarPath.GetNearestCarInPath(CLogic, Position, Id);
                if (cNearest != null)
                {
                    float dist = Calc.Modulus(Calc.Magnitude(Position, cNearest.Position));
                    if (dist < SecureDistance) // <--------------------------------------- TODO
                    {
                        List <Path> availablePaths = cCarPath.ParentPathGroup.GetWaysWithDir(cCarPath.Direction);
                        foreach (Path p in availablePaths)
                        {
                            if (p.ID == cCarPath.ID)
                            {
                                continue;
                            }
                            //
                            PointF nLinePos           = Calc.PointLineNormalizedIntersection(Position, p.P1, p.P2);
                            Car    nearestAnotherPath = p.GetNearestCarInPath(CLogic, nLinePos);
                            if (nearestAnotherPath == null)
                            {
                                //
                                PointF futurePoint = new PointF(nLinePos.X + (float)((Math.Cos(Angle) * Speed)),
                                                                nLinePos.Y + (float)((Math.Sin(Angle) * SecureDistance)));

                                // Go TO Another Path
                                Task task = CreateTask(futurePoint, TaskType.Immediate);
                                ImmediateTasks.Push(task);
                                TasksQueue.Clear();
                                break;
                            }
                            //
                            float distCarAnotherPath = Calc.Modulus(Calc.Magnitude(Position, nearestAnotherPath.Position));
                            if (distCarAnotherPath > SecureDistance)
                            {
                                //
                                PointF futurePoint = new PointF(nLinePos.X + (float)((Math.Cos(Angle) * Speed)),
                                                                nLinePos.Y + (float)((Math.Sin(Angle) * SecureDistance)));
                                // Go TO Another Path
                                Task task = CreateTask(futurePoint, TaskType.Immediate);
                                ImmediateTasks.Push(task);
                                TasksQueue.Clear();
                                break;
                            }
                        }
                    }
                }
            }

            // Car Operations
            for (int C = 0; C < CLogic.Cars.Count; C++)
            {
                if (CLogic.Cars[C].Id != Id)
                {
                    // Current Car
                    Car cCar = CLogic.Cars[C];

                    // Error margin
                    const float errAngle    = 30.0f;
                    double      errAngleRad = Calc.NormalizeRadian(Calc.DegreeToRadians(errAngle));

                    // Vars
                    double angAc    = Calc.NormalizeRadian(cCar.Angle);
                    double angAcInv = Calc.NormalizeRadian(cCar.Angle + Math.PI);
                    double angTc    = Calc.NormalizeRadian(Angle);
                    double angAcTc  = Calc.NormalizeRadian(Calc.GetAngleOfLineBetweenTwoPoints(cCar.Position, Position));
                    double angTcAc  = Calc.NormalizeRadian(Calc.GetAngleOfLineBetweenTwoPoints(Position, cCar.Position));
                    float  distBoth = Calc.Modulus(Calc.Magnitude(Position, cCar.Position));

                    // Test if the other car is going toward this car
                    if (Calc.IsInRange(angAcTc - (errAngleRad / 2.00d), angAcTc + (errAngleRad / 2.00d), angAc))
                    {
                        // Test if the other car is going in the same direction
                        if (Calc.IsInRange(angTc - (errAngleRad / 2.00d), angTc + (errAngleRad / 2.00d), angAcInv))
                        {
                            if (distBoth < SecureDistance)
                            {
                                //Break();
                                SetObjectiveSpeed(0.00f);
                            }
                        }
                    }

                    // Test if this car is going toward another car (few FOV to avoid the car speed down when the car is comming in the oposite way)
                    //if (Calc.IsInRange(angTcAc - (errAngleRad / 2.00d), angTcAc + (errAngleRad / 2.00d), angTc))
                    //{
                    //    if (distBoth < SecureDistance)
                    //    {
                    //        //Break();
                    //        SetObjectiveSpeed(0.00f);
                    //    }
                    //}

                    if (Calc.IsInRange(angTcAc - (Calc.DegreeToRadians(FOV) / 2.00d), angTcAc + (Calc.DegreeToRadians(FOV) / 2.00d), angTc))
                    {
                        Path bpcCar = cCar.GetBelongingPath();
                        if (bpcCar != null && GetBelongingPath() != null)
                        {
                            if (distBoth < SecureDistance && bpcCar.ID == GetBelongingPath().ID)
                            {
                                //Break();
                                SetObjectiveSpeed(0.00f);
                            }
                        }
                        else
                        {
                            if (distBoth < SecureDistance)
                            {
                                //Break();
                                SetObjectiveSpeed(0.00f);
                            }
                        }
                    }
                }
            }

            // Traffic Lights
            foreach (TrafficLightGroup tfg in CLogic.TrafficLights)
            {
                foreach (TrafficLight tl in tfg.TLs)
                {
                    if (tl.IsAlligned(this))
                    {
                        if (tl.IsTowardTrafficLight(this))
                        {
                            if (tl.Status == TrafficLightStatus.Red)
                            {
                                float dist = tl.DistanceOfCar(this);
                                //
                                if (dist < SecureDistance)
                                {
                                    SetObjectiveSpeed(0.00f);
                                }
                            }
                        }
                    }
                }
            }

            return(IPos);
        }