示例#1
1
        // Check if polygon A is going to collide with polygon B for the given velocity
        public SvgCollision.PolygonCollisionResult PolygonCollision(Polygon polygonA, Polygon polygonB, Vector velocity)
        {
            SvgCollision.PolygonCollisionResult result = new SvgCollision.PolygonCollisionResult();
            result.IsIntersecting = true;
            result.WillIntersect = true;

            int edgeCountA = polygonA.Edges.Count;
            int edgeCountB = polygonB.Edges.Count;
            float minIntervalDistance = float.PositiveInfinity;
            Vector translationAxis = new Vector();
            Vector edge;

            // Loop through all the edges of both polygons
            for (int edgeIndex = 0; edgeIndex < edgeCountA + edgeCountB; edgeIndex++) {
                if (edgeIndex < edgeCountA) {
                    edge = polygonA.Edges[edgeIndex];
                } else {
                    edge = polygonB.Edges[edgeIndex - edgeCountA];
                }

                // ===== 1. Find if the polygons are currently intersecting =====

                // Find the axis perpendicular to the current edge
                Vector axis = new Vector(-edge.Y, edge.X);
                axis.Normalize();

                // Find the projection of the polygon on the current axis
                float minA = 0; float minB = 0; float maxA = 0; float maxB = 0;
                ProjectPolygon(axis, polygonA, ref minA, ref maxA);
                ProjectPolygon(axis, polygonB, ref minB, ref maxB);

                // Check if the polygon projections are currentlty intersecting
                float intervalDistance = IntervalDistance(minA, maxA, minB, maxB);
                if (intervalDistance > 0) result.IsIntersecting = false;

                // ===== 2. Now find if the polygons *will* intersect =====
                // Project the velocity on the current axis
                float velocityProjection = axis.DotProduct(velocity);

                // Get the projection of polygon A during the movement
                if (velocityProjection < 0) {
                    minA += velocityProjection;
                } else {
                    maxA += velocityProjection;
                }

                // Do the same test as above for the new projection
                intervalDistance = IntervalDistance(minA, maxA, minB, maxB);
                if (intervalDistance > 0) result.WillIntersect = false;

                // If the polygons are not intersecting and won't intersect, exit the loop
                if (!result.IsIntersecting && !result.WillIntersect) break;

                // Check if the current interval distance is the minimum one. If so store
                // the interval distance and the current distance.
                // This will be used to calculate the minimum translation vector
                intervalDistance = Math.Abs(intervalDistance);
                if (intervalDistance < minIntervalDistance) {
                    minIntervalDistance = intervalDistance;
                    translationAxis = axis;

                    Vector d = polygonA.Center - polygonB.Center;
                    if (d.DotProduct(translationAxis) < 0) translationAxis = -translationAxis;
                }
            }

            // The minimum translation vector can be used to push the polygons appart.
            // First moves the polygons by their velocity
            // then move polygonA by MinimumTranslationVector.
            if (result.WillIntersect) result.MinimumTranslationVector = translationAxis * minIntervalDistance;

            return result;
        }
示例#2
0
文件: Form1.cs 项目: jrnker/SVG
        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            try
            {
            var t = new XmlDocument();
            t.XmlResolver = null; // Don't verify the XML
            t.LoadXml(textBox1.Text.Substring(textBox1.Text.IndexOf("<svg")));
            FSvgDoc = SvgDocument.Open(t);

            pictureBox1.Image = FSvgDoc.Draw();
            IterateKids(FSvgDoc.Children);

            Vector velocity = new Vector(0, 20);
            DateTime dte1, dte2;
            List<SvgCollision.PolygonCollisionResult> collisions;

            //dte1 = DateTime.Now;
            //collisions = SvgCollision.checkForCollision(FSvgDoc.Children, SvgCollision.collisionCheckType.LineCollision, velocity);
            //dte2 = DateTime.Now;
            //Debug.WriteLine((dte2 - dte1).TotalMilliseconds.ToString());
            //foreach (SvgCollision.PolygonCollisionResult col in collisions)
            //{
            //    //Debug.WriteLine(col.collidor.ToString() + " intersects with " + col.collidee.ToString() + "\tIsIntersecting=" + col.IsIntersecting + "\tWillIntersect=" + col.WillIntersect + "\tOnPath=" + col.OnPath);
            //}

            //dte1 = DateTime.Now;
            //collisions = SvgCollision.checkForCollision(FSvgDoc.Children, SvgCollision.collisionCheckType.SeparatingAxisTheorem, velocity);
            //dte2 = DateTime.Now;
            //Debug.WriteLine((dte2 - dte1).TotalMilliseconds.ToString());
            //foreach (SvgCollision.PolygonCollisionResult col in collisions)
            //{
            //    //Debug.WriteLine(col.collidor.ToString() + " intersects with " + col.collidee.ToString() + "\tIsIntersecting=" + col.IsIntersecting + "\tWillIntersect=" + col.WillIntersect + "\tOnPath=" + col.OnPath);
            //}

            dte1 = DateTime.Now;
            collisions = SvgCollision.checkForCollision(FSvgDoc.Children, SvgCollision.collisionCheckType.Mixed,0, velocity);
            dte2 = DateTime.Now;
            Debug.WriteLine((dte2 - dte1).TotalMilliseconds.ToString() + "\t" + collisions.Count + " collisions found");

            foreach (SvgCollision.PolygonCollisionResult col in collisions)
            {
                Debug.WriteLine(col.collidor.ToString() + " intersects with " + col.collidee.ToString() + "\tIsIntersecting=" + col.IsIntersecting + "\tWillIntersect=" +
                    col.WillIntersect + "\tOnPath=" + col.OnPath + "\tRayCasting=" + col.rayCastingResult + "\tMinVector=" + col.MinimumTranslationVector.X + "," + col.MinimumTranslationVector.Y   );
            }
            }
            catch { }

            //drawCirclePath(FSvgDoc.Children);
        }
示例#3
0
 /// <summary>
 /// Test all visualelements in a SvgElementCollection for collisions and return the result as a list of PolygonCollisionResult
 /// </summary>
 /// <param name="elCol"></param>
 /// <param name="colCheckType">Optional</param>
 /// <param name="minimumArea">Optional, should only be used if a majority of objects should be excluded from collision detection as it otherwise can cause a large performance penalty</param>
 /// <param name="velocity">Optional to simulate movement of all objects in certain direction. Result stored in PolygonCollisionResult.WillIntersect.</param>
 /// <returns></returns>
 public static List<PolygonCollisionResult> checkForCollision(SvgElementCollection elCol, collisionCheckType colCheckType = collisionCheckType.Mixed, float minimumArea = 0, Vector velocity = default(Vector))
 {
     _collisionResultList = new List<PolygonCollisionResult>();
     _elCol = elCol;
     _velocity = velocity;
     _colCheckType = colCheckType;
     _minimumArea = minimumArea;
     iterate(elCol, elCol);
     return _collisionResultList;
 }
示例#4
0
 // Calculate the projection of a polygon on an axis and returns it as a [min, max] interval
 public void ProjectPolygon(Vector axis, Polygon polygon, ref float min, ref float max)
 {
     // To project a point on an axis use the dot product
     float d = axis.DotProduct(polygon.Points[0]);
     min = d;
     max = d;
     for (int i = 0; i < polygon.Points.Count; i++) {
         d = polygon.Points[i].DotProduct(axis);
         if (d < min) {
             min = d;
         } else {
             if (d > max) {
                 max = d;
             }
         }
     }
 }
示例#5
0
        public static SvgCollision.PolygonCollisionResult PolygonCollision(PointF[] ptsA, PointF[] ptsB, Vector velocity)
        {
            Polygon polygonA, polygonB;
            polygonA = new Polygon();
            polygonB = new Polygon();
            foreach (PointF pts in ptsA)
            {
                polygonA.Points.Add(new Vector(pts.X, pts.Y));
            }
            foreach (PointF pts in ptsB)
            {
                polygonB.Points.Add(new Vector(pts.X, pts.Y));
            }

            polygonA.BuildEdges();
            polygonB.BuildEdges();

            SeparatingAxisTheorem svgCollision = new SeparatingAxisTheorem();
            return svgCollision.PolygonCollision(polygonA, polygonB, velocity);
        }
示例#6
0
 public void Offset(float x, float y)
 {
     for (int i = 0; i < points.Count; i++)
     {
         Vector p = points[i];
         points[i] = new Vector(p.X + x, p.Y + y);
     }
 }
示例#7
0
 public void Offset(Vector v)
 {
     Offset(v.X, v.Y);
 }
示例#8
0
 public bool Equals(Vector v)
 {
     return X == v.X && Y == v.Y;
 }
示例#9
0
 public float DotProduct(Vector vector)
 {
     return this.X * vector.X + this.Y * vector.Y;
 }
示例#10
0
 public float DistanceTo(Vector vector)
 {
     return (float)Math.Sqrt(Math.Pow(vector.X - this.X, 2) + Math.Pow(vector.Y - this.Y, 2));
 }