/// <summary> /// Gets a point at which two polygons are coliding, or null otherwise /// </summary> /// <param name="p"></param> /// <returns></returns> public Vector2? CheckColisions_Accurate_GetPoint(Polygon p) { Vector2[] myCorners = GetCorners(); Vector2[] otherCorners = p.GetCorners(); for (int i = 0; i < myCorners.Length; i++) { for (int i2 = 0; i2 < otherCorners.Length; i2++) { if (LocationManager.linesIntersect(myCorners[i], myCorners[(i + 1) % myCorners.Length], otherCorners[i2], otherCorners[(i2 + 1) % otherCorners.Length])) return LocationManager.getIntersectionPoint(myCorners[i], myCorners[(i + 1) % myCorners.Length], otherCorners[i2], otherCorners[(i2 + 1) % otherCorners.Length]); } } return null; }
public bool VelocityColision(Polygon moving, Polygon stationary, Vector2 velocity) { Rectangle roughBounds = moving.Bounds; roughBounds.Width += (int)Math.Ceiling(Math.Abs(velocity.X)); roughBounds.Height += (int)Math.Ceiling(Math.Abs(velocity.Y)); if (velocity.X < 0) { roughBounds.X += (int)Math.Ceiling(velocity.X); } if (velocity.Y < 0) { roughBounds.Y += (int)Math.Ceiling(velocity.Y); } debug_bounds = roughBounds; if (!roughBounds.Intersects(stationary.Bounds)) { return(false); } float MV = Physics.ConvertToMA(velocity).X; float MV2 = MV * MV; List <Vector2[]> movingLines = new List <Vector2[]>(); List <Vector2[]> stationaryLines = new List <Vector2[]>(); for (int i = 0; i < moving.NumberOfSides(); i++) { movingLines.Add(new Vector2[] { moving.GetCorner(i), Vector2.Add(moving.GetCorner(i), velocity) }); } for (int i = 0; i < stationary.NumberOfSides(); i++) { stationaryLines.Add(new Vector2[] { Vector2.Subtract(stationary.GetCorner(i), velocity), stationary.GetCorner(i) }); } float maxMove = (velocity.X * velocity.X) + (velocity.Y * velocity.Y); bool colid = false; for (int i = 0; i < movingLines.Count; i++) { foreach (Vector2 [] edge in stationary.GetEdges()) { Vector2?Colision = LocationManager.getIntersectionPoint(movingLines[i], edge); switch (LocationManager.LinesIntersect_Precise(movingLines[i], edge)) { case 1: if (Colision.HasValue) { float newdist = LocationManager.getDistanceSquared(movingLines[i][0], Colision.Value); if (newdist < maxMove) { maxMove = newdist; } colid = true; HITEDGE = edge; } else { Console.Out.WriteLine("? ? ? ?"); } break; case 2: Cot = new Vector2[2][] { movingLines[i], edge }; Vector2[] edgecheck = new Vector2[] { movingLines[i][0], Vector2.Add(movingLines[i][0], Vector2.Multiply(velocity, 100000)) }; int hitcount = 0; foreach (Vector2[] ec2 in stationary.GetEdges()) { if (LocationManager.LinesIntersect_Precise(ec2, edgecheck) == 1) { hitcount++; } } if (hitcount % 2 == 0) { } else { if (Colision.HasValue) { float newdist = LocationManager.getDistanceSquared(movingLines[i][0], Colision.Value); if (newdist < maxMove) { maxMove = newdist; } colid = true; HITEDGE = edge; } else { Console.Out.WriteLine("? ? ? ?"); } } break; default: case 0: break; } } } for (int i = 0; i < stationaryLines.Count; i++) { foreach (Vector2[] edge in moving.GetEdges()) { Vector2?Colision = LocationManager.getIntersectionPoint(stationaryLines[i], edge); switch (LocationManager.LinesIntersect_Precise(stationaryLines[i], edge)) { case 1: if (Colision.HasValue) { float newdist = MV2 - LocationManager.getDistanceSquared(stationaryLines[i][0], Colision.Value); if (newdist < maxMove) { maxMove = newdist; } colid = true; HITEDGE = edge; } else { Console.Out.WriteLine("? ? ? ?"); } break; case 2: Cot = new Vector2[2][] { stationaryLines[i], edge }; Vector2[] edgecheck = new Vector2[] { stationaryLines[i][0], Vector2.Add(stationaryLines[i][0], Vector2.Multiply(velocity, 100000)) }; int hitcount = 0; foreach (Vector2[] ec2 in moving.GetEdges()) { if (LocationManager.LinesIntersect_Precise(ec2, edgecheck) == 1) { hitcount++; } } if (hitcount % 2 == 0) { } else { if (Colision.HasValue) { float newdist = MV2 - LocationManager.getDistanceSquared(stationaryLines[i][0], Colision.Value); if (newdist < maxMove) { maxMove = newdist; } colid = true; HITEDGE = edge; } else { Console.Out.WriteLine("? ? ? ?"); } } break; default: case 0: break; } } } if (colid) { maxV = (float)Math.Sqrt(maxMove) / MV; return(true); } debug_AllLines = new List <Vector2[]>(); debug_AllLines.AddRange(movingLines); debug_AllLines.AddRange(stationaryLines); return(false); }
public static bool DoSingleColision_Debug(Polygon MovingPoly, Polygon StationaryPoly, Velocity velocity, List <Vector2[]> lines, List <Color> linecolors) { Vector2[][] MovingLines = new Vector2[MovingPoly.NumberOfSides()][]; Vector2[][] StationaryLines = new Vector2[StationaryPoly.NumberOfSides()][]; bool doWork = false; for (int i = 0; i < MovingLines.Length; i++) { MovingLines[i] = new Vector2[] { velocity.Move(MovingPoly.GetCorner(i), -1f), velocity.Move(MovingPoly.GetCorner(i), 1f) }; lines.Add(MovingLines[i]); linecolors.Add(Color.Blue); if (!doWork && LocationManager.getBounds(MovingLines[i]).Intersects(StationaryPoly.Bounds)) { doWork = true; } } for (int i = 0; i < StationaryLines.Length; i++) { StationaryLines[i] = new Vector2[] { velocity.Move(StationaryPoly.GetCorner(i), -1f), velocity.Move(StationaryPoly.GetCorner(i), 1f) }; lines.Add(StationaryLines[i]); linecolors.Add(Color.Green); if (!doWork && LocationManager.getBounds(StationaryLines[i]).Intersects(MovingPoly.Bounds)) { doWork = true; } } if (!doWork) { foreach (Vector2[] v in LocationManager.RectangleEdges(MovingPoly.Bounds)) { lines.Add(v); linecolors.Add(Color.Yellow); } foreach (Vector2[] v in LocationManager.RectangleEdges(StationaryPoly.Bounds)) { lines.Add(v); linecolors.Add(Color.Yellow); } return(false); } int lowindex = -1; int otherindex = -1; float lowdistance = 0; bool movingcloser = false; Vector2 intersect = new Vector2(); for (int i = 0; i < MovingLines.Length; i++) { for (int i2 = 0; i2 < StationaryLines.Length; i2++) { Vector2?V2 = LocationManager.getIntersectionPoint(StationaryPoly.GetEdge(i2), MovingLines[i]); if (V2.HasValue) { if (lowindex == -1 || LocationManager.distanceCheck(V2.Value, MovingLines[i][0], lowdistance)) { lowdistance = LocationManager.getDistance(V2.Value, MovingLines[i][0]); lowindex = i; otherindex = i2; movingcloser = true; intersect = V2.Value; } } } } for (int i = 0; i < StationaryLines.Length; i++) { for (int i2 = 0; i2 < MovingLines.Length; i2++) { Vector2?V2 = LocationManager.getIntersectionPoint(MovingPoly.GetEdge(i2), StationaryLines[i]); if (V2.HasValue) { //Console.Out.WriteLine("Intersection at {0}::{1} => Point at {2}", MovingPoly.GetEdge(i2)[0] + "," + MovingPoly.GetEdge(i2)[1], StationaryLines[i][0] + "," + StationaryLines[i][1], V2.Value); if (lowindex == -1 || LocationManager.distanceCheck(V2.Value, StationaryLines[i][1], lowdistance)) { lowdistance = velocity.M - LocationManager.getDistance(V2.Value, StationaryLines[i][0]); lowindex = i; otherindex = i2; movingcloser = false; intersect = V2.Value; } } } } if (lowindex != -1) { Velocity AddToVelocity = new Velocity(); if (movingcloser) { float angle = LocationManager.getRotation(intersect, LocationManager.getReflectionLine(MovingLines[lowindex], StationaryPoly.GetEdge(otherindex))[1]); AddToVelocity.A = angle; AddToVelocity.M = velocity.M; lines.Add(new Vector2[] { MovingLines[lowindex][0], MovingLines[lowindex][1] }); linecolors.Add(Color.Red); } else { float angle = LocationManager.getRotation(intersect, LocationManager.getReflectionLine(StationaryLines[lowindex], MovingPoly.GetEdge(otherindex))[1]); AddToVelocity.A = angle; AddToVelocity.M = velocity.M; lines.Add(new Vector2[] { StationaryLines[lowindex][0], StationaryLines[lowindex][1] }); linecolors.Add(Color.Red); } velocity.X = AddToVelocity.X; velocity.Y = AddToVelocity.Y; MovingPoly.Position = LocationManager.moveByRotation(MovingPoly.Position, lowdistance, velocity.A); return(true); } return(false); }
public static bool DoSingleColision(Polygon MovingPoly, Polygon StationaryPoly, ref Vector2 velocity, bool isMA) { if (!isMA) { velocity = Physics.ConvertToMA(velocity); } Vector2[][] MovingLines = new Vector2[MovingPoly.NumberOfSides()][]; Vector2[][] StationaryLines = new Vector2[StationaryPoly.NumberOfSides()][]; for (int i = 0; i < MovingLines.Length; i++) { MovingLines[i] = new Vector2[] { LocationManager.moveByRotation(MovingPoly.GetCorner(i), -velocity.X, velocity.Y), LocationManager.moveByRotation(MovingPoly.GetCorner(i), velocity.X, velocity.Y) }; } for (int i = 0; i < StationaryLines.Length; i++) { StationaryLines[i] = new Vector2[] { /*StationaryPoly.GetCorner(i)*/ LocationManager.moveByRotation(StationaryPoly.GetCorner(i), velocity.X, velocity.Y), LocationManager.moveByRotation(StationaryPoly.GetCorner(i), -velocity.X, velocity.Y) }; } int lowindex = -1; int otherindex = -1; float lowdistance = 0; bool movingcloser = false; Vector2 intersect = new Vector2(); for (int i = 0; i < MovingLines.Length; i++) { for (int i2 = 0; i2 < StationaryLines.Length; i2++) { Vector2?V2 = LocationManager.getIntersectionPoint(StationaryPoly.GetEdge(i2), MovingLines[i]); if (V2.HasValue) { if (lowindex == -1 || LocationManager.distanceCheck(V2.Value, MovingLines[i][0], lowdistance)) { lowdistance = LocationManager.getDistance(V2.Value, MovingLines[i][0]); lowindex = i; otherindex = i2; movingcloser = true; intersect = V2.Value; } } } } for (int i = 0; i < StationaryLines.Length; i++) { for (int i2 = 0; i2 < MovingLines.Length; i2++) { Vector2?V2 = LocationManager.getIntersectionPoint(MovingPoly.GetEdge(i2), StationaryLines[i]); if (V2.HasValue) { //Console.Out.WriteLine("Intersection at {0}::{1} => Point at {2}", MovingPoly.GetEdge(i2)[0] + "," + MovingPoly.GetEdge(i2)[1], StationaryLines[i][0] + "," + StationaryLines[i][1], V2.Value); if (lowindex == -1 || LocationManager.distanceCheck(V2.Value, StationaryLines[i][1], lowdistance)) { lowdistance = velocity.X - LocationManager.getDistance(V2.Value, StationaryLines[i][0]); lowindex = i; otherindex = i2; movingcloser = false; intersect = V2.Value; } } } } if (lowindex != -1) { //Console.Out.WriteLine("Colis=> Lowindex: {0}, distance: {1}, whose:{2}", lowindex, lowdistance, movingcloser); Vector2 AddToVelocity = new Vector2(); if (movingcloser) { float angle = LocationManager.getRotation(intersect, LocationManager.getReflectionLine(MovingLines[lowindex], StationaryPoly.GetEdge(otherindex))[1]); AddToVelocity.Y = angle; AddToVelocity.X = velocity.X; } else { float angle = LocationManager.getRotation(intersect, LocationManager.getReflectionLine(StationaryLines[lowindex], MovingPoly.GetEdge(otherindex))[1]); AddToVelocity.Y = angle; AddToVelocity.X = -velocity.X; } velocity = AddToVelocity; MovingPoly.Position = LocationManager.moveByRotation(MovingPoly.Position, lowdistance - .4f, velocity.Y); if (!isMA) { velocity = Physics.ConvertToXY(velocity); } return(true); } if (!isMA) { velocity = Physics.ConvertToXY(velocity); } return(false); }