public void Update(DDDServerConnection serverConnection, DMView dmView) { SimObject me = dmView.AllObjects[m_thisID]; SimActiveRegion zone = dmView.ActiveRegions[m_zoneID]; LocationValue otherLocation = null; Polygon2D azPoly = new Polygon2D(); foreach (PolygonValue.PolygonPoint p in zone.Shape.points) { azPoly.AddVertex(new Vec2D(p.X, p.Y)); } bool clear = true; foreach (String id in dmView.AllObjects.Keys) { if (id == m_thisID) { continue; } otherLocation = dmView.AllObjects[id].Location; if (Polygon2D.IsPointInside(azPoly, new Vec2D(otherLocation))) { clear = false; break; } } if (clear) { m_done = true; } }
/// <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 double ScalarDistanceToPolygon(Polygon2D poly, Vec2D point) { if (IsPointInside(poly, point)) { return(0.0); } double result = 999999; double curResult = 999999; 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]); //curResult = Math.Abs((two.X-one.X)*(one.Y-zero.Y)-(one.X-zero.X)*(two.Y-one.Y))/Math.Sqrt(Math.Pow(two.X-one.X,2)+Math.Pow(two.Y-one.Y,2)); curResult = DistanceFromPointToSegment(zero, one, two); //curResult = (poly.yPoints[i + 1] - poly.yPoints[i]) * (point.X - poly.xPoints[i]) - (poly.xPoints[i + 1] - poly.xPoints[i]) * (point.Y - poly.yPoints[i]); //Math.Sqrt(Math.Pow((two.Y-one.Y)*(zero.X-one.X)+(two.X-one.X)*(zero.Y-one.Y),2)/(Math.Pow(two.X-one.X,2)+Math.Pow(two.Y-one.Y,2))); if (result > curResult) { result = curResult; //do we save the point where they intersect? } } //then [Count-1]:[0] //curResult = (poly.yPoints[0] - poly.yPoints[poly.xPoints.Count - 1]) * (point.X - poly.xPoints[poly.xPoints.Count - 1]) - (poly.xPoints[0] - poly.xPoints[poly.xPoints.Count - 1]) * (point.Y - poly.yPoints[poly.xPoints.Count - 1]); one = new Vec2D(poly.xPoints[poly.xPoints.Count - 1], poly.yPoints[poly.xPoints.Count - 1]); two = new Vec2D(poly.xPoints[0], poly.yPoints[0]); curResult = DistanceFromPointToSegment(zero, one, two); if (result > curResult) { result = curResult; //do we save the point where they intersect? } return(result); }
public static Vec2D FindIntersect(PolygonValue poly1, PolygonValue poly2) { List <Vec2D> intersections = new List <Vec2D>(); //with polys, we might have 2 intersections, should we find the middle of the two? List <PolygonValue.PolygonPoint> p2Points = poly2.points; Vec2D intersect = null; Polygon2D p2d = new Polygon2D(); PolygonValue.PolygonPoint p0; PolygonValue.PolygonPoint p1; p2d.FromPolygon(poly1); for (int i = 0; i < p2Points.Count - 1; i++) { p0 = p2Points[i]; p1 = p2Points[i + 1]; intersect = FindIntersect(p2d, new Vec2D(p0.X, p0.Y), new Vec2D(p1.X, p1.Y)); if (intersect != null) { intersections.Add(intersect); } } //then once more from len-1 to 0 p0 = p2Points[p2Points.Count - 1]; p1 = p2Points[0]; intersect = FindIntersect(p2d, new Vec2D(p0.X, p0.Y), new Vec2D(p1.X, p1.Y)); //intersect = FindIntersect(poly1, p2Points[p2Points.Count - 1], p2Points[0]); if (intersect != null) { intersections.Add(intersect); } if (intersections.Count > 0) { return(AverageVectors(intersections)); } return(null); }
private Vec2D MakeLocationInEntryRegions(List<PolygonValue> acceptableEntryRegions) { PolygonValue entryRegion = acceptableEntryRegions.ElementAt(random.Next(acceptableEntryRegions.Count)); Vec2D location = new Polygon2D(entryRegion).PointInside(); return location; }
private List<Vec2D> MakeLocationsInEntryRegions(int numPirates, List<PolygonValue> acceptableEntryRegions) { List<Vec2D> locations = new List<Vec2D>(); for (int i = 0; i < numPirates; i++) { PolygonValue entryRegion = acceptableEntryRegions.ElementAt(random.Next(acceptableEntryRegions.Count)); Vec2D location = new Polygon2D(entryRegion).PointInside(); locations.Add(location); } return locations; }
/// <summary> /// Calculates the absolute polygon of a region given a new location, /// using the region's reference point and relative polygon /// </summary> /// <param name="location"></param> /// <param name="region"></param> /// <returns></returns> private Polygon3D GetAbsolutePolygon(Vec2D refPoint, Polygon2D relativePolygon) { //Vec2D difference = refPoint.VectorDistanceTo(location); Polygon3D absolute = new Polygon3D(0,0); foreach (Vec2D vertex in relativePolygon.getVertices()) { absolute.AddVertex(vertex.Add(refPoint)); } return absolute; }
public static bool IsPointInside(Polygon2D poly, Vec2D p) { // Check bounding box first if (p.X < poly.bboxXMin || p.X > poly.bboxXMax) { return false; } if (p.Y < poly.bboxYMin || p.Y > poly.bboxYMax) { return false; } // cast ray to random location to avoid casting through a vertex. Vec2D p2 = new Vec2D(p); p2.X = (random.NextDouble() * 1000) + poly.bboxXMax; p2.Y = (random.NextDouble() * 1000) + poly.bboxYMax; Line line = new Line(p, p2); int k, j; Line line2 = new Line(); int count = 0; for (k = 0; k < poly.xPoints.Count; k++) { j = k - 1; if (j < 0) { j = poly.xPoints.Count - 1; } line2.p1 = new Vec2D(poly.xPoints[k], poly.yPoints[k]); line2.p2 = new Vec2D(poly.xPoints[j], poly.yPoints[j]); if (DoLinesIntersect(line.p1, line.p2, line2.p1, line2.p2)) { count++; } } if ((count % 2) == 1) { return true; } else { return false; } }
public static Vec2D FindIntersect(PolygonValue poly1, PolygonValue poly2) { List<Vec2D> intersections = new List<Vec2D>(); //with polys, we might have 2 intersections, should we find the middle of the two? List<PolygonValue.PolygonPoint> p2Points = poly2.points; Vec2D intersect = null; Polygon2D p2d = new Polygon2D(); PolygonValue.PolygonPoint p0; PolygonValue.PolygonPoint p1; p2d.FromPolygon(poly1); for (int i = 0; i < p2Points.Count - 1; i++) { p0 = p2Points[i]; p1 = p2Points[i + 1]; intersect = FindIntersect(p2d, new Vec2D(p0.X, p0.Y), new Vec2D(p1.X, p1.Y)); if (intersect != null) intersections.Add(intersect); } //then once more from len-1 to 0 p0 = p2Points[p2Points.Count - 1]; p1 = p2Points[0]; intersect = FindIntersect(p2d, new Vec2D(p0.X, p0.Y), new Vec2D(p1.X, p1.Y)); //intersect = FindIntersect(poly1, p2Points[p2Points.Count - 1], p2Points[0]); if (intersect != null) intersections.Add(intersect); if (intersections.Count > 0) return AverageVectors(intersections); return null; }
//Vec2D SmallestX(List<Vec2D> l) //{ // Vec2D r = l[0]; // for (int i = 1; i < l.Count; i++) // { // if (l[i].X < r.X) // { // r = l[i]; // } // } // return r; //} //Vec2D SmallestY(List<Vec2D> l) //{ // Vec2D r = l[0]; // for (int i = 1; i < l.Count; i++) // { // if (l[i].Y < r.Y) // { // r = l[i]; // } // } // return r; //} //Vec2D BiggestY(List<Vec2D> l) //{ // Vec2D r = l[0]; // for (int i = 1; i < l.Count; i++) // { // if (l[i].Y > r.Y) // { // r = l[i]; // } // } // return r; //} //Polygon2D GetPoly2(Vec2D p1, Vec2D p2) //{ // double halfwidth = m_avoidPathWidth / 2; // Polygon2D poly = new Polygon2D(); // List<Vec2D> vertices = new List<Vec2D>(); // Vec2D v1 = GetPerpendicularPoint(p1, p2, -1* halfwidth); // Vec2D v2 = GetPerpendicularPoint(p1, p2, 1 * halfwidth); // Vec2D v3 = GetPerpendicularPoint(p2, p1, 1 * halfwidth); // Vec2D v4 = GetPerpendicularPoint(p2, p1, -1 * halfwidth); // if (v1 == null || v2 == null || v3 == null || v4 == null) // { // return null; // } // else // { // vertices.Add(v1); // vertices.Add(v2); // vertices.Add(v3); // vertices.Add(v4); // Vec2D first = SmallestX(vertices); // vertices.Remove(first); // Vec2D second = SmallestX(vertices); // vertices.Remove(second); // Vec2D third; // if (second.Y > first.Y) // { // third = BiggestY(vertices); // vertices.Remove(third); // } // else // { // third = SmallestY(vertices); // vertices.Remove(third); // } // Vec2D fourth = vertices[0]; // poly.AddVertex(first); // poly.AddVertex(second); // poly.AddVertex(third); // poly.AddVertex(fourth); // return poly; // } //} //Vec2D GetPerpendicularPoint(Vec2D p1, Vec2D p2, double d) //{ // Vec2D p3 = new Vec2D(0, 0); // p3.X = p2.X + 1; // double m = -1 * ((p2.Y - p1.Y) / (p2.X - p1.X)); // double b = p2.Y + ((p2.Y - p1.Y) / (p2.X - p1.X)); // p3.Y = (m * p3.X) + b; // return ProjectPointOnLine(p2, p3, d); //} Polygon2D GetPoly(Vec2D p1, Vec2D p2) { double halfwidth = m_avoidPathWidth/2; Polygon2D poly = new Polygon2D(); double dx = p2.X - p1.X >= 0 ? halfwidth : halfwidth * -1; double dy = p2.Y - p1.Y >= 0 ? halfwidth : halfwidth * -1; if (Math.Abs(p2.X - p1.X) > Math.Abs(p2.Y - p1.Y)) { poly.AddVertex(new Vec2D(p1.X, p1.Y - halfwidth)); poly.AddVertex(new Vec2D(p1.X, p1.Y + halfwidth)); poly.AddVertex(new Vec2D(p2.X+dx, p2.Y + halfwidth)); poly.AddVertex(new Vec2D(p2.X+dx, p2.Y - halfwidth)); return poly; } else { poly.AddVertex(new Vec2D(p1.X - halfwidth, p1.Y)); poly.AddVertex(new Vec2D(p1.X + halfwidth, p1.Y)); poly.AddVertex(new Vec2D(p2.X + halfwidth, p2.Y+dy)); poly.AddVertex(new Vec2D(p2.X - halfwidth, p2.Y+dy)); return poly; } }
public LandRegion(string id, Polygon2D poly) { this.id = id; this.poly = poly; }
/// <summary> /// Makes a point which is in the closest entry region to the group of pirates, /// TODO: but not in the same entry region as any of them. /// </summary> /// <param name="pirates">The move events representing pirates</param> /// <param name="entryRegions">All entry regions</param> /// <returns>A random point in the closest entry region to the group of pirates</returns> private Vec2D GetPointInClosestEntryRegion(Dictionary<T_Move,T_Reveal> pirates, List<PolygonValue> entryRegions) { Vec2D point = new Vec2D(0,0); double closestDistance = 100000000; PolygonValue closestRegion = null; Shuffle(entryRegions); T_Move randomPirate = pirates.Keys.ToList().ElementAt(0); LocationValue location = GetLocation(randomPirate, pirates[randomPirate]); foreach (PolygonValue entryRegion in entryRegions) { Polygon2D entry2D = new Polygon2D(entryRegion); double distance = Polygon2D.ScalarDistanceToPolygon(entry2D, new Vec2D(location)); if (distance < oneGroupingDistance) { point = entry2D.PointInside(); break; } else { if (distance < closestDistance) { closestDistance = distance; closestRegion = entryRegion; } } } if (point == null) { point = new Polygon2D(closestRegion).PointInside(); } return point; }
/// <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 double ScalarDistanceToPolygon(Polygon2D poly, Vec2D point) { if (IsPointInside(poly, point)) { return 0.0; } double result = 999999; double curResult = 999999; 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]); //curResult = Math.Abs((two.X-one.X)*(one.Y-zero.Y)-(one.X-zero.X)*(two.Y-one.Y))/Math.Sqrt(Math.Pow(two.X-one.X,2)+Math.Pow(two.Y-one.Y,2)); curResult = DistanceFromPointToSegment(zero, one, two); //curResult = (poly.yPoints[i + 1] - poly.yPoints[i]) * (point.X - poly.xPoints[i]) - (poly.xPoints[i + 1] - poly.xPoints[i]) * (point.Y - poly.yPoints[i]); //Math.Sqrt(Math.Pow((two.Y-one.Y)*(zero.X-one.X)+(two.X-one.X)*(zero.Y-one.Y),2)/(Math.Pow(two.X-one.X,2)+Math.Pow(two.Y-one.Y,2))); if (result > curResult) { result = curResult; //do we save the point where they intersect? } } //then [Count-1]:[0] //curResult = (poly.yPoints[0] - poly.yPoints[poly.xPoints.Count - 1]) * (point.X - poly.xPoints[poly.xPoints.Count - 1]) - (poly.xPoints[0] - poly.xPoints[poly.xPoints.Count - 1]) * (point.Y - poly.yPoints[poly.xPoints.Count - 1]); one = new Vec2D(poly.xPoints[poly.xPoints.Count - 1], poly.yPoints[poly.xPoints.Count - 1]); two = new Vec2D(poly.xPoints[0], poly.yPoints[0]); curResult = DistanceFromPointToSegment(zero, one, two); if (result > curResult) { result = curResult; //do we save the point where they intersect? } return result; }
//Threat generator -- generates or chooses ONE pirate or friendly vessel in DM domain //So either creates a RevealEvent or chooses existing vessel for MoveEvent public List<DDDAdapter.SeamateObject> GenerateWithTriedItems(T_Item currentItem, String dmID, List<DDDAdapter.SeamateObject> triedVessels) { //make a copy of the input which we'll modify and return at the end List<DDDAdapter.SeamateObject> returnTriedVessels = new List<DDDAdapter.SeamateObject>(triedVessels); String owner; bool isPirate; if (currentItem.Parameters.Threat == T_Threat.None) { isPirate = false; owner = "Merchant DM"; } else { isPirate = true; owner = "Pirate DM"; } PolygonValue domainPV = this.ddd.GetDecisionMakersAreaOfResponsibility(dmID); Polygon2D domain = new Polygon2D(domainPV); List<Object> actions = new List<object>(); if (shouldAddNewVessel(revealedSeaVessels)) { Console.WriteLine("ThreatGenerator: I'm trying to reuse a vessel because there are " + revealedSeaVessels.Count + " in play already and/or probability told me to."); List<DDDAdapter.SeamateObject> vessels = new List<DDDAdapter.SeamateObject>(); //Find all vessels of the appropriate type (pirate or merchant) within the BAMS/Firescout's range. foreach (DDDAdapter.SeamateObject vessel in revealedSeaVessels) { if (vessel.Owner == owner && Polygon2D.IsPointInside(domain, new Vec2D(vessel.Location))) vessels.Add(vessel); } Console.WriteLine("ThreatGenerator: Found " + vessels.Count + " to reuse"); if (vessels.Count > 0) { //manage the list of previously tried objects if (triedVessels.Count == vessels.Count) returnTriedVessels = new List<DDDAdapter.SeamateObject>(); foreach (DDDAdapter.SeamateObject alreadyTried in returnTriedVessels) vessels.Remove(alreadyTried); Shuffle(vessels); DDDAdapter.SeamateObject vessel = null; //see if any eligible vessels are stopped, if so, use one of them foreach (DDDAdapter.SeamateObject possiblyStoppedVessel in vessels) { if (possiblyStoppedVessel.Throttle == 0) //yes, it is stopped { Console.WriteLine("ThreatGenerator: Picking a stopped vessel " + possiblyStoppedVessel.ID + " to reuse."); vessel = possiblyStoppedVessel; break; } } //we didn't find any stopped vessels, so pick a random eligible one. if (vessel == null) vessel = vessels[random.Next(vessels.Count)]; returnTriedVessels.Add(vessel); T_Move move = new T_Move(); move.ID = vessel.ID; move.Location = new T_Location(); actions.Add(move); } } if (actions.Count() == 0) //we couldn't find a ship or need more vessels { //reveal a random new one Console.WriteLine("ThreatGenerator: I'm revealing a new vessel, either couldn't find a ship or need more vessels."); List<string> unrevealedObjectIDs = ddd.GetAllUnrevealedObjectIds(isPirate,true,null); T_Reveal reveal = new T_Reveal(); reveal.ID = unrevealedObjectIDs[random.Next(unrevealedObjectIDs.Count())]; reveal.Owner = owner; reveal.State = "FullyFunctional"; reveal.Location = new T_Location(); reveal.StartupParameters = new T_StartupParameters(); reveal.StartupParameters.Items = new string[0]; T_Move move = new T_Move(); move.ID = reveal.ID; move.Location = new T_Location(); Vec2D point; List<PolygonValue> entryRegions = ddd.GetAllEntryRegions(); //TODO: Write a safe PointInsideMultipleDomains() function. This could theoretically loop forever with a terrible scenario while (true) { point = new Polygon2D(entryRegions[random.Next(entryRegions.Count)]).PointInside(); if (Polygon2D.IsPointInside(domain,point)) { break; } } reveal.Location.Item = point.ToLocationValue(); actions.Add(reveal); actions.Add(move); Console.WriteLine("ThreatGenerator: Just revealed a pirate " + reveal.ID); } currentItem.Action = actions.ToArray(); return returnTriedVessels; }
/// <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; }
public static bool SensorDoesLineCross(Polygon2D poly, Vec2D fromP, Vec2D toP) { Line line = new Line(fromP, toP); int k, j; Line line2 = new Line(); for (k = 0; k < poly.xPoints.Count; k++) { j = k - 1; if (j < 0) { j = poly.xPoints.Count - 1; } line2.p1 = new Vec2D(poly.xPoints[k], poly.yPoints[k]); line2.p2 = new Vec2D(poly.xPoints[j], poly.yPoints[j]); if (DoLinesIntersect(line.p1, line.p2, line2.p1, line2.p2)) { return true; } } return false; }
public static bool DoesLineCross(Polygon2D poly, Vec2D fromP, Vec2D toP) { // Check bounding box first /* if (toP.X < poly.bboxXMin || toP.X > poly.bboxXMax) { return false; } if (toP.Y < poly.bboxYMin || toP.Y > poly.bboxYMax) { return false; } */ Line line = new Line(fromP, toP); int k, j; Line line2 = new Line(); for (k = 0; k < poly.xPoints.Count; k++) { j = k - 1; if (j < 0) { j = poly.xPoints.Count - 1; } line2.p1 = new Vec2D(poly.xPoints[k], poly.yPoints[k]); line2.p2 = new Vec2D(poly.xPoints[j], poly.yPoints[j]); if (DoLinesIntersect(line.p1, line.p2, line2.p1, line2.p2)) { return true; } } return false; }
//Pirate generator -- generates or chooses several pirates or friendly vessels in DM domain //So either creates a RevealEvent or chooses existing vessel for MoveEvent public override void Generate(T_Item currentItem, String dmID) { if (currentItem.Parameters.Threat == T_Threat.None) return; actions = currentItem.Action.ToList(); // Do some setup bool isPirate = !(currentItem.Parameters.Threat == T_Threat.None); if (isPirate) owner = "Pirate DM"; else owner = "Merchant DM"; PolygonValue domainPV = this.ddd.GetDecisionMakersAreaOfResponsibility(dmID); domain = new Polygon2D(domainPV); List<string> unrevealedObjectIDs = ddd.GetAllUnrevealedObjectIds(isPirate, true, null); //How many pirates should we generate? These numbers may need tweaking int minPirates = Properties.Settings.Default.minPirates; int maxPirates = Properties.Settings.Default.maxPirates; int numPirates = random.Next(minPirates, maxPirates); //Are there any pirates we can reuse, already in play? List<DDDAdapter.SeamateObject> reusableVessels = revealedSeaVessels.FindAll(IsReusable); if (reusableVessels.Count > 0 && Properties.Settings.Default.reusePirates) { for (int i = 0; i < numPirates; i++) { if (reusableVessels.Count > 0) { DDDAdapter.SeamateObject vessel = reusableVessels[0]; reusableVessels.Remove(vessel); CreateEmptyMove(vessel); } else { Vec2D location = MakeLocationInEntryRegions(entryRegions); string id = unrevealedObjectIDs[random.Next(unrevealedObjectIDs.Count())]; unrevealedObjectIDs.Remove(id); CreateRevealAndEmptyMove(id, owner, location); } } ////See if any existing pirates can be paired under "grouping" distance constraints //List<List<DDDAdapter.SeamateObject>> groupedPirates = GroupVessels(currentItem.Parameters.Groupings, numPirates, reusableVessels); //List<List<DDDAdapter.SeamateObject>> groupsOfNumPirateSize = groupedPirates.FindAll(delegate(List<DDDAdapter.SeamateObject> g) { return g.Count >= numPirates; }); ////Any groups of numPirates? //if (groupsOfNumPirateSize.Count > 0) //{ // //if yes, make dummy move events for them and add to actions list. done. // foreach (DDDAdapter.SeamateObject pirate in groupsOfNumPirateSize.ElementAt(0)) // CreateEmptyMove(pirate); //} //else //{ // //Can any of these smaller groupings include an entry region too, so we can add new pirates? // groupedPirates.Sort(delegate(List<DDDAdapter.SeamateObject> g1, List<DDDAdapter.SeamateObject> g2) { return g1.Count.CompareTo(g2.Count); }); //sort by size, largest first // foreach (List<DDDAdapter.SeamateObject> group in groupedPirates) // { // List<PolygonValue> matchingEntryRegions = GetMatchingEntryRegions(currentItem.Parameters.Groupings, group, entryRegions); // if (matchingEntryRegions.Count > 0) // { // //if yes, then make dummy move events for the pirates in grouping, then // foreach (DDDAdapter.SeamateObject pirate in groupsOfNumPirateSize.ElementAt(0)) // CreateEmptyMove(pirate); // //Create as many remaining pirates as we need distributed randomly among suitable entry regions. // List<Vec2D> locations = MakeLocationsInEntryRegions(numPirates - group.Count, matchingEntryRegions); // foreach (Vec2D location in locations) // { // string id = unrevealedObjectIDs[random.Next(unrevealedObjectIDs.Count())]; // unrevealedObjectIDs.Remove(id); // CreateRevealAndEmptyMove(id, owner, location); // } // break; // } // } // //if no, we couldn't include an entry region (where new pirates would be created) with any existing pirates // if (actions.Count == 0) // //TODO: maybe should make smaller num of pirates if above min rather than making all new? // MakeAllNewPirates(currentItem.Parameters.Groupings,numPirates,entryRegions,unrevealedObjectIDs); //} } //no reusable vessels, we have to create all new pirates else { MakeAllNewPirates(currentItem.Parameters.Groupings,numPirates,entryRegions,unrevealedObjectIDs); } currentItem.Action = actions.ToArray(); }
static void Main(string[] args) { Polygon2D poly = new Polygon2D(); poly.AddVertex(new Vec2D(1,1)); poly.AddVertex(new Vec2D(4, 1)); poly.AddVertex(new Vec2D(2.5, 3)); poly.AddVertex(new Vec2D(4, 3)); poly.AddVertex(new Vec2D(4, 4)); poly.AddVertex(new Vec2D(2, 3.5)); bool r; r = Polygon2D.IsPointInside(poly,new Vec2D(5, 3)); //false r = Polygon2D.IsPointInside(poly, new Vec2D(2, 2)); //true r = Polygon2D.IsPointInside(poly, new Vec2D(3.5, 3.5)); //true r = Polygon2D.IsPointInside(poly, new Vec2D(1, 3.5)); //false r = Polygon2D.IsPointInside(poly, new Vec2D(3, 2.5)); //false r = Polygon2D.DoLinesIntersect(new Vec2D(0, 2), new Vec2D(3, 0), new Vec2D(1, 1), new Vec2D(3, 3)); //true r = Polygon2D.DoLinesIntersect(new Vec2D(0, 2), new Vec2D(3, 0), new Vec2D(2, 1), new Vec2D(3, 3)); //false DataValue dv = DataValueFactory.BuildValue("CapabilityType"); ((CapabilityValue)dv).effects.Add(new CapabilityValue.Effect("foo",45,10,.50)); ((CapabilityValue)dv).effects.Add(new CapabilityValue.Effect("foo", 100, 5, .25)); string s = DataValueFactory.XMLSerialize(dv); DataValue dv2 = DataValueFactory.XMLDeserialize(s); DataValue dv3 = DataValueFactory.BuildValue("VulnerabilityType"); VulnerabilityValue.Transition t = new VulnerabilityValue.Transition("dead"); t.conditions.Add(new VulnerabilityValue.TransitionCondition("foo",50,0,0)); t.conditions.Add(new VulnerabilityValue.TransitionCondition("bar", 20,0,0)); ((VulnerabilityValue)dv3).transitions.Add(t); t = new VulnerabilityValue.Transition("hurt"); t.conditions.Add(new VulnerabilityValue.TransitionCondition("foo", 25,0,0)); ((VulnerabilityValue)dv3).transitions.Add(t); s = DataValueFactory.XMLSerialize(dv3); DataValue dv4 = DataValueFactory.XMLDeserialize(s); System.Console.WriteLine(s == DataValueFactory.XMLSerialize(dv4)); DataValue dv5 = DataValueFactory.BuildValue("StateTableType"); DataValue dv6 = DataValueFactory.BuildValue("AttributeCollectionType"); ((StateTableValue)dv5).states["foo"] = DataValueFactory.BuildValue("DoubleType"); ((AttributeCollectionValue)dv6).attributes["foo2"] = DataValueFactory.BuildValue("DoubleType"); ((StateTableValue)dv5).states["bar"] = dv6; s = DataValueFactory.XMLSerialize(dv5); DataValue dv7 = DataValueFactory.XMLDeserialize(s); DataValue dv8 = DataValueFactory.BuildValue("StringListType"); ((StringListValue)dv8).strings.Add("Foo"); ((StringListValue)dv8).strings.Add("Bar"); s = DataValueFactory.XMLSerialize(dv8); dv8 = DataValueFactory.XMLDeserialize(s); DataValue dv9 = DataValueFactory.BuildValue("PolygonType"); ((PolygonValue)dv9).points.Add(new PolygonValue.PolygonPoint(0, 0)); ((PolygonValue)dv9).points.Add(new PolygonValue.PolygonPoint(10.234, 34.097)); ((PolygonValue)dv9).points.Add(new PolygonValue.PolygonPoint(10.234, 1.2)); s = DataValueFactory.XMLSerialize(dv9); DataValue dv10 = DataValueFactory.XMLDeserialize(s); }
public static bool DeriveReferenceFromVertexList(String currentReferencePoint, String vertexList, out String referencePoint, out String updatedVertexList) { referencePoint = "0 0"; updatedVertexList = vertexList; if (vertexList.Trim().Length == 0) return false; //list is formed as (x, y), (x2, y2), etc char[] del = { ' ' }; string[] pairDel = { ")," }; String[] refPt = currentReferencePoint.Split(del); Vec2D curRefPt = new Vec2D(0, 0); if (refPt.Length == 2) { curRefPt = new Vec2D(Double.Parse(refPt[0].Trim()), Double.Parse(refPt[1].Trim())); } String[] pair = vertexList.Split(pairDel, StringSplitOptions.RemoveEmptyEntries); PolygonValue poly = new PolygonValue(); double minX = 0, maxX = 0, minY = 0, maxY = 0; bool set = false; foreach (String p in pair) { String[] pp = p.Replace('(', ' ').Replace(')', ' ').Split(del, StringSplitOptions.RemoveEmptyEntries); double x = Double.Parse(pp[0].Replace(",","").Replace("\r\n","").Trim()); double y = Double.Parse(pp[1].Replace("\r\n", "").Trim()); if (pp.Length == 2) { if (!set) { minX = maxX = x; minY = maxY = y; set = true; } else { if (x < minX) { minX = x; } else if (x > maxX) { maxX = x; } if (y < minY) { minY = y; } else if (y > maxY) { maxY = y; } } poly.points.Add(new PolygonValue.PolygonPoint(x, y)); } else { Console.WriteLine("Something's wrong!"); } } Polygon2D p2d = new Polygon2D(); p2d.FromPolygon(poly); if (!Polygon2D.IsPointInside(p2d, curRefPt)) { //find new ref point Vec2D tempPt = new Vec2D((maxX + minX) / 2, (maxY + minY) / 2); Random r = new Random(DateTime.Now.Millisecond); while (!Polygon2D.IsPointInside(p2d, tempPt)) { double newX = r.NextDouble() * (maxX - minX) + minX; double newY = r.NextDouble() * (maxY - minY) + minY; tempPt = new Vec2D(newX, newY); } curRefPt = tempPt; } referencePoint = String.Format("{0} {1}", curRefPt.X, curRefPt.Y); StringBuilder sb = new StringBuilder(); for (int i = 0; i < poly.points.Count - 1; i++) { sb.AppendFormat("({0}, {1}), ", poly.points[i].X - curRefPt.X, poly.points[i].Y - curRefPt.Y); } //then once more for count -1 sb.AppendFormat("({0}, {1})", poly.points[poly.points.Count - 1].X - curRefPt.X, poly.points[poly.points.Count - 1].Y - curRefPt.Y); updatedVertexList = sb.ToString(); return true; }
public override void Generate(T_Item currentItem, String dmID) { //Identify what's already in actions list. foreach (Object action in currentItem.Action) { if (action as T_Move != null) primaryMove = (T_Move)action; if (action as T_Reveal != null) primaryReveal = (T_Reveal)action; } LocationValue location = GetLocation(primaryMove, primaryReveal); bool isPirate = GetOwner(primaryMove, primaryReveal)=="Pirate DM"; PolygonValue pirateEntryRegion = null; if (isPirate) { foreach (PolygonValue region in entryRegions) { if (Polygon2D.IsPointInside(new Polygon2D(region), new Vec2D(location))) { pirateEntryRegion = region; break; } } } List<Object> list = currentItem.Action.ToList(); List<string> unrevealedObjectIDs = ddd.GetAllUnrevealedObjectIds(false, true, null); if (primaryReveal != null) unrevealedObjectIDs.Remove(primaryReveal.ID); int minStimuli = 0; //If threat type is imminent, we need to guarantee there will be a merchant for the pirate to attack. if (currentItem.Parameters.ThreatType == T_ThreatType.Imminent) minStimuli = 1; int maxStimuli; //If resources need to be available, then two is maximum of stimulus events. if (T_ResourceAvailability.Available == currentItem.Parameters.PlayerResources) maxStimuli = 2; //If resources are unavailable, there must be at least 3 total stimulus events, and max can be higher. else { minStimuli = 3; maxStimuli = 5; } int numStimuliToGenerate = this.changingNumber(minStimuli, 60, minStimuli, maxStimuli); //probably minStimuli but could be up to maxStimuli //If our probability criteria says we should add vessels, try and populate reusable objects list List<DDDAdapter.SeamateObject> reuseableObjects = new List<DDDAdapter.SeamateObject>(); if (shouldAddNewVessel(revealedSeaVessels)) reuseableObjects = findObjectsInPlay(location, pirateEntryRegion, currentItem.Parameters.Groupings, false); for (int i = 0; i < numStimuliToGenerate; i++) { T_Move move = new T_Move(); //Try and recycle objects to create stimulus. if (reuseableObjects.Count != 0) { Shuffle(reuseableObjects); DDDAdapter.SeamateObject objectForReuse = null; //see if any eligible vessels are stopped, if so, use one of them foreach (DDDAdapter.SeamateObject possiblyStoppedVessel in reuseableObjects) { if (possiblyStoppedVessel.Throttle == 0) //yes, it is stopped { //Console.WriteLine("GRoupingGenerator: Picking a stopped vessel " + possiblyStoppedVessel.ID + " to reuse."); objectForReuse = possiblyStoppedVessel; break; } } //randomly pick one of the suitable objects to create a stimulus if (objectForReuse == null) objectForReuse = reuseableObjects[random.Next(reuseableObjects.Count)]; move.ID = objectForReuse.ID; reuseableObjects.Remove(objectForReuse); //Console.WriteLine("GroupingGenerator: Moving existing merchant " + objectForReuse.ID); } else //Reveal and move new merchant. { T_Reveal reveal = new T_Reveal(); reveal.Owner = "Merchant DM"; reveal.State = "FullyFunctional"; reveal.StartupParameters = new T_StartupParameters(); reveal.StartupParameters.Items = new string[0]; reveal.ID = unrevealedObjectIDs[random.Next(unrevealedObjectIDs.Count)]; //pick a random new object unrevealedObjectIDs.Remove(reveal.ID); //take it out of the available list //ADDED 11/10/11: To make sure that the merchants don't end up in the same entry region as a newly created pirate, //if there's a new pirate, instead of iterating over all entry regions we'll remove the pirate's region from the list first. if (pirateEntryRegion != null) entryRegions.Remove(pirateEntryRegion); Vec2D point = null; //If two grouping, pick points in entry regions until one is > 100 away if (currentItem.Parameters.Groupings == T_Groupings.Two) { while (true) { point = new Polygon2D(entryRegions[random.Next(entryRegions.Count)]).PointInside(); if (point.ScalerDistanceTo(new Vec2D(location)) > twoGroupingDistance) { break; } } } //If one grouping, see if any entry region is within 50km. If so, pick a point in that entry region. //It's possible that no entry region may be within 50km. In that case, pick a point in the closest one. if (currentItem.Parameters.Groupings == T_Groupings.One) { double closestDistance = 100000000; PolygonValue closestRegion = null; Shuffle(entryRegions); foreach (PolygonValue entryRegion in entryRegions) { Polygon2D entry2D = new Polygon2D(entryRegion); double distance = Polygon2D.ScalarDistanceToPolygon(entry2D, new Vec2D(location)); if (distance < oneGroupingDistance) { point = entry2D.PointInside(); break; } else { if (distance < closestDistance) { closestDistance = distance; closestRegion = entryRegion; } } } if (point == null) { //Console.WriteLine("GroupingGenerator: Unable to place vessel in an entry region AND <100km away. Placing in closest entry region " + closestDistance + " away."); point = new Polygon2D(closestRegion).PointInside(); } } reveal.Location = new T_Location(); reveal.Location.Item = point.ToLocationValue(); list.Add(reveal); move.ID = reveal.ID; //Console.WriteLine("GroupingGenerator: Revealing new merchant " + reveal.ID + " and moving it"); } move.Location = new T_Location(); list.Add(move); } currentItem.Action = list.ToArray(); }
public override void Generate(T_Item currentItem, String dmID) { actions = currentItem.Action.ToList(); dict = GetActionsAsDictionary(currentItem.Action); grouping = currentItem.Parameters.Groupings; List<string> unrevealedMerchantIDs = ddd.GetAllUnrevealedObjectIds(false, true, null); //Gets only merchants int minStimuli = 1; int maxStimuli; //If resources need to be available, then two is maximum of stimulus events. if (T_ResourceAvailability.Available == currentItem.Parameters.PlayerResources) maxStimuli = Properties.Settings.Default.resourceThreshold-1; //If resources are unavailable, there must be at least 3 total stimulus events, and max can be higher. else { minStimuli = Properties.Settings.Default.resourceThreshold; maxStimuli = Properties.Settings.Default.resourceThreshold*2-1; } int numPirates = dict.Keys.Count; int numMerchants = Math.Max(0, random.Next(minStimuli, maxStimuli) - numPirates); if (numMerchants == 0) return; //If our probability criteria says we should add vessels, let's see if we can reuse any existing vessels List<DDDAdapter.SeamateObject> reuseableVessels = new List<DDDAdapter.SeamateObject>(); List<DDDAdapter.SeamateObject> allExistingMerchants = revealedSeaVessels.FindAll(IsMerchant); if (shouldAddNewVessel(revealedSeaVessels)) reuseableVessels = allExistingMerchants.FindAll(MatchesGroupingConstraints); for (int i = 0; i < numMerchants; i++) //Do once for each merchant we need to create. { //Try and recycle objects to create stimulus. if (reuseableVessels.Count > 0) { DDDAdapter.SeamateObject objectForReuse = null; //Make sure we reuse any stopped objects first List<DDDAdapter.SeamateObject> stoppedObjects = reuseableVessels.FindAll(IsStopped); if (stoppedObjects.Count > 0) objectForReuse = stoppedObjects[random.Next(stoppedObjects.Count)]; else objectForReuse = reuseableVessels[random.Next(reuseableVessels.Count)]; CreateEmptyMove(objectForReuse); reuseableVessels.Remove(objectForReuse); } else //Reveal and move new merchant starting at an appropriate point for grouping constraints. { Vec2D location = null; if (currentItem.Parameters.Groupings == T_Groupings.One) //Get point in closest entry region { location = GetPointInClosestEntryRegion(dict, entryRegions); } else if (currentItem.Parameters.Groupings == T_Groupings.Two) //Get point in any entry region { location = new Polygon2D(entryRegions[random.Next(entryRegions.Count)]).PointInside(); } string id = unrevealedMerchantIDs[random.Next(unrevealedMerchantIDs.Count)]; CreateRevealAndEmptyMove(id, "Merchant DM", location); unrevealedMerchantIDs.Remove(id); } } currentItem.Action = actions.ToArray(); }
void UpdateInActiveRegions(ref SimObject ob) { ob.InActiveRegions.Clear(); foreach (SimActiveRegion sar in m_activeRegions.Values) { Polygon2D azPoly = new Polygon2D(); foreach (PolygonValue.PolygonPoint p in sar.Shape.points) { azPoly.AddVertex(new Vec2D(p.X, p.Y)); } if (Polygon2D.IsPointInside(azPoly, new Vec2D(ob.Location))) { ob.InActiveRegions.Add(sar.ID); } } }
private void NewObject(SimulationEvent e) { //objectProxies = bbClient.GetObjectProxies(); string id = ((StringValue)e["ID"]).value; string type = ((StringValue)e["ObjectType"]).value; if (objectProxies == null) { objectProxies = new Dictionary<string, SimulationObjectProxy>(); } SimulationObjectProxy prox = bbClient.GetObjectProxy(id); if (prox != null) { if (!objectProxies.ContainsKey(id)) { objectProxies.Add(id, prox); } else { objectProxies[id] = prox; } } if (((StringValue)e["ObjectType"]).value == "LandRegion") { StateDB.LandRegion l = new StateDB.LandRegion(((StringValue)e["ID"]).value, null); Polygon2D poly = new Polygon2D(); foreach (PolygonValue.PolygonPoint pp in ((PolygonValue)((AttributeCollectionValue)e["Attributes"]).attributes["Polygon"]).points) { poly.AddVertex(new Vec2D(pp.X, pp.Y)); } l.poly = poly; StateDB.landRegions[l.id] = l; } else if (((StringValue)e["ObjectType"]).value == "ActiveRegion") { StateDB.ActiveRegion b = new StateDB.ActiveRegion(((StringValue)e["ID"]).value, null); double start = ((DoubleValue)((AttributeCollectionValue)e["Attributes"]).attributes["StartHeight"]).value; double end = ((DoubleValue)((AttributeCollectionValue)e["Attributes"]).attributes["EndHeight"]).value; Polygon3D poly2 = new Polygon3D(start, end); foreach (PolygonValue.PolygonPoint pp in ((PolygonValue)((AttributeCollectionValue)e["Attributes"]).attributes["Polygon"]).points) { poly2.AddVertex(new Vec2D(pp.X, pp.Y)); } b.poly = poly2; b.currentAbsolutePolygon = poly2; if (((BooleanValue)((AttributeCollectionValue)e["Attributes"]).attributes["BlocksMovement"]).value) { b.blockingRegion = true; } else { b.blockingRegion = false; } if (((AttributeCollectionValue)e["Attributes"]).attributes.ContainsKey("SpeedMultiplier")) { b.speedMultiplier = ((DoubleValue)((AttributeCollectionValue)e["Attributes"]).attributes["SpeedMultiplier"]).value; } else { b.speedMultiplier = 1; } if (((AttributeCollectionValue)e["Attributes"]).attributes.ContainsKey("IsVisible")) { b.isVisible = ((BooleanValue)((AttributeCollectionValue)e["Attributes"]).attributes["IsVisible"]).value; } else { b.isVisible = false; } if (((AttributeCollectionValue)e["Attributes"]).attributes.ContainsKey("DisplayColor")) { b.displayColor = ((IntegerValue)((AttributeCollectionValue)e["Attributes"]).attributes["DisplayColor"]).value; } else { b.displayColor = -10185235; } if (((AttributeCollectionValue)e["Attributes"]).attributes.ContainsKey("IsDynamicRegion")) { b.isDynamicRegion = ((BooleanValue)((AttributeCollectionValue)e["Attributes"]).attributes["IsDynamicRegion"]).value; } else { b.isDynamicRegion = false; } if (((AttributeCollectionValue)e["Attributes"]).attributes.ContainsKey("ReferencePoint") && !b.isDynamicRegion) //if isDynamic, will use its LinkedObject as Ref. { b.referencePoint = new Vec2D(((LocationValue)((AttributeCollectionValue)e["Attributes"]).attributes["ReferencePoint"])); b.currentAbsolutePolygon = GetAbsolutePolygon(b.referencePoint, poly2.Footprint); } else { b.referencePoint = new Vec2D(0,0); } //Make separate lists for dynamic and active regions in StateDB if (b.isDynamicRegion) { StateDB.dynamicRegions[b.id] = b; } else { StateDB.activeRegions[b.id] = b; } } }
public Polygon3D(double z1,double z2) { footprint = new Polygon2D(); bottom = z1; top = z2; }
private void NewObject(SimulationEvent e) { //objectProxies = bbClient.GetObjectProxies(); string id = ((StringValue)e["ID"]).value; string type = ((StringValue)e["ObjectType"]).value; if (objectProxies == null) { objectProxies = new Dictionary<string, SimulationObjectProxy>(); } SimulationObjectProxy prox = bbClient.GetObjectProxy(id); if (prox != null) { if (!objectProxies.ContainsKey(id)) { objectProxies.Add(id, prox); } else { objectProxies[id] = prox; } } if (((StringValue)e["ObjectType"]).value == "LandRegion") { StateDB.LandRegion l = new StateDB.LandRegion(((StringValue)e["ID"]).value, null); Polygon2D poly = new Polygon2D(); foreach (PolygonValue.PolygonPoint pp in ((PolygonValue)((AttributeCollectionValue)e["Attributes"]).attributes["Polygon"]).points) { poly.AddVertex(new Vec2D(pp.X, pp.Y)); } l.poly = poly; StateDB.landRegions[l.id] = l; } else if (((StringValue)e["ObjectType"]).value == "ActiveRegion") { StateDB.ActiveRegion b = new StateDB.ActiveRegion(((StringValue)e["ID"]).value, null); double start = ((DoubleValue)((AttributeCollectionValue)e["Attributes"]).attributes["StartHeight"]).value; double end = ((DoubleValue)((AttributeCollectionValue)e["Attributes"]).attributes["EndHeight"]).value; Polygon3D poly2 = new Polygon3D(start, end); foreach (PolygonValue.PolygonPoint pp in ((PolygonValue)((AttributeCollectionValue)e["Attributes"]).attributes["Polygon"]).points) { poly2.AddVertex(new Vec2D(pp.X, pp.Y)); } b.poly = poly2; if (((BooleanValue)((AttributeCollectionValue)e["Attributes"]).attributes["BlocksMovement"]).value) { b.blockingRegion = true; } else { b.blockingRegion = false; } if (((AttributeCollectionValue)e["Attributes"]).attributes.ContainsKey("SpeedMultiplier")) { b.speedMultiplier = ((DoubleValue)((AttributeCollectionValue)e["Attributes"]).attributes["SpeedMultiplier"]).value; } else { b.speedMultiplier = 1; } if (((AttributeCollectionValue)e["Attributes"]).attributes.ContainsKey("IsVisible")) { b.isVisible = ((BooleanValue)((AttributeCollectionValue)e["Attributes"]).attributes["IsVisible"]).value; } else { b.isVisible = false; } if (((AttributeCollectionValue)e["Attributes"]).attributes.ContainsKey("DisplayColor")) { b.displayColor = ((IntegerValue)((AttributeCollectionValue)e["Attributes"]).attributes["DisplayColor"]).value; } else { b.displayColor = -10185235; } //b.displayColor = -10185235; //b.isVisible = true; StateDB.activeRegions[b.id] = b; } }
public static Vec2D FindIntersect(Polygon2D poly1, Polygon2D poly2) { List<Vec2D> intersections = new List<Vec2D>(); //with polys, we might have 2 intersections, should we find the middle of the two? List<Vec2D> p2Points = poly2.getVertices(); Vec2D intersect = null; for (int i = 0; i < p2Points.Count - 1; i++) { intersect = FindIntersect(poly1, p2Points[i], p2Points[i + 1]); if (intersect != null) intersections.Add(intersect); } //then once more from len-1 to 0 intersect = FindIntersect(poly1, p2Points[p2Points.Count - 1], p2Points[0]); if (intersect != null) intersections.Add(intersect); if (intersections.Count > 0) return AverageVectors(intersections); return null; }
private void TimeTick(SimulationEvent e) { //update time if (((IntegerValue)e["Time"]).value % 1000 == 0) time = ((IntegerValue)e["Time"]).value / 1000; // time is in ms, we want seconds /* * "Time" is an attribute of all events. The SimulationModel.xml file lists all of the top-level attributes for each event. * Certain events have an additional "Attribute" attribute, which contains a key-value pair collection of additional attributes. * See RevealObject for an example of this. */ if (((IntegerValue)e["Time"]).value == 1000) { InitializeAllScores(); } SimulationObjectProxy obProx; foreach (string id in objectProxies.Keys) { obProx = objectProxies[id]; bool isInSealane = false; bool movingTowardsPort = false; StringListValue slv = obProx["InActiveRegions"].GetDataValue() as StringListValue; LocationValue dest = obProx["DestinationLocation"].GetDataValue() as LocationValue; if(dest.exists) { Vec2D destVec = new Vec2D(dest); Polygon2D p; foreach(Aptima.Asim.DDD.CommonComponents.SimulatorTools.StateDB.ActiveRegion a in StateDB.activeRegions.Values) { if (!a.id.Contains("Entry-")) continue; p = new Polygon2D(); p = a.poly.Footprint; if (Aptima.Asim.DDD.CommonComponents.SimMathTools.Polygon2D.IsPointInside(p, destVec)) { movingTowardsPort = true; } } } if (slv.strings.Count > 0) isInSealane = true; obProx["IsInSeaLane"].SetDataValue(DataValueFactory.BuildBoolean(isInSealane)); obProx["IsGoingTowardsPort"].SetDataValue(DataValueFactory.BuildBoolean(movingTowardsPort)); } }
public static Vec2D FindIntersect(Polygon2D poly, Vec2D fromP, Vec2D toP) { Line line = new Line(fromP, toP); int k, j; Line line2 = new Line(); int count = 0; Vec2D intersect = null; for (k = 0; k < poly.xPoints.Count; k++) { j = k - 1; if (j < 0) { j = poly.xPoints.Count - 1; } line2.p1 = new Vec2D(poly.xPoints[k], poly.yPoints[k]); line2.p2 = new Vec2D(poly.xPoints[j], poly.yPoints[j]); intersect = FindIntersect2(fromP, toP, line2.p1, line2.p2); //AD: Changed to new method for now. if (intersect != null) { return intersect; } } return null; }
public bool SpecialGenerate(T_Item currentItem, String dmID) { Dictionary<T_Move,T_Reveal> dict = GetActionsAsDictionary(currentItem.Action); Dictionary<T_Move, T_Reveal> newDict = new Dictionary<T_Move,T_Reveal>(); List<PolygonValue> seaLanes = ddd.GetAllSeaLanes(); PolygonValue domain = this.ddd.GetDecisionMakersAreaOfResponsibility(dmID); foreach (T_Move key in dict.Keys) { T_Move move = key; T_Reveal reveal = dict[key]; //Is this vessel a pirate? bool isPirate = false; if (reveal!=null) //there's a reveal event { if (reveal.Owner == "Pirate DM") isPirate = true; } else if (ddd.GetSeamateObject(move.ID).Owner == "Pirate DM") isPirate = true; //Vessel's desired perceived ambiguity bool ambiguity = true; if (currentItem.Parameters.Threat == T_Threat.Unambiguous) ambiguity = false; //If it's a merchant and resources aren't unavailable, always make merchants UNambiguous (so IFF is likely to be on) if (!isPirate && currentItem.Parameters.PlayerResources == T_ResourceAvailability.Available) ambiguity = false; //Is it in a sea lane? If it is already in play check, Yes if it is being revealed in an entry region bool locationInSeaLane = false; LocationValue location; if (reveal == null) //already in play location = ddd.GetSeamateObject(move.ID).Location; else location = (LocationValue)reveal.Location.Item; foreach (PolygonValue seaLane in seaLanes) { Polygon2D seaLane2D = new Polygon2D(seaLane); if (Polygon2D.IsPointInside(seaLane2D, new Vec2D(location))) { locationInSeaLane = true; break; } } //Intercept course bool onInterceptCourse = false; if (currentItem.Parameters.ThreatType == T_ThreatType.Imminent && isPirate) onInterceptCourse = true; //IFF bool hasIFFon = false; //Is its IFF already on? if (move == null) //Object already exists in play { String displayName = ddd.GetSeamateObject(move.ID).ObjectName; if (!displayName.StartsWith("unknown")) //Object has IFF set on hasIFFon = true; } //Pick row from ambiguity table using existing constraints. Shuffle(ambiguityTable); bool[] selectedRow = null; foreach (bool[] row in ambiguityTable) { if ((!onInterceptCourse || row[2]) //if onInterceptCourse is true, only allow course to be "on"/true ... if onInterceptCourse is false, either value is OK && (!hasIFFon || row[0]) //same as above for hasIFFon and IFF && (!locationInSeaLane || row[3]) //same as above for inSeaLane and location && ambiguity == row[4]) // ambiguity must match selectedRow = row; } if (selectedRow == null) { return false; //Console.WriteLine("Impossible scenario"); //selectedRow = ambiguityTable[random.Next(ambiguityTable.Length)]; //TODO: Wipe out actions, go back to Threat Generator and make a new object } // Console.WriteLine("AmbiguityGenerator: Making settings for an " + currentItem.Parameters.ThreatType.ToString() + " vessel. IFF should be on?" + selectedRow[0]); //Create scenario described in ambiguity table //IFF ================================= //If we're revealing a new vessel, we can set its IFF on if we need to. Default is off so we don't // have to do anything. We can't change existing ships. if (reveal != null) { if (selectedRow[0] && !isPirate) SetIFF(isPirate, reveal); //If it's a pirate, ignore what it says in the ambiguity table. //Unambiguous == IFF ON always. Ambiguous = IFF OFF always if (isPirate && currentItem.Parameters.Threat == T_Threat.Unambiguous) SetIFF(isPirate, reveal); } //SPEED =============================== double maxSpeed = GetMaxSpeed(move); double newSpeed; if (selectedRow[1]) //speed 69-84 m/s newSpeed = random.Next(69, Math.Max((int)maxSpeed,84)); else { //speed <69 or >84 m/s if (maxSpeed > 84) newSpeed = random.Next(84, (int)maxSpeed); else newSpeed = random.Next(20, 68); } move.Throttle = ((double)newSpeed / (double)maxSpeed); //COURSE ================================= if (selectedRow[2]) { if (onInterceptCourse) // we will take care of this later { } else //if (locationInSeaLane) { //pick any entry region and send it there. Polygon2D entryRegion2D = new Polygon2D(entryRegions[random.Next(entryRegions.Count)]); Vec2D point = entryRegion2D.PointInside(); move.Location = new T_Location(); move.Location.Item = point.ToLocationValue(); } } else { //just send it anywhere ... probably won't be in a sea lane Vec2D point = new Polygon2D(domain).PointInside(); //TODO: this should be in whole scenario boundaries, not just DM domain move.Location = new T_Location(); move.Location.Item = point.ToLocationValue(); //TODO: Send it to the edge of the universe. Just kidding ... to edge of sea region. ddd.GetDecisionMakersAreaOfResponsibility("BAMS DM"); ddd.GetDecisionMakersAreaOfResponsibility("Firescout DM"); } //Add modified move and reveal back to dictionary. newDict[move] = reveal; } currentItem.Action = GetActionsFromDictionary(newDict); return true; }
public Polygon3D(double z1, double z2) { footprint = new Polygon2D(); bottom = z1; top = z2; }