Polygon, not necessarily axis-aligned
Inheritance: Body
Ejemplo n.º 1
0
        /// <summary>
        /// Intersection detection function
        /// Mostly derived from http://www.codeproject.com/Articles/15573/2D-Polygon-Collision-Detection
        /// </summary>
        /// <param name="other">The other Body to check intersection with</param>
        /// <returns>Vector2.Zero for no intersection, and minimum translation vector if there is an intersection</returns>
        public override Vector2 Intersects(Polygon other)
        {
            //Separating Axis Theorem
            int edgeCountA = this.Edges.Length;
            int edgeCountB = other.Edges.Length;
            float minIntervalDistance = 0;
            Vector2 translationAxis = Vector2.Zero;
            Vector2 edge;

            for (int edgeIndex = 0; edgeIndex < edgeCountA + edgeCountB; edgeIndex++)
            {
                if (edgeIndex < edgeCountA)
                {
                    edge = this.Edges[edgeIndex];
                }
                else
                {
                    edge = other.Edges[edgeIndex - edgeCountA];
                }

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

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

                // Find the projection of the polygon on the current axis
                float minA = 0, minB = 0, maxA = 0, maxB = 0;
                ProjectRectangle(axis, this, ref minA, ref maxA);
                ProjectRectangle(axis, other, ref minB, ref maxB);

                // Check if the polygon projections are currentlty intersecting
                float intervalDistance = IntervalDistance(minA, maxA, minB, maxB);
                if (intervalDistance > 0)
                {
                    return Vector2.Zero;
                }

                // 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 Vector2
                if (intervalDistance > minIntervalDistance || minIntervalDistance == 0)
                {
                    minIntervalDistance = intervalDistance;
                    translationAxis = axis;

                    Vector2 d = this.Position - other.Position;
                    if (d.X * translationAxis.X + d.Y * translationAxis.Y < 0)
                        translationAxis = -translationAxis;
                }
            }
            //Console.WriteLine(minIntervalDistance);
            return translationAxis * minIntervalDistance;
        }
Ejemplo n.º 2
0
        private void ApplyForce(float scale, Polygon player, Vector2 position, float deltaTime)
        {
            // Force drops off as 1/r for objects and 1/r^2 for players
            foreach (Particle part in game.particles)
            {
                Vector2 dist = part.Position - position;
                float length = dist.Length();
                if (length != 0)
                {
                    Vector2 force = scale * dist / (length * length);
                    if (force.LengthSquared() > GameData.MAX_FORCE)
                    {
                        force.Normalize();
                        force *= GameData.MAX_FORCE;
                    }
                    part.Velocity += force * deltaTime;
                }
            }
            foreach (Drop drop in game.drops)
            {
                Vector2 dist = drop.Position - position;
                float length = dist.Length();
                if (length != 0)
                {
                    Vector2 force = scale * dist / (length * length);
                    if (force.LengthSquared() > GameData.MAX_FORCE)
                    {
                        force.Normalize();
                        force *= GameData.MAX_FORCE;
                    }
                    drop.Velocity += force * deltaTime;
                }
            }
            foreach (Player body in game.players)
            {
                if (body != player)
                {
                    //Console.WriteLine(body.Velocity + "\t\t" + player.Velocity);
                    Vector2 dist = body.Position - position;
                    float length = dist.Length();
                    if (length != 0)
                    {
                        Vector2 force = scale * dist / (length * length);
                        if (force.Length() > GameData.MAX_FORCE)
                        {
                            force.Normalize();
                            force *= GameData.MAX_FORCE;
                        }
                        Console.WriteLine("Applying force: " + force);
                        body.Velocity += force * deltaTime; // 1/r for gravity

                        // User basically loses control if they are closer than the threshold
                        if (length < GameData.BOOMERANG_ANTIGRAV)
                        {
                            //if (force.X * body.Velocity.X > 0)      // Velocity.X and force are in same direction
                            //    body.TargetVelocity = body.Velocity.X;
                            body.Velocity.Y -= GameData.GRAVITY * deltaTime;
                        }
                        //Console.WriteLine("TargetVelocity: {0}", body.TargetVelocity);
                    }
                }
            }
        }
Ejemplo n.º 3
0
 private static void ProjectRectangle(Vector2 axis, Polygon body, ref float min, ref float max)
 {
     // Project a point on an axis using the dot product.
     float dotProduct = axis.X * body.Points[0].X + axis.Y * body.Points[0].Y;
     min = dotProduct;
     max = dotProduct;
     for (int i = 0; i < body.Points.Length; i++)
     {
         dotProduct = axis.X * body.Points[i].X + axis.Y * body.Points[i].Y;
         if (dotProduct < min)
         {
             min = dotProduct;
         }
         else
         {
             if (dotProduct > max)
             {
                 max = dotProduct;
             }
         }
     }
 }
Ejemplo n.º 4
0
 /// <summary>
 /// Intersection detection function
 /// Mostly derived from http://www.codeproject.com/Articles/15573/2D-Polygon-Collision-Detection
 /// </summary>
 /// <param name="other">The other Body to check intersection with</param>
 /// <returns>Vector2.Zero for no intersection, and minimum translation vector if there is an intersection</returns>
 public abstract Vector2 Intersects(Polygon other);