public static Polygon FromRectangle(Rectangle source) { Polygon convertedRectangle = new Polygon(); convertedRectangle.Vertices.Add(new Vector2(source.X, source.Y)); convertedRectangle.Vertices.Add(new Vector2(source.X + source.Width, source.Y)); convertedRectangle.Vertices.Add(new Vector2(source.X + source.Width, source.Y + source.Height)); convertedRectangle.Vertices.Add(new Vector2(source.X, source.Y + source.Height)); return convertedRectangle; }
public static Polygon PolygonCollisionData(string objectName) { Polygon collisionShape = new Polygon(); XElement dataElement = GetCollisionDataElement(objectName, ColliderShape.PolygonCollider); if ((dataElement != null) && (dataElement.Elements("vertex").Count() > 0)) { foreach (XElement vertex in dataElement.Elements("vertex")) { collisionShape.Vertices.Add(new Vector2(Utility.ToFloat(vertex.Attribute("x").Value), Utility.ToFloat(vertex.Attribute("y").Value))); } } return collisionShape; }
public static List<Polygon> CompoundPolygonCollisionData(string objectName) { List<Polygon> collisionShapes = new List<Polygon>(); XElement dataElement = GetCollisionDataElement(objectName, ColliderShape.CompoundPolygonCollider); if ((dataElement != null) && (dataElement.Elements("polygon").Count() > 0)) { foreach (XElement polygon in dataElement.Elements("polygon")) { if (polygon.Elements("vertex").Count() > 0) { Polygon component = new Polygon(); foreach (XElement vertex in polygon.Elements("vertex")) { component.Vertices.Add(new Vector2(Utility.ToFloat(vertex.Attribute("x").Value), Utility.ToFloat(vertex.Attribute("y").Value))); } collisionShapes.Add(component); } } } return collisionShapes; }
public bool Intersects(Polygon target) { if ((this.Vertices.Count > 1) && (target.Vertices.Count > 1)) { bool hasIntersected = true; List<Vector2> edges = new List<Vector2>(); edges.AddRange(GetEdges(this)); edges.AddRange(GetEdges(target)); for (int i = 0; i < edges.Count; i++) { Vector2 axis = new Vector2(-edges[i].Y, edges[i].X); axis.Normalize(); Range subjectProjection = ProjectOntoAxis(axis, this); Range targetProjection = ProjectOntoAxis(axis, target); if (IntervalDistance(subjectProjection, targetProjection) > 0) { hasIntersected = false; break; } } return hasIntersected; } return false; }
public Polygon Clone() { Polygon copy = new Polygon(); for (int i = 0; i < Vertices.Count; i++) { copy.Vertices.Add(new Vector2(Vertices[i].X, Vertices[i].Y)); } return copy; }
private Range ProjectOntoAxis(Vector2 axis, Polygon toProject) { Range projection = new Range(Vector2.Dot(axis, toProject.Vertices[0])); for (int i = 1; i < toProject.Vertices.Count; i++) { projection.Expand(Vector2.Dot(toProject.Vertices[i], axis)); } return projection; }
private List<Vector2> GetEdges(Polygon edgeSource) { List<Vector2> edges = new List<Vector2>(); for (int i = 0; i < edgeSource.Vertices.Count; i++) { edges.Add(edgeSource.Vertices[(i + 1) % edgeSource.Vertices.Count] - edgeSource.Vertices[i]); } return edges; }
public Vector2 Separate(Polygon target, Vector2 velocity) { if ((this.Vertices.Count > 1) && (target.Vertices.Count > 1)) { bool hasIntersected = true; bool willIntersect = true; Vector2 separationAxis = Vector2.Zero; float separationInterval = float.PositiveInfinity; List<Vector2> edges = new List<Vector2>(); edges.AddRange(GetEdges(this)); edges.AddRange(GetEdges(target)); for (int i = 0; i < edges.Count; i++) { Vector2 axis = new Vector2(-edges[i].Y, edges[i].X); axis.Normalize(); Range subjectProjection = ProjectOntoAxis(axis, this); Range targetProjection = ProjectOntoAxis(axis, target); if (IntervalDistance(subjectProjection, targetProjection) > 0) { hasIntersected = false; } float velocityProjection = Vector2.Dot(axis, velocity); if (velocityProjection < 0) { subjectProjection.Minimum += velocityProjection; } else { subjectProjection.Maximum += velocityProjection; } float intervalDistance = IntervalDistance(subjectProjection, targetProjection); if (intervalDistance > 0) { willIntersect = false; } if ((!hasIntersected) && (!willIntersect)) { break; } if ((intervalDistance <= 0.0f) && (Math.Abs(intervalDistance) < separationInterval)) { separationInterval = Math.Min(Math.Abs(intervalDistance), separationInterval); separationAxis = axis; if (Vector2.Dot(this.Center - target.Center, separationAxis) < 0.0f) { separationAxis = -separationAxis; } } } if (willIntersect) { return separationAxis * separationInterval; } } return Vector2.Zero; }