예제 #1
0
        /// <summary>
        /// Returns the distance to the nearest point of a polygon.  If the point is in the Poly, should return 0
        /// </summary>
        /// <param name="poly"></param>
        /// <param name="point"></param>
        /// <returns></returns>
        public static Vec2D ClosestPointOnPolygon(Polygon2D poly, Vec2D point)
        {
            double result = 999999;
            double curResult = 999999;
            Vec2D  BestPoint = null, curPoint;
            Vec2D  one, two, zero;

            zero = new Vec2D(point);
            for (int i = 0; i < poly.xPoints.Count - 1; i++)
            {
                //calculate [i]:[1+1]
                one       = new Vec2D(poly.xPoints[i], poly.yPoints[i]);
                two       = new Vec2D(poly.xPoints[i + 1], poly.yPoints[i + 1]);
                curPoint  = ClosestPointOnLineSegment(zero, one, two);
                curResult = zero.ScalerDistanceTo(curPoint);
                if (result > curResult)
                {
                    result    = curResult; //do we save the point where they intersect?
                    BestPoint = curPoint;
                }
            }
            //then [Count-1]:[0]
            one       = new Vec2D(poly.xPoints[poly.xPoints.Count - 1], poly.yPoints[poly.xPoints.Count - 1]);
            two       = new Vec2D(poly.xPoints[0], poly.yPoints[0]);
            curPoint  = ClosestPointOnLineSegment(zero, one, two);
            curResult = zero.ScalerDistanceTo(curPoint);
            if (result > curResult)
            {
                result    = curResult; //do we save the point where they intersect?
                BestPoint = curPoint;
            }

            return(BestPoint);
        }
예제 #2
0
        public static double DistanceFromPointToSegment(Vec2D p, Vec2D s0, Vec2D s1)
        {/*
          * Vec2D v = s0.VectorDistanceTo(s1);
          * Vec2D w = s0.VectorDistanceTo(p);
          *
          * double c1 = VectorDotProduct(w, v);
          * if (c1 <= 0)
          *     return p.ScalerDistanceTo(s0);// d(P, S.P0);
          *
          * double c2 = VectorDotProduct(v, v);
          * if (c2 <= c1)
          *     return p.ScalerDistanceTo(s1);// d(P, S.P1);
          *
          * double b = c1 / c2;
          * Vec2D Pb = s0.Add(v.Multiply(b));// S.P0 + b * v;
          */
            Vec2D Pb = ClosestPointOnLineSegment(p, s0, s1);

            return(p.ScalerDistanceTo(Pb));// d(P, Pb);
        }
예제 #3
0
        private List<Vec2D> MakeLocationsForGroup(T_Groupings grouping, int numPirates, List<PolygonValue> entryRegions)
        {
            //For two groupings, just return all the entry regions.  We'll probably get a good distribution.
            if (grouping == T_Groupings.Two)
                return MakeLocationsInEntryRegions(numPirates, entryRegions);

            //For one groupings, pick a random entry region to start the group.
            PolygonValue entryRegion = entryRegions.ElementAt(random.Next(entryRegions.Count));
            List<PolygonValue> acceptableEntryRegions = new List<PolygonValue>();
            foreach (PolygonValue region in entryRegions)
            {
                Vec2D pointFromNewRegion = new Vec2D(region.points.ElementAt(0).X, region.points.ElementAt(0).Y);
                Vec2D pointFromFirstRegion = new Vec2D(entryRegion.points.ElementAt(0).X, entryRegion.points.ElementAt(0).Y);
                if (pointFromNewRegion.ScalerDistanceTo(pointFromFirstRegion) < oneGroupingDistance)
                {
                    acceptableEntryRegions.Add(region);
                }
            }
            return MakeLocationsInEntryRegions(numPirates, acceptableEntryRegions);
        }
예제 #4
0
 /// <summary>
 /// Returns a list of entry regions in which new pirates can be added while satisfying grouping constraints, given a group of existing pirates.
 /// </summary>
 /// <param name="grouping">Grouping constraints</param>
 /// <param name="group">Group of existing pirates</param>
 /// <param name="entryRegions">All avilable entry regions</param>
 /// <returns></returns>
 private List<PolygonValue> GetMatchingEntryRegions(T_Groupings grouping, List<DDDAdapter.SeamateObject> group, List<PolygonValue>entryRegions)
 {
     List<PolygonValue> matchingEntryRegions = new List<PolygonValue>();
     //One grouping: matching entry regions must be within certain distance of every individual vessel in group
     if (grouping == T_Groupings.One)
     {
         foreach (PolygonValue region in entryRegions) 
         {
             Vec2D regionPoint = new Vec2D(region.points.ElementAt(0).X, region.points.ElementAt(0).Y);
             bool matching = true;
             foreach (DDDAdapter.SeamateObject vessel in group)
             {
                 Vec2D vesselPoint = new Vec2D(vessel.Location);
                 if (vesselPoint.ScalerDistanceTo(regionPoint) > oneGroupingDistance)
                 {
                     matching = false;
                     break;
                 }
             }
             if (matching)
                 matchingEntryRegions.Add(region);
         }
         return matchingEntryRegions;
     }
     //Two grouping: any entry region will do, the existing group satisfies constraint
     else 
         return entryRegions;
 }
예제 #5
0
        /// <summary>
        /// Calculates an intercept course for all pirates
        /// </summary>
        /// <param name="currentItem"></param>
        /// <param name="dmID"></param>

        public override void Generate(T_Item currentItem, String dmID)
        {

            Dictionary<T_Move, T_Reveal> dict = GetActionsAsDictionary(currentItem.Action);
            //Make new dictionaries; they will be copies containing either merchants or pirates 
            Dictionary<T_Move, T_Reveal> merchantsDict = new Dictionary<T_Move,T_Reveal>();
            Dictionary<T_Move, T_Reveal> piratesDict = new Dictionary<T_Move, T_Reveal>();

            //Copy pirates and merchants into dictionaries
            foreach (T_Move key in dict.Keys)
            {
                if (GetOwner(key, dict[key]) == "Pirate DM") piratesDict.Add(key, dict[key]);
                else merchantsDict.Add(key, dict[key]); 
            }

            if (piratesDict.Keys.Count == 0) return;

            //This dictionary of pirates is the one we'll use to save intercept courses.
            Dictionary<T_Move, T_Reveal> piratesWithInterceptCourse = new Dictionary<T_Move, T_Reveal>();

            //Set each pirate on the shortest intercept course to a newly revealed or existing merchant.
            foreach (T_Move pirateMove in piratesDict.Keys) {
                Vec2D pirateLocation = new Vec2D(GetLocation(pirateMove, piratesDict[pirateMove]));

                //=========Check newly revealed merchants created in this item to find closest ===========================//
                double timeToIntercept = 1000000000000000;
                Vec2D closestInterceptPoint = null;
                T_Move closestNewMerchant = null;

                foreach (T_Move merchantMove in merchantsDict.Keys)
                {
                    double merchantSpeed = merchantMove.Throttle * GetMaxSpeed(merchantMove);
                    Vec2D merchantStart = new Vec2D(GetLocation(merchantMove, merchantsDict[merchantMove]));
                    Vec2D merchantDestination = new Vec2D((LocationValue)merchantMove.Location.Item);
                    Vec2D interceptPoint = GetInterceptPoint(merchantStart, merchantDestination, merchantSpeed, pirateLocation, GetMaxSpeed(pirateMove));
                    double merchantTimeToIntercept = merchantStart.ScalerDistanceTo(interceptPoint) / merchantSpeed;
                    if (merchantTimeToIntercept < timeToIntercept)
                    {
                        closestNewMerchant = merchantMove;
                        closestInterceptPoint = interceptPoint;
                        timeToIntercept = merchantTimeToIntercept;
                    }
                }            

                //============Check merchants already revealed, see if one is closer ========================
                //TODO: make sure any merchants we will move in this round are not being compared
                DDDAdapter.SeamateObject closestRevealedMerchant = null;
             
                foreach (DDDAdapter.SeamateObject vessel in revealedSeaVessels)
                {
                    //Compare all the existing merchants' positions to see if they are closer.

                    //if (vessel.ID == closestNewMerchant.ID) continue;

                    if (vessel.Owner == "Merchant DM")
                    {
                        double merchantSpeed = vessel.Throttle * vessel.MaximumSpeed;
                        Vec2D merchantStart = new Vec2D(vessel.Location);
                        Vec2D merchantDestination = new Vec2D(vessel.DestinationLocation);
                        Vec2D interceptPoint = GetInterceptPoint(merchantStart, merchantDestination, merchantSpeed, pirateLocation, GetMaxSpeed(pirateMove));

                        double merchantTimeToIntercept = merchantStart.ScalerDistanceTo(interceptPoint) / merchantSpeed;
                        if (merchantTimeToIntercept < timeToIntercept)
                        {
                            closestNewMerchant = null;
                            closestRevealedMerchant = vessel;
                            closestInterceptPoint = interceptPoint;
                            timeToIntercept = merchantTimeToIntercept;
                        }
                    }
                    else continue; //ignore pirates or fleet ships
                }


                if (closestInterceptPoint == null)
                {
                    return;
                }
                //Make a new move for the pirate, containing the pirate's intercept course.
                T_Move moveWithInterceptCourse = new T_Move();
                moveWithInterceptCourse.ID = pirateMove.ID;
                moveWithInterceptCourse.Throttle = 1.0;
                moveWithInterceptCourse.Location = new T_Location();
                moveWithInterceptCourse.Location.Item = closestInterceptPoint.ToLocationValue();



                
                //Set the pirate and merchant's "Intent" relating to the intercept in their SimObjects
                if (closestNewMerchant != null)
                {
                    ddd.UpdateObjectAttribute(closestNewMerchant.ID, "Intent", "Being intercepted:" + pirateMove.ID + ":" + timeToIntercept, "AGENT");   //Merchant
                    ddd.UpdateObjectAttribute(pirateMove.ID, "Intent", "Intercepting:" + closestNewMerchant.ID + ":" + timeToIntercept, "AGENT");  //Pirate
                }
                else if (closestRevealedMerchant != null)
                {
                    ddd.UpdateObjectAttribute(closestRevealedMerchant.ID, "Intent", "Being intercepted:" + pirateMove.ID + ":" + timeToIntercept, "AGENT");   //Merchant
                    ddd.UpdateObjectAttribute(pirateMove.ID, "Intent", "Intercepting:" + closestRevealedMerchant.ID + ":" + timeToIntercept, "AGENT");  //Pirate
                }
                else
                    Console.Error.WriteLine("Fix intercept generator");
                 
             
                //Add the pirate's updated move and reveal to pirate dictionary.
                piratesWithInterceptCourse[moveWithInterceptCourse] = piratesDict[pirateMove];

            }

            //Add altered pirates back to merchants, and reset the action array.
            currentItem.Action = GetActionsFromDictionary(merchantsDict.Concat(piratesWithInterceptCourse).ToDictionary(kvp => kvp.Key, kvp => kvp.Value));

        }
예제 #6
0
파일: Polygon2D.cs 프로젝트: wshanshan/DDD
        /// <summary>
        /// Returns the distance to the nearest point of a polygon.  If the point is in the Poly, should return 0
        /// </summary>
        /// <param name="poly"></param>
        /// <param name="point"></param>
        /// <returns></returns>
        public static Vec2D ClosestPointOnPolygon(Polygon2D poly, Vec2D point)
        {
            double result = 999999;
            double curResult = 999999;
            Vec2D BestPoint = null, curPoint;
            Vec2D one, two, zero;
            zero = new Vec2D(point);
            for (int i = 0; i < poly.xPoints.Count - 1; i++)
            {
                //calculate [i]:[1+1]
                one = new Vec2D(poly.xPoints[i], poly.yPoints[i]);
                two = new Vec2D(poly.xPoints[i + 1], poly.yPoints[i + 1]);
                curPoint = ClosestPointOnLineSegment(zero, one, two);
                curResult = zero.ScalerDistanceTo(curPoint);
                if (result > curResult)
                {
                    result = curResult; //do we save the point where they intersect?
                    BestPoint = curPoint;
                }
            }
            //then [Count-1]:[0]
            one = new Vec2D(poly.xPoints[poly.xPoints.Count - 1], poly.yPoints[poly.xPoints.Count - 1]);
            two = new Vec2D(poly.xPoints[0], poly.yPoints[0]);
            curPoint = ClosestPointOnLineSegment(zero, one, two);
            curResult = zero.ScalerDistanceTo(curPoint);
            if (result > curResult)
            {
                result = curResult; //do we save the point where they intersect?
                BestPoint = curPoint;
            }

            return BestPoint;
        }
예제 #7
0
파일: Polygon2D.cs 프로젝트: wshanshan/DDD
        public static double DistanceFromPointToSegment(Vec2D p, Vec2D s0, Vec2D s1)
        {/*
            Vec2D v = s0.VectorDistanceTo(s1);
            Vec2D w = s0.VectorDistanceTo(p);

            double c1 = VectorDotProduct(w, v);
            if (c1 <= 0)
                return p.ScalerDistanceTo(s0);// d(P, S.P0);

            double c2 = VectorDotProduct(v, v);
            if (c2 <= c1)
                return p.ScalerDistanceTo(s1);// d(P, S.P1);

            double b = c1 / c2;
            Vec2D Pb = s0.Add(v.Multiply(b));// S.P0 + b * v;
            */
            Vec2D Pb = ClosestPointOnLineSegment(p, s0, s1);
            return p.ScalerDistanceTo(Pb);// d(P, Pb);
        }