예제 #1
0
        public Path GetNearestPath(PointF pos)
        {
            Path  np    = null;
            float dist  = 0.00f;
            bool  first = true;

            //
            foreach (PathGroup pg in PathGroups)
            {
                foreach (Path p in pg.Paths)
                {
                    PointF nearestPath = p.GetNearestPathPoint(pos);
                    float  distTmp     = Calc.Modulus(Calc.Magnitude(pos, nearestPath));
                    //
                    if (first)
                    {
                        first = false;
                        dist  = distTmp;
                        np    = p;
                    }
                    //
                    if (distTmp < dist)
                    {
                        dist = distTmp;
                        np   = p;
                    }
                }
            }
            //
            return(np);
        }
예제 #2
0
        public void Update()
        {
            foreach (Car c in Cars)
            {
                // Keep In Path
                if (c.KeepInPath)
                {
                    Path   np = GetNearestPath(c.Position);
                    PointF pathNearestPoint = np.GetNearestPathPoint(c.Position);
                    //
                    float dist = Calc.Modulus(Calc.Magnitude(c.Position, pathNearestPoint));
                    if (dist > c.ErrorMargin)
                    {
                        if (c.ImmediateTasks.Count == 0)
                        {
                            Task t = c.CreateTask(pathNearestPoint, TaskType.Immediate);
                            c.ImmediateTasks.Push(t);
                        }
                    }
                }

                // Update the Traffic Light
                foreach (TrafficLightGroup tfg in TrafficLights)
                {
                    tfg.DoStep();
                }

                // Update the Car Behavior
                c.Update();
            }
        }
예제 #3
0
        public PointF GetNearestPointInEdge(PointF p)
        {
            float  dist = Calc.Modulus(Calc.Magnitude(P1, p));
            PointF np   = P1;

            //
            for (int C = 1; C <= 4; C++)
            {
                //Point CP = GetPointByNumber(C);
                ////
                //float cDist = Calc.Modulus(Calc.Magnitude(CP, p));
                //if (cDist < dist)
                //{
                //    dist = cDist;
                //    np = CP;
                //}
                Line ln = new Line();
                ln.P1 = Point.Round(GetPointByNumber(C));
                ln.P2 = Point.Round(GetPointByNumber(C + 1 == 5 ? 1 : C + 1));
                //
                PointF intersectionPos = Calc.PointLineNormalizedIntersection(p, ln.P1, ln.P2);
                float  cDist           = Calc.Modulus(Calc.DistancePointLine(p, ln.P1, ln.P2));
                if (cDist < dist)
                {
                    dist = cDist;
                    np   = intersectionPos;
                }
            }
            //
            return(np);
        }
예제 #4
0
 public bool IsInCorner(PointF pos)
 {
     if (Calc.Modulus(Calc.Magnitude(pos, P1)) <= ErrorMargin ||
         Calc.Modulus(Calc.Magnitude(pos, P2)) <= ErrorMargin)
     {
         return(true);
     }
     return(false);
 }
예제 #5
0
 /// <summary>
 /// 0 = None
 /// 1 = P1
 /// 2 = P2
 /// </summary>
 /// <param name="pos"></param>
 /// <returns></returns>
 public int IsInWhichCorner(PointF pos)
 {
     if (Calc.Modulus(Calc.Magnitude(pos, P1)) <= ErrorMargin)
     {
         return(1);
     }
     if (Calc.Modulus(Calc.Magnitude(pos, P2)) <= ErrorMargin)
     {
         return(2);
     }
     return(0);
 }
예제 #6
0
        public PointF GetNearestCorner(PointF pos)
        {
            float distP1 = Calc.Modulus(Calc.Magnitude(pos, P1));
            float distP2 = Calc.Modulus(Calc.Magnitude(pos, P2));

            //
            if (distP1 < distP2)
            {
                return(P1);
            }
            else
            {
                return(P2);
            }
        }
예제 #7
0
 public Path GetBelongingPath()
 {
     //////////////////// TODO <------------- THE CAR NEED TO BE ALIGNED WITH THE STREET (SAME ANGLES)
     foreach (PathGroup pg in CLogic.PathGroups)
     {
         foreach (Path p in pg.Paths)
         {
             if (Calc.Modulus(Calc.Magnitude(p.GetNearestPathPoint(Position), Position)) <= ErrorMargin)
             {
                 return(p);
             }
         }
     }
     return(null);
 }
예제 #8
0
        public PointF GetNearestPoint(PointF p)
        {
            float  dist = Calc.Modulus(Calc.Magnitude(P1, p));
            PointF np   = P1;

            //
            for (int C = 1; C <= 4; C++)
            {
                PointF CP = GetPointByNumber(C);
                //
                float cDist = Calc.Modulus(Calc.Magnitude(CP, p));
                if (cDist < dist)
                {
                    dist = cDist;
                    np   = CP;
                }
            }
            //
            return(np);
        }
예제 #9
0
        public PointF GetNearestPathPoint(PointF pos)
        {
            bool isBetweenLineSegment = Calc.DoesPointLineNormalizedIntersectionIsBetweenTheLine(pos, P1, P2);

            if (isBetweenLineSegment)
            {
                return(Calc.PointLineNormalizedIntersection(pos, P1, P2));
            }
            else
            {
                float distCP1 = Calc.Modulus(Calc.Magnitude(pos, P1));
                float distCP2 = Calc.Modulus(Calc.Magnitude(pos, P2));
                if (distCP1 < distCP2)
                {
                    return(P1);
                }
                else
                {
                    return(P2);
                }
            }
        }
예제 #10
0
        public PointF GetNearestPointBetweenTwoRectangles(Rectangle4P r4p)
        {
            float  dist = Calc.Modulus(Calc.Magnitude(P1, r4p.P1));
            PointF np   = P1;

            //
            for (int C = 1; C <= 4; C++)
            {
                PointF CP = GetPointByNumber(C);
                //
                for (int D = 1; D <= 4; D++)
                {
                    float cDist = Calc.Modulus(Calc.Magnitude(CP, r4p.GetPointByNumber(D)));
                    if (cDist < dist)
                    {
                        dist = cDist;
                        np   = CP;
                    }
                }
            }
            //
            return(np);
        }
        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));
            }
        }
예제 #12
0
        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);
        }