public static Collision2? FindCollision(Rectangle2 rectangle, Vector2 movement, Line2 line) { if (Vector2.Dot(movement, line.Normal()) >= 0) return null; var h = InFrontOf(rectangle.Center, line); var j = InFrontOf(rectangle.Center + movement, line); if (!h && !j) return null; var f1 = LineSegmentIntersection(line.Start, line.End, rectangle.TopLeft, rectangle.TopLeft + movement); var f2 = LineSegmentIntersection(line.Start, line.End, rectangle.TopRight, rectangle.TopRight + movement); var f3 = LineSegmentIntersection(line.Start, line.End, rectangle.BottomLeft, rectangle.BottomLeft + movement); var f4 = LineSegmentIntersection(line.Start, line.End, rectangle.BottomRight, rectangle.BottomRight + movement); if (!f1.HasValue && !f2.HasValue && !f3.HasValue && !f4.HasValue) return null; f1 = LinesIntersection(line.Start, line.End, rectangle.TopLeft, rectangle.TopLeft + movement); f2 = LinesIntersection(line.Start, line.End, rectangle.TopRight, rectangle.TopRight + movement); f3 = LinesIntersection(line.Start, line.End, rectangle.BottomLeft, rectangle.BottomLeft + movement); f4 = LinesIntersection(line.Start, line.End, rectangle.BottomRight, rectangle.BottomRight + movement); List<float> fs = new List<float>(); if ((Vector2.Dot(rectangle.Top.Normal(), line.Normal()) <= 0) && (Vector2.Dot(rectangle.Left.Normal(), line.Normal()) <= 0)) fs.Add(f1.Value); if ((Vector2.Dot(rectangle.Top.Normal(), line.Normal()) <= 0) && (Vector2.Dot(rectangle.Right.Normal(), line.Normal()) <= 0)) fs.Add(f2.Value); if ((Vector2.Dot(rectangle.Bottom.Normal(), line.Normal()) <= 0) && (Vector2.Dot(rectangle.Left.Normal(), line.Normal()) <= 0)) fs.Add(f3.Value); if ((Vector2.Dot(rectangle.Bottom.Normal(), line.Normal()) <= 0) && (Vector2.Dot(rectangle.Right.Normal(), line.Normal()) <= 0)) fs.Add(f4.Value); var array = fs.OrderBy(x => x); if (!array.Any()) return null; if (array.Last() < 0) return null; if (array.First() > 1) return null; Collision2 collision = new Collision2(); collision.Value = MinLinesIntersection(rectangle, movement, line); collision.Line = line; return collision; }
public static Vector2? FindCollision(Rectangle2 rectangle, Line2 line) { var f1 = SegmentsIntersection(rectangle.Top, line); var f2 = SegmentsIntersection(rectangle.Left, line); var f3 = SegmentsIntersection(rectangle.Right, line); var f4 = SegmentsIntersection(rectangle.Bottom, line); if (!f1.HasValue && !f2.HasValue && !f3.HasValue && !f4.HasValue) return null; var d = Math.Min(Math.Min(Distance(rectangle.TopLeft, line), Distance(rectangle.TopRight, line)), Math.Min(Distance(rectangle.BottomLeft, line), Distance(rectangle.BottomRight, line))); return -line.Normal() * d * 1.01f; }
public bool IsGrounded(Rectangle2 rectangle) { var groundGeometry = GetCollisionGeometry().Where(x => x.Normal().Y > 0.5f); return CollisionDetector.FindCollision(rectangle + CollisionDetector.GetStaticCollisionResolvingVector(rectangle, groundGeometry), new Vector2(0, -0.1f), groundGeometry).HasValue; }
public Vector2 GetFinalVelocity(Rectangle2 rectangle, Vector2 velocity) { return CollisionDetector.GetFinalMovement(rectangle, velocity, GetCollisionGeometry()); }
public Vector2 GetCollisionResolvingVector(Rectangle2 rectangle) { return CollisionDetector.GetStaticCollisionResolvingVector(rectangle, GetCollisionGeometry()); }
private static float MinLinesIntersection(Rectangle2 rectangle, Vector2 movement, Line2 line) { return Math.Min( Math.Min( LinesIntersection(rectangle.TopLeft, rectangle.TopLeft + movement, line.Start, line.End) ?? 1f, LinesIntersection(rectangle.TopRight, rectangle.TopRight + movement, line.Start, line.End) ?? 1f), Math.Min( LinesIntersection(rectangle.BottomLeft, rectangle.BottomLeft + movement, line.Start, line.End) ?? 1f, LinesIntersection(rectangle.BottomRight, rectangle.BottomRight + movement, line.Start, line.End) ?? 1f)); }
public static bool Collides(Rectangle2 rectangle, Vector2 movement, Line2 line) { return FindCollision(rectangle, movement, line).HasValue; }
public static Vector2 GetStaticCollisionResolvingVector(Rectangle2 rectangle, IEnumerable<Line2> lines) { var staticCollisionResolvingVector = Vector2.Zero; foreach (var line in lines) { var partial = CollisionDetector.FindCollision(rectangle, line); if (partial.HasValue) staticCollisionResolvingVector = staticCollisionResolvingVector + partial.Value; } return staticCollisionResolvingVector; }
public static Vector2 GetFinalMovement(Rectangle2 rectangle, Vector2 movement, IEnumerable<Line2> lines) { float damp = 0.99f; var v = movement; var v2 = Vector2.Zero; var step = rectangle; var collision = CollisionDetector.FindCollision(step, v, lines); while (collision.HasValue) { if (collision.Value.Value < 0) break; v2 += v * collision.Value.Value * damp; step = step + v * collision.Value.Value * damp; //step = step + CollisionDetector.GetStaticCollisionResolvingVector(step, lines); v = GetSlidingVector(v, collision.Value.Line.Direction(), collision.Value.Value) * damp; collision = CollisionDetector.FindCollision(step, v, lines); } return v2 + v; }
public static Vector2 FindMaxMovement(Rectangle2 rectangle, Vector2 movement, IEnumerable<Line2> lines) { var collision = FindCollision(rectangle, movement, lines); if (collision.HasValue) return movement * collision.Value.Value; else return movement; }
public static Collision2? FindCollision(Rectangle2 rectangle, Vector2 movement, IEnumerable<Line2> lines) { var collisions = lines.Select(x => FindCollision(rectangle, movement, x)).Where(x => x.HasValue); if (collisions.Any()) return collisions.OrderBy(x => x.Value.Value).First(); else return null; }