/// <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; }
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); } } } }
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; } } } }
/// <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);