public static float? FindCollision(Vector2 position, Vector2 movement, Line2 line) { if (Vector2.Dot(movement, line.Normal()) >= 0) return null; return SegmentsIntersection(position, position + movement, line.Start, line.End); }
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 Rectangle2(float x1, float y1, float x2, float y2) { TopLeft = new Vector2(x1, y1); TopRight = new Vector2(x2, y1); BottomLeft = new Vector2(x1, y2); BottomRight = new Vector2(x2, y2); Top = new Line2(TopLeft, TopRight); Left = new Line2(BottomLeft, TopLeft); Right = new Line2(TopRight, BottomRight); Bottom = new Line2(BottomRight, BottomLeft); Center = new Vector2((x1 + x2) / 2, (y1 + y2) / 2); }
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 static float Distance(Vector2 point, Line2 line) { var p2 = line.Start + line.Direction(); return ((line.Start.X - point.X) * (p2.Y - point.Y) - (line.Start.Y - point.Y) * (p2.X - point.X)); }
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)); }
private static float? SegmentsIntersection(Line2 l1, Line2 l2) { return SegmentsIntersection(l1.Start, l1.End, l2.Start, l2.End); }
public static bool Collides(Rectangle2 rectangle, Vector2 movement, Line2 line) { return FindCollision(rectangle, movement, line).HasValue; }
public static bool InFrontOf(Vector2 point, Line2 line) { return (line.Start.X - point.X) * (line.End.Y - point.Y) - (line.Start.Y - point.Y) * (line.End.X - point.X) >= 0; }
public static Vector2 FindMaxMovement(Rectangle2 rectangle, Vector2 movement, Line2 line) { var collision = FindCollision(rectangle, movement, line); if (collision.HasValue) return movement * collision.Value.Value; else return movement; }
public static Vector2 FindMaxMovement(Vector2 position, Vector2 movement, Line2 line) { float? collision = FindCollision(position, movement, line); if (collision.HasValue) return movement * collision.Value; else return movement; }
public static bool Collides(Vector2 position, Vector2 movement, Line2 line) { return FindCollision(position, movement, line).HasValue; }