public void AddVertex(Vec2D p) { if (xPoints.Count == 0) { bboxXMax = bboxXMin = p.X; bboxYMax = bboxYMin = p.Y; } xPoints.Add(p.X); yPoints.Add(p.Y); if (p.X < bboxXMin) { bboxXMin = p.X; } if (p.X > bboxXMax) { bboxXMax = p.X; } if (p.Y < bboxYMin) { bboxYMin = p.Y; } if (p.Y > bboxYMax) { bboxYMax = p.Y; } }
public Vec2D Multiply(double s) { Vec2D r = new Vec2D(this); r.X *= s; r.Y *= s; return r; }
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); }
/// <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 DoLinesIntersect(Vec2D p1, Vec2D p2, Vec2D p3, Vec2D p4) { double x1 = p1.X; double x2 = p2.X; double x3 = p3.X; double x4 = p4.X; double y1 = p1.Y; double y2 = p2.Y; double y3 = p3.Y; double y4 = p4.Y; double ua = (((x4 - x3) * (y1 - y3)) - ((y4 - y3) * (x1 - x3))) / (((y4 - y3) * (x2 - x1)) - ((x4 - x3) * (y2 - y1))); double ub = (((x2 - x1) * (y1 - y3)) - ((y2 - y1) * (x1 - x3))) / (((y4 - y3) * (x2 - x1)) - ((x4 - x3) * (y2 - y1))); double x = x1 + (ua * (x2 - x1)); double y = y1 + (ub * (y2 - y1)); bool xr = Math.Min(x1, x2) <= x && x <= Math.Max(x1, x2); bool yr = Math.Min(y1, y2) <= y && y <= Math.Max(y1, y2); return(xr && yr); }
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); }
public static bool DeriveAbsoluteVerticesFromRelative(String currentReferencePoint, String relativeVertices, out String absoluteVertexList) { StringBuilder vertices = new StringBuilder(); char[] cS = {' '}; String[] rpSplit = currentReferencePoint.Split(cS, StringSplitOptions.RemoveEmptyEntries); if (rpSplit.Length != 2) { absoluteVertexList = ""; return false; } Vec2D refPt = new Vec2D(double.Parse(rpSplit[0]),double.Parse(rpSplit[1])); String[] sS = { ")," }; String[] vertSplit = relativeVertices.Split(sS, StringSplitOptions.RemoveEmptyEntries); foreach (String s in vertSplit) { String[] pS = {","}; String[] pt = s.Split(pS, StringSplitOptions.RemoveEmptyEntries); Vec2D v = new Vec2D(double.Parse(pt[0].Replace(',', ' ').Replace('(', ' ').Replace(')', ' ').Trim()), double.Parse(pt[1].Replace(',', ' ').Replace('(', ' ').Replace(')', ' ').Trim())); v.X += refPt.X; v.Y += refPt.Y; vertices.AppendFormat("({0}, {1}), ", v.X, v.Y); } if (vertices.Length > 2) { vertices.Remove(vertices.Length - 2, 1); } absoluteVertexList = vertices.ToString(); return true; }
public T_Move SetToInterceptCourse(T_Move move, T_Reveal reveal, Dictionary<T_Move, T_Reveal> merchantsDict) { //Pick the closest merchant, either newly revealed or existing. double distance = 1000000000000000; T_Move closestKey = null; Vec2D location = new Vec2D(GetLocation(move, reveal)); foreach (T_Move key in merchantsDict.Keys) { double thisDistance = new Vec2D(location).ScalerDistanceTo(new Vec2D(GetLocation(key,merchantsDict[key]))); if (thisDistance < distance) { closestKey = key; distance = thisDistance; } } double merchantSpeed = closestKey.Throttle*GetMaxSpeed(closestKey); Vec2D merchantStart = new Vec2D(GetLocation(closestKey, merchantsDict[closestKey])); Vec2D merchantDestination = new Vec2D((LocationValue)closestKey.Location.Item); Vec2D interceptPoint = GetInterceptPoint(merchantStart, merchantDestination, merchantSpeed, location, GetMaxSpeed(move)); move.Location = new T_Location(); move.Location.Item = interceptPoint.ToLocationValue(); Console.WriteLine("setting pirate " + move.ID + " on intercept course to merchant " + closestKey.ID); return move; }
private void TimeTick(SimulationEvent e) { foreach (StateDB.ActiveRegion region in StateDB.dynamicRegions.Values) { if (region.linkedObject == "") continue; //don't draw unlinked regions SimulationObjectProxy obProx = objectProxies[region.linkedObject]; //Calculate new absolute poly for region and send ViewPro event LocationValue lvLoc = (LocationValue)obProx["Location"].GetDataValue(); Vec2D loc = new Vec2D(lvLoc); if (!lvLoc.exists) { return; //possible that the tractor object doesn't exist, so don't show it. } Polygon3D absolutePoly = GetAbsolutePolygon(loc, region.poly.Footprint); absolutePoly.TopZ = region.poly.TopZ; absolutePoly.BottomZ = region.poly.BottomZ; region.referencePoint = loc; region.currentAbsolutePolygon = absolutePoly; this.SendViewProActiveRegionUpdate(region.id, region.isVisible, region.displayColor, absolutePoly); } }
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 Vec2D Add(Vec2D v2) { Vec2D r = new Vec2D(this); r.X += v2.X; r.Y += v2.Y; return(r); }
public Vec2D Multiply(double s) { Vec2D r = new Vec2D(this); r.X *= s; r.Y *= s; return(r); }
public Vec2D VectorDistanceTo(Vec2D v2) { Vec2D r = new Vec2D(v2); r.X -= X; r.Y -= Y; return(r); }
public static Vec2D FindIntersect(Vec2D from1, Vec2D to1, Vec2D from2, Vec2D to2) { double x1 = from1.X; double y1 = from1.Y; double x2 = to1.X; double y2 = to1.Y; double x3 = from2.X; double y3 = from2.Y; double x4 = to2.X; double y4 = to2.Y; double ua = (((x4 - x3) * (y1 - y3)) - ((y4 - y3) * (x1 - x3))) / (((y4 - y3) * (x2 - x1)) - ((x4 - x3) * (y2 - y1))); double ub = (((x2 - x1) * (y1 - y3)) - ((y2 - y1) * (x1 - x3))) / (((y4 - y3) * (x2 - x1)) - ((x4 - x3) * (y2 - y1))); double x = x1 + (ua * (x2 - x1)); double y = y1 + (ub * (y2 - y1)); bool lineOneIsVertical = x2 == x1; bool lineTwoIsVertical = x3 == x4; bool xr = Math.Min(x1, x2) <= x && x <= Math.Max(x1, x2); bool yr = Math.Min(y1, y2) <= y && y <= Math.Max(y1, y2); if (lineOneIsVertical || lineTwoIsVertical) { //Because line one is vertical we want to check that the intersection point (x,y) crosses both y values for the segment //this is important because vertical lines don't have a slope, and will trick the above calculation to returning TRUE when the segment //doesn't cross the second segment if (Math.Min(y3, y4) <= y && y <= Math.Max(y3, y4)) { yr = yr && true; } else { yr = yr && false; } } if (xr && yr) { Vec2D r = new Vec2D(x, y); return(r); } else { return(null); } //return xr && yr; }
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 Vec3D FindIntersect(Polygon3D poly, Vec3D fromP, Vec3D toP) { Vec2D intersect = Polygon2D.FindIntersect(poly.footprint, new Vec2D(fromP.X, fromP.Y), new Vec2D(toP.X, toP.Y)); if (intersect != null) { return(new Vec3D(intersect.X, intersect.Y, fromP.Z)); } else { return(null); } }
public Vec2D PointInside() { double x = random.Next((int)this.bboxXMin, (int)this.bboxXMax); double y = random.Next((int)this.bboxYMin, (int)this.bboxYMax); Vec2D vector = new Vec2D(x, y); if (IsPointInside(this, vector)) { return(vector); } else { return(PointInside()); } }
private static Vec2D AverageVectors(List <Vec2D> listOfVectors) { Vec2D returnValue = new Vec2D(0, 0); double totalX = 0.0; double totalY = 0.0; int count = 0; foreach (Vec2D v in listOfVectors) { totalX += v.X; totalY += v.Y; count++; } returnValue.X = totalX / (double)count; returnValue.Y = totalY / (double)count; return(returnValue); }
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); }
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); }
public static Vec2D FindIntersect2(Vec2D from1, Vec2D to1, Vec2D from2, Vec2D to2) { Vec2D E = new Vec2D(to1.X - from1.X, to1.Y - from1.Y); Vec2D F = new Vec2D(to2.X - from2.X, to2.Y - from2.Y); Vec2D P = new Vec2D(-1 * E.Y, E.X); double h = (VectorDotProduct(new Vec2D(from1.X - from2.X, from1.Y - from2.Y), P) / VectorDotProduct(F, P)); double FxP = VectorDotProduct(F, P); if ((h < 0 || h > 1) && FxP != 0.0) { return(null); } else if (FxP == 0.0) { //only equal if both line segments are overlapping } double x = from2.X + F.X * h; //Cx + Dx*h; double y = from2.Y + F.Y * h; //Cy + Dy*h bool lineOneIsVertical = to1.X == from1.X; bool lineTwoIsVertical = to2.X == from2.X; // if (lineOneIsVertical || lineTwoIsVertical) //{ //Because line one is vertical we want to check that the intersection point (x,y) crosses both y values for the segment //this is important because vertical lines don't have a slope, and will trick the above calculation to returning TRUE when the segment //doesn't cross the second segment if ((Math.Min(from2.Y, to2.Y) <= y && y <= Math.Max(from2.Y, to2.Y) && Math.Min(from1.Y, to1.Y) <= y && y <= Math.Max(from1.Y, to1.Y)) && (Math.Min(from2.X, to2.X) <= x && x <= Math.Max(from2.X, to2.X) && Math.Min(from1.X, to1.X) <= x && x <= Math.Max(from1.X, to1.X))) { //we're good } else { return(null); } // } return(new Vec2D(x, y)); }
/// <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); }
public static Vec2D ClosestPointOnLineSegment(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(s0); } double c2 = VectorDotProduct(v, v); if (c2 <= c1) { return(s1); } double b = c1 / c2; Vec2D Pb = s0.Add(v.Multiply(b)); return(Pb); }
public Vec2D Add(Vec2D v2) { Vec2D r = new Vec2D(this); r.X += v2.X; r.Y += v2.Y; return r; }
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)); } }
/// <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; }
//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; } }
//Boolean IsBlocked() //{ // if (Paused) // { // m_blockedBy = "PAUSED"; // m_isBlocked = true; // return m_isBlocked; // } // SimObject me = m_dmView.AllObjects[m_thisID]; // //SimObject dest = m_dmView.AllObjects[m_destID]; // LocationValue myLoc = me.Location; // //LocationValue destLoc = dest.Location; // LocationValue otherLocation = null; // Vec2D myVec = new Vec2D(myLoc); // Vec2D otherVec = null; // Vec2D destVec = new Vec2D(m_destLocation); // Polygon2D poly = GetPoly(myVec, destVec); // foreach (String id in m_dmView.AllObjects.Keys) // { // if (id == m_thisID) // { // continue; // } // if (!m_objectClassesToAvoid.Contains(m_dmView.AllObjects[id].ClassName)) // { // continue; // } // otherLocation = m_dmView.AllObjects[id].Location; // otherVec = new Vec2D(otherLocation); // if (Polygon2D.IsPointInside(poly, otherVec)) // { // if (myVec.ScalerDistanceTo(otherVec) < m_avoidRange) // { // m_blockedBy = id; // m_isBlocked = true; // return m_isBlocked; // } // } // } // if (m_holdWP != null) // { // otherVec = new Vec2D(m_holdWP.Location); // if (Polygon2D.IsPointInside(poly, otherVec)) // { // if (myVec.ScalerDistanceTo(otherVec) < m_avoidRange) // { // //Console.Out.WriteLine(String.Format("MoveWithAvoidanceBehavior.IsBlocked() {0} true", m_thisID)); // m_blockedBy = "HOLD"; // m_isBlocked = true; // return m_isBlocked; // } // } // } // //Console.Out.WriteLine(String.Format("MoveWithAvoidanceBehavior.IsBlocked() {0} false", m_thisID)); // m_blockedBy = String.Empty; // m_isBlocked = false; // return m_isBlocked; //} Boolean IsBlocked2() { if (Paused) { m_blockedBy = "PAUSED"; m_isBlocked = true; return m_isBlocked; } if (!ShouldAvoid) { m_blockedBy = String.Empty; ; m_isBlocked = false; return m_isBlocked; } SimObject me = m_dmView.AllObjects[m_thisID]; LocationValue myLoc = me.Location; LocationValue otherLocation = null; Vec2D myVec = new Vec2D(myLoc); Vec2D otherVec = null; Vec2D destVec = new Vec2D(m_destLocation); Vec2D farPoint = ProjectPointOnLine(myVec, destVec, m_avoidRange); //Polygon2D poly = GetPoly(myVec, destVec); foreach (String id in m_dmView.AllObjects.Keys) { if (id == m_thisID) { continue; } if (!m_objectClassesToAvoid.Contains("ALL")) { if (!m_objectClassesToAvoid.Contains(m_dmView.AllObjects[id].ClassName)) { continue; } } otherLocation = m_dmView.AllObjects[id].Location; otherVec = new Vec2D(otherLocation); double d = BehaviorHelper.DistanceFromPointToLineSegment(otherVec, myVec, farPoint); if (d < (m_avoidPathWidth / 2)) { m_blockedBy = id; m_isBlocked = true; return m_isBlocked; } } if (m_holdWP != null) { otherVec = new Vec2D(m_holdWP.Location); double d2 = BehaviorHelper.DistanceFromPointToLineSegment(otherVec, myVec, farPoint); if (d2 < (m_avoidPathWidth / 2)) { m_blockedBy = "HOLD"; m_isBlocked = true; return m_isBlocked; } } //Console.Out.WriteLine(String.Format("MoveWithAvoidanceBehavior.IsBlocked() {0} false", m_thisID)); m_blockedBy = String.Empty; m_isBlocked = false; return m_isBlocked; }
/// <summary> /// Determines whether a merchant is within grouping constraints of previously chosen pirates. /// </summary> /// <param name="vessel">Merchant</param> /// <returns>Boolean</returns> private bool MatchesGroupingConstraints(DDDAdapter.SeamateObject vessel) { if (vessel.Intent != "") return false; if (grouping == T_Groupings.One) { foreach (T_Move key in dict.Keys) { Vec2D otherVesselLocation = new Vec2D(GetLocation(key, dict[key])); double distance = new Vec2D(vessel.Location).ScalerDistanceTo(otherVesselLocation); if (distance > oneGroupingDistance) return false; } return true; } else { return true; } }
/// <summary> /// Returns a boolean value expressing whether or not a new vessel can be added to an existing group while fulfilling /// grouping constraints. /// One grouping: Every item in the group must be within the one-grouping parameter of each other. /// Two grouping: At least one pair in the group must be separated by the two-grouping parameter. /// </summary> /// <param name="oneOrTwo">Must be "One" or "Two" for a one- or two-grouping</param> /// <param name="newVessel">Vessel to be added to the group</param> /// <param name="otherVessels">Existing group of vessels</param> /// <returns></returns> private bool MatchesGroupingCriteria(T_Groupings grouping, DDDAdapter.SeamateObject newVessel, List<DDDAdapter.SeamateObject> otherVessels) { if (otherVessels.Contains(newVessel)) return false; if (grouping == T_Groupings.One) { foreach (DDDAdapter.SeamateObject vessel in otherVessels) { double distance = new Vec2D(vessel.Location).ScalerDistanceTo(new Vec2D(newVessel.Location)); if (distance > oneGroupingDistance) return false; } return true; } else { foreach (DDDAdapter.SeamateObject vessel in otherVessels) { double distance = new Vec2D(vessel.Location).ScalerDistanceTo(new Vec2D(newVessel.Location)); if (distance > twoGroupingDistance) return true; } return false; } }
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); }
static double DotProduct(Vec2D v1, Vec2D v2) { return v1.X * v2.X + v1.Y * v2.Y; }
public void Set(Vec2D v) { X = v.X; Y = v.Y; }
public double ScalerDistanceTo(Vec2D v2) { return Math.Sqrt(Math.Pow(v2.X - X, 2) + Math.Pow(v2.Y - Y, 2)); }
public Line() { this.p1 = null; this.p2 = null; }
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 Line(Vec2D p1, Vec2D p2) { this.p1 = p1; this.p2 = p2; }
/// <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; }
//isPirate here refers to the objects we are trying to find, e.g. isPirate = true means find pirates private List<SeamateAdapter.DDD.DDDAdapter.SeamateObject> findObjectsInPlay(LocationValue nearby, PolygonValue pirateEntryRegion, T_Groupings grouping, bool isPirate) { List<DDDAdapter.SeamateObject> vessels = new List<DDDAdapter.SeamateObject>(); foreach (DDDAdapter.SeamateObject vessel in ddd.GetAllRevealedSeaVessels()) { if (isPirate && vessel.Owner == "Pirate DM" || !isPirate && vessel.Owner == "Merchant DM") { } else continue; double distance = new Vec2D(vessel.Location).ScalerDistanceTo(new Vec2D(nearby)); bool inSameEntryRegionAsPirate = false; if (pirateEntryRegion != null) inSameEntryRegionAsPirate = Polygon2D.IsPointInside(new Polygon2D(pirateEntryRegion),new Vec2D(vessel.Location)); if (grouping == T_Groupings.One && distance < oneGroupingDistance && !inSameEntryRegionAsPirate) { vessels.Add(vessel); } else if (grouping == T_Groupings.Two && distance > twoGroupingDistance && !inSameEntryRegionAsPirate) { vessels.Add(vessel); } } return vessels; }
/// <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)); }
public Vec2D(Vec2D v) { X = v.X; Y = v.Y; }
Vec2D ProjectPointOnLine(Vec2D p1, Vec2D p2, Double d) { Vec2D r = new Vec2D(0,0); Double d1, x1, y1, x2, y2, x3, y3; x1 = p1.X; y1 = p1.Y; x2 = p2.X; y2 = p2.Y; d1 = Math.Sqrt(Math.Pow(x2 -x1,2) + Math.Pow(y2 - y1,2)); if ((y2 == y1) && (x2 == x1)) // p1 == p2 is not allowed { return null; } else { x3 = x1 + ((d * (x2 - x1)) / d1); y3 = y1 + ((d * (y2 - y1)) / d1); r.X = x3; r.Y = y3; return r; } }
private bool OnLandRegion(Vec2D loc) { foreach (StateDB.LandRegion reg in StateDB.landRegions.Values) { if (Polygon2D.IsPointInside(reg.poly, loc)) { return true; } } return false; }
public ActiveRegion(string id, Polygon3D poly) { this.id = id; this.poly = poly; this.sensorsBlocked = new List<string>(); this.blockingRegion = false; this.speedMultiplier = 1; this.isVisible = true; this.displayColor = 0; this.linkedObject = ""; this.isDynamicRegion = false; this.referencePoint = new Vec2D(0,0); this.currentAbsolutePolygon = new Polygon3D(0, 0); }
static public double DistanceFromPointToLineSegment(Vec2D point, Vec2D anchor, Vec2D end) { Vec2D d = end.Add(anchor.Multiply(-1)); double length = Vec2DLength(d); if (length == 0) return Vec2DLength(point.Add(anchor.Multiply(-1))); d.Normalize(); double intersect = DotProduct(point.Add(anchor.Multiply(-1)), d); if (intersect < 0) return Vec2DLength(point.Add(anchor.Multiply(-1))); if (intersect > length) return Vec2DLength(point.Add(end.Multiply(-1))); return Vec2DLength(point.Add(anchor.Add(d.Multiply(intersect)).Multiply(-1))); }
public double ScalerDistanceTo(Vec2D v2) { return(Math.Sqrt(Math.Pow(v2.X - X, 2) + Math.Pow(v2.Y - Y, 2))); }
public void AddVertex(Vec2D p) { footprint.AddVertex(p); }
public DynamicRegion(string id, Polygon3D poly, Vec2D refPoint) { this.id = id; this.poly = poly; this.sensorsBlocked = new List<string>(); this.blockingRegion = false; this.speedMultiplier = 1; this.isVisible = true; this.displayColor = 0; this.referencePoint = refPoint; }
public static double VectorDotProduct(Vec2D v1, Vec2D v2) { return(v1.X * v2.X + v1.Y * v2.Y); }
/// <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; }
static double Vec2DLength(Vec2D v) { return Math.Sqrt(v.X*v.X + v.Y*v.Y); }
public Vec2D VectorDistanceTo(Vec2D v2) { Vec2D r = new Vec2D(v2); r.X -= X; r.Y -= Y; return r; }