1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
public struct Line { public Vector2 a; public Vector2 b; public Line(float x1, float y1, float x2, float y2) { a = new Vector2(x1, y1); b = new Vector2(x2, y2); } public void Rotate(float rad, Vector2 center) { Rotate(rad, ref a, center); Rotate(rad, ref b, center); } private void Rotate(float rad, ref Vector2 point, Vector2 center) { point = Vector2.Transform(point - center, Matrix.CreateRotationZ(rad)) + center; } public bool Intersect(Line line, out Vector2? intersectionPoint) { intersectionPoint = null; float a1 = b.Y - a.Y; float b1 = a.X - b.X; float c1 = a1 * a.X + b1 * a.Y; float a2 = line.b.Y - line.a.Y; float b2 = line.a.X - line.b.X; float c2 = a2 * line.a.X + b2 * line.a.Y; //If the lines are parallel, no collision possible. float det = a1 * b2 - a2 * b1; if (det == 0) return false; float x = (b2 * c1 - b1 * c2) / det; float y = (a1 * c2 - a2 * c1) / det; if (OnLine(this, x, y) && OnLine(line, x, y)) { intersectionPoint = new Vector2(x, y); return true; } return false; } public static bool OnLine(Line line, float x, float y) { return Math.Min(line.a.X, line.b.X) <= x && x <= Math.Max(line.a.X, line.b.X) && Math.Min(line.a.Y, line.b.Y) <= y && y <= Math.Max(line.a.Y, line.b.Y); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
public struct SRectangle { public Line left; public Line top; public Line right; public Line bottom; public void Rotate(float rad, Vector2 center) { left.Rotate(rad, center); top.Rotate(rad, center); right.Rotate(rad, center); bottom.Rotate(rad, center); } public static SRectangle FromRectangle(Rectangle rectangle, Vector2 origin, float rotation) { Line left = new Line(rectangle.X, rectangle.Y, rectangle.X, rectangle.Y + rectangle.Height); Line top = new Line(rectangle.X, rectangle.Y, rectangle.X + rectangle.Width, rectangle.Y); Line right = new Line(rectangle.X + rectangle.Width, rectangle.Y, rectangle.X + rectangle.Width, rectangle.Y + rectangle.Height); Line bottom = new Line(rectangle.X, rectangle.Y + rectangle.Height, rectangle.X + rectangle.Width, rectangle.Y + rectangle.Height); left.a.X -= origin.X; left.a.Y -= origin.Y; left.b.X -= origin.X; left.b.Y -= origin.Y; top.a.X -= origin.X; top.a.Y -= origin.Y; top.b.X -= origin.X; top.b.Y -= origin.Y; right.a.X -= origin.X; right.a.Y -= origin.Y; right.b.X -= origin.X; right.b.Y -= origin.Y; bottom.a.X -= origin.X; bottom.a.Y -= origin.Y; bottom.b.X -= origin.X; bottom.b.Y -= origin.Y; origin.X += rectangle.X - rectangle.Width / 2; origin.Y += rectangle.Y - rectangle.Height / 2; left.Rotate(rotation, origin); right.Rotate(rotation, origin); top.Rotate(rotation, origin); bottom.Rotate(rotation, origin); return new SRectangle() { left = left, right = right, top = top, bottom = bottom }; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
public static bool AABB_AABB(SmartRectangle x, SmartRectangle y, out Vector2[] collisionPoints) { List<Vector2> cp = new List<Vector2>(); /* Left against y */ if (x.left.Intersect(y.left, out Vector2? llcp)) cp.Add(llcp.Value); if (x.left.Intersect(y.top, out Vector2? ltcp)) cp.Add(ltcp.Value); if (x.left.Intersect(y.right, out Vector2? lrcp)) cp.Add(lrcp.Value); if (x.left.Intersect(y.bottom, out Vector2? lbcp)) cp.Add(lbcp.Value); /* Top against y */ if (x.top.Intersect(y.left, out Vector2? tlcp)) cp.Add(tlcp.Value); if (x.top.Intersect(y.top, out Vector2? ttcp)) cp.Add(ttcp.Value); if (x.top.Intersect(y.right, out Vector2? trcp)) cp.Add(trcp.Value); if (x.top.Intersect(y.bottom, out Vector2? tbcp)) cp.Add(tbcp.Value); /* Right against y */ if (x.right.Intersect(y.left, out Vector2? rlcp)) cp.Add(rlcp.Value); if (x.right.Intersect(y.top, out Vector2? rtcp)) cp.Add(rtcp.Value); if (x.right.Intersect(y.right, out Vector2? rrcp)) cp.Add(rrcp.Value); if (x.right.Intersect(y.bottom, out Vector2? rbcp)) cp.Add(rbcp.Value); /* Bottom against y */ if (x.bottom.Intersect(y.left, out Vector2? blcp)) cp.Add(blcp.Value); if (x.bottom.Intersect(y.top, out Vector2? btcp)) cp.Add(btcp.Value); if (x.bottom.Intersect(y.right, out Vector2? brcp)) cp.Add(brcp.Value); if (x.bottom.Intersect(y.bottom, out Vector2? bbcp)) cp.Add(bbcp.Value); collisionPoints = cp.ToArray(); return cp.Count > 0; } |