예제 #1
0
        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;
        }
예제 #4
0
        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;
        }
예제 #5
0
        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;
        }
예제 #6
0
        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;
        }
예제 #7
0
        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;
        }
예제 #8
0
        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;
        }