/// <summary> /// Gets an array of colision data including both polygon lines and the actual intersect point /// </summary> /// <param name="p"></param> /// <returns>[TgtLineStart, TgtLineEnd, MyLineStart, MyLineEnd, IntersectionPoint]</returns> public Vector2[] CheckColisions_Accurate_GetLine(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 new Vector2[] { otherCorners[i2], otherCorners[(i2 + 1) % otherCorners.Length], myCorners[i], myCorners[(i + 1) % myCorners.Length], LocationManager.getIntersectionPoint(myCorners[i], myCorners[(i + 1) % myCorners.Length], otherCorners[i2], otherCorners[(i2 + 1) % otherCorners.Length]).Value } } ; } } return(null); }
/// <summary> /// Draws an image stretched along it's X axis to form a line between two points /// </summary> /// <param name="sb">Spritebatch to use</param> /// <param name="i">The image to use</param> /// <param name="p1">Start point</param> /// <param name="p2">End point</param> /// <param name="forcedWidth">Width of the line</param> /// <param name="c">Tint color</param> public static void drawAsLine(SpriteBatch sb, Image i, Vector2 p1, Vector2 p2, int forcedWidth, Color c) { float distance = LocationManager.getDistance(p1, p2); float rotation = LocationManager.getRotation(p1, p2); Vector2 placementPoint = LocationManager.moveByRotation(p1, distance / 2, rotation); Rectangle colisCheck = new Rectangle((int)Math.Ceiling(Math.Min(p1.X, p2.X)), (int)Math.Ceiling(Math.Min(p1.Y, p2.Y)), (int)Math.Ceiling(Math.Abs(p1.X - p2.X)), (int)Math.Ceiling(Math.Abs(p1.Y - p2.Y))); Rectangle drawLocation = new Rectangle((int)placementPoint.X, (int)placementPoint.Y, (int)Math.Ceiling(distance), forcedWidth); drawLocation = new Rectangle( (int)((Math.Round((drawLocation.X - cameraLocation.X) * zoom)) + Camera.origin.X), (int)((Math.Round((drawLocation.Y - cameraLocation.Y) * zoom)) + Camera.origin.Y), (int)Math.Round(drawLocation.Width * zoom), (int)Math.Round(drawLocation.Height * zoom)); if (colisCheck.Intersects(getFullScreen())) { sb.Draw(i.getTexture(), drawLocation, null, c, rotation, new Vector2(((float)i.getTexture().Width) / 2f, ((float)i.getTexture().Height) / 2f), SpriteEffects.None, 0); } }
public static Vector2[] getReflectionLine(Vector2[] src, Vector2[] tgt) { if (LinesIntersect_Precise(src, tgt) == 0) { return(null); } Vector2 si1 = convertLineToSI(src); Vector2 si2 = convertLineToSI(tgt); Vector2 pointOfIntersection = new Vector2(); if (!float.IsInfinity(si1.X) && !float.IsInfinity(si2.X)) { pointOfIntersection.X = (si2.Y - si1.Y) / (si1.X - si2.X); pointOfIntersection.Y = (si1.X * pointOfIntersection.X) + si1.Y; } else if (!float.IsInfinity(si2.X)) { pointOfIntersection.X = src[0].X; pointOfIntersection.Y = (si2.X * pointOfIntersection.X) + si2.Y; } else if (!float.IsInfinity(si1.X)) { pointOfIntersection.X = tgt[0].X; pointOfIntersection.Y = (si1.X * pointOfIntersection.X) + si1.Y; } float Angle1 = (float)Math.Atan2(src[1].Y - src[0].Y, src[1].X - src[0].X); float Angle2 = (float)Math.Atan2(tgt[1].Y - tgt[0].Y, tgt[1].X - tgt[0].X); float newAngle = Angle2 + (Angle2 - Angle1); float distanceRemaining = LocationManager.getDistance(src[0], src[1]) - LocationManager.getDistance(src[0], pointOfIntersection); Vector2[] returnLine = new Vector2[] { pointOfIntersection, moveByRotation(pointOfIntersection, distanceRemaining, newAngle) }; return(returnLine); }
/// <summary> /// Checks if a line intersects a circle and returns all intersection positions /// </summary> /// <param name="line">The line to check</param> /// <param name="CirclePosition">The position of the circle</param> /// <param name="CircleRadius">The radius of the circle</param> /// <returns>A list of intersection points</returns> public static List <Vector2> CircleIntersects_V(Vector2[] line, Vector2 CirclePosition, float CircleRadius) { List <Vector2> outp = new List <Vector2>(); Vector2 d = Vector2.Subtract(line[1], line[0]); Vector2 f = Vector2.Subtract(line[0], CirclePosition); float a = Vector2.Dot(d, d); float b = 2 * Vector2.Dot(f, d); float c = Vector2.Dot(f, f) - CircleRadius * CircleRadius; float discriminant = b * b - 4 * a * c; if (discriminant < 0) { } else { discriminant = (float)Math.Sqrt(discriminant); float t1 = (-b - discriminant) / (2 * a); float t2 = (-b + discriminant) / (2 * a); if (t1 >= 0 && t1 <= 1) { outp.Add(LocationManager.moveByRotation(line[0], t1 * LocationManager.getDistance(line[0], line[1]), LocationManager.getRotation(line[0], line[1]))); if (t2 >= 0 && t2 <= 1) { outp.Add(LocationManager.moveByRotation(line[0], t2 * LocationManager.getDistance(line[0], line[1]), LocationManager.getRotation(line[0], line[1]))); } } if (t2 >= 0 && t2 <= 1) { outp.Add(LocationManager.moveByRotation(line[0], t2 * LocationManager.getDistance(line[0], line[1]), LocationManager.getRotation(line[0], line[1]))); } } return(outp); }
public static List <float> CircleIntersects_A(Vector2[] line, Vector2 CirclePosition, float CircleRadius) { List <float> outp = new List <float>(); Vector2 d = Vector2.Subtract(line[1], line[0]); Vector2 f = Vector2.Subtract(line[0], CirclePosition); float a = Vector2.Dot(d, d); float b = 2 * Vector2.Dot(f, d); float c = Vector2.Dot(f, f) - CircleRadius * CircleRadius; float discriminant = b * b - 4 * a * c; if (discriminant < 0) { // no intersection } else { // ray didn't totally miss sphere, // so there is a solution to // the equation. discriminant = (float)Math.Sqrt(discriminant); // either solution may be on or off the ray so need to test both // t1 is always the smaller value, because BOTH discriminant and // a are nonnegative. float t1 = (-b - discriminant) / (2 * a); float t2 = (-b + discriminant) / (2 * a); // 3x HIT cases: // -o-> --|--> | | --|-> // Impale(t1 hit,t2 hit), Poke(t1 hit,t2>1), ExitWound(t1<0, t2 hit), // 3x MISS cases: // -> o o -> | -> | // FallShort (t1>1,t2>1), Past (t1<0,t2<0), CompletelyInside(t1<0, t2>1) if (t1 >= 0 && t1 <= 1) { // t1 is the intersection, and it's closer than t2 // (since t1 uses -b - discriminant) // Impale, Poke outp.Add(getRotation(CirclePosition, LocationManager.moveByRotation(line[0], t1 * LocationManager.getDistance(line[0], line[1]), LocationManager.getRotation(line[0], line[1])))); if (t2 >= 0 && t2 <= 1) { outp.Add(getRotation(CirclePosition, LocationManager.moveByRotation(line[0], t2 * LocationManager.getDistance(line[0], line[1]), LocationManager.getRotation(line[0], line[1])))); } //return true; } // here t1 didn't intersect so we are either started // inside the sphere or completely past it if (t2 >= 0 && t2 <= 1) { outp.Add(getRotation(CirclePosition, LocationManager.moveByRotation(line[0], t2 * LocationManager.getDistance(line[0], line[1]), LocationManager.getRotation(line[0], line[1])))); } // no intn: FallShort, Past, CompletelyInside } return(outp); }
public Vector2[] RelativeLine(Vector2[] GlobalLine, Vector2 Position, float CurrentRotation) { return(new Vector2[] { LocationManager.TransformAround(Position, GlobalLine[0], CurrentRotation) - Position, LocationManager.TransformAround(Position, GlobalLine[1], CurrentRotation) - Position }); }
public static Vector2 ConvertToMA(Vector2 v) { return(new Vector2(LocationManager.getDistance(Vector2.Zero, v), (float)Math.Atan2(v.Y, v.X))); }
/// <summary> /// Draws a generic texture (solid color) line between two points /// </summary> /// <param name="v1">Start point of the line</param> /// <param name="v2">End point of the line</param> /// <param name="sb">SpriteBatch to use</param> /// <param name="c">Color of the line</param> public static void drawLineGeneric(Vector2 v1, Vector2 v2, SpriteBatch sb, Color c) { float betweenAngle = LocationManager.getRotation(v1, v2); float distance = LocationManager.getDistance(v1, v2); drawGenericNoCheck(sb, new Rectangle((int)Math.Round(LocationManager.moveByRotation(v1, distance / 2f, betweenAngle).X), (int)Math.Round(LocationManager.moveByRotation(v1, distance / 2f, betweenAngle).Y), (int)Math.Round(distance), 1), c, null, betweenAngle, new Vector2(0.5f, 0.5f), SpriteEffects.None, 0); }
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); }
/// <summary> /// Centers the camera on a given vector /// </summary> /// <param name="p"></param> public void Center(Vector2 p) { Center(LocationManager.getPointFromVector(p)); }
private void CalculateArea() { AreaGood = true; area = 0; for (int i = 0; i < corners.Length; i++) { Vector2 corner1 = corners[i]; Vector2 corner2 = corners[(i + 1) % corners.Length]; Vector2 center = Vector2.Zero; area += (1 / 2f) * LocationManager.getDistance(center, corner1) * LocationManager.getDistance(center, corner2) * (float)Math.Sin(LocationManager.NormalRelitiveAngle_NormalInput(LocationManager.getRotation(center, corner1), LocationManager.getRotation(center, corner2))); } }
protected static bool[,] ScanOctant(Point Source, bool[,] World, bool[,] Ret, int pDepth, int pOctant, double pStartSlope, double pEndSlope, int range) { int visrange2 = range * range; int x = 0; int y = 0; switch (pOctant) { case 1: //nnw // 0, -1 // -1, 0 y = Source.Y - pDepth; if (y < 0) { return(Ret); } x = Source.X - Convert.ToInt32((pStartSlope * Convert.ToDouble(pDepth))); if (x < 0) { x = 0; } while (GetSlope(x, y, Source.X, Source.Y, false) >= pEndSlope) { if (LocationManager.distanceCheck(LocationManager.getVectorFromPoint(Source), new Vector2(x, y), range)) { Ret[x, y] = true; if (World[x, y]) //current cell blocked { if (x - 1 >= 0 && !World[x - 1, y]) //prior cell within range AND open... //...incremenet the depth, adjust the endslope and recurse { ScanOctant(Source, World, Ret, pDepth + 1, pOctant, pStartSlope, GetSlope(x - 0.5, y + 0.5, Source.X, Source.Y, false), range); } } else { if (x - 1 >= 0 && World[x - 1, y]) //prior cell within range AND open... //..adjust the startslope { pStartSlope = GetSlope(x - 0.5, y - 0.5, Source.X, Source.Y, false); } } } x++; } x--; break; case 2: //nne y = Source.Y - pDepth; if (y < 0) { return(Ret); } x = Source.X + Convert.ToInt32((pStartSlope * Convert.ToDouble(pDepth))); if (x >= World.GetLength(0)) { x = World.GetLength(0) - 1; } while (GetSlope(x, y, Source.X, Source.Y, false) <= pEndSlope) { if (GetVisDistance(x, y, Source.X, Source.Y) <= visrange2) { Ret[x, y] = true; if (World[x, y]) { if (x + 1 < World.GetLength(0) && !World[x + 1, y]) { ScanOctant(Source, World, Ret, pDepth + 1, pOctant, pStartSlope, GetSlope(x + 0.5, y + 0.5, Source.X, Source.Y, false), range); } } else { if (x + 1 < World.GetLength(0) && World[x + 1, y]) { pStartSlope = -GetSlope(x + 0.5, y - 0.5, Source.X, Source.Y, false); } } } x--; } x++; break; case 3: x = Source.X + pDepth; if (x >= World.GetLength(0)) { return(Ret); } y = Source.Y - Convert.ToInt32((pStartSlope * Convert.ToDouble(pDepth))); if (y < 0) { y = 0; } while (GetSlope(x, y, Source.X, Source.Y, true) <= pEndSlope) { if (GetVisDistance(x, y, Source.X, Source.Y) <= visrange2) { Ret[x, y] = true; if (World[x, y]) { if (y - 1 >= 0 && !World[x, y - 1]) { ScanOctant(Source, World, Ret, pDepth + 1, pOctant, pStartSlope, GetSlope(x - 0.5, y - 0.5, Source.X, Source.Y, true), range); } } else { if (y - 1 >= 0 && World[x, y - 1]) { pStartSlope = -GetSlope(x + 0.5, y - 0.5, Source.X, Source.Y, true); } } } y++; } y--; break; case 4: x = Source.X + pDepth; if (x >= World.GetLength(0)) { return(Ret); } y = Source.Y + Convert.ToInt32((pStartSlope * Convert.ToDouble(pDepth))); if (y >= World.GetLength(1)) { y = World.GetLength(1) - 1; } while (GetSlope(x, y, Source.X, Source.Y, true) >= pEndSlope) { if (GetVisDistance(x, y, Source.X, Source.Y) <= visrange2) { Ret[x, y] = true; if (World[x, y]) { if (y + 1 < World.GetLength(1) && !World[x, y + 1]) { ScanOctant(Source, World, Ret, pDepth + 1, pOctant, pStartSlope, GetSlope(x - 0.5, y + 0.5, Source.X, Source.Y, true), range); } } else { if (y + 1 < World.GetLength(1) && World[x, y + 1]) { pStartSlope = GetSlope(x + 0.5, y + 0.5, Source.X, Source.Y, true); } } } y--; } y++; break; case 5: y = Source.Y + pDepth; if (y >= World.GetLength(1)) { return(Ret); } x = Source.X + Convert.ToInt32((pStartSlope * Convert.ToDouble(pDepth))); if (x >= World.GetLength(0)) { x = World.GetLength(0) - 1; } while (GetSlope(x, y, Source.X, Source.Y, false) >= pEndSlope) { if (GetVisDistance(x, y, Source.X, Source.Y) <= visrange2) { Ret[x, y] = true; if (World[x, y]) { if (x + 1 < World.GetLength(1) && !World[x + 1, y]) { ScanOctant(Source, World, Ret, pDepth + 1, pOctant, pStartSlope, GetSlope(x + 0.5, y - 0.5, Source.X, Source.Y, false), range); } } else { if (x + 1 < World.GetLength(1) && World[x + 1, y]) { pStartSlope = GetSlope(x + 0.5, y + 0.5, Source.X, Source.Y, false); } } } x--; } x++; break; case 6: y = Source.Y + pDepth; if (y >= World.GetLength(1)) { return(Ret); } x = Source.X - Convert.ToInt32((pStartSlope * Convert.ToDouble(pDepth))); if (x < 0) { x = 0; } while (GetSlope(x, y, Source.X, Source.Y, false) <= pEndSlope) { if (GetVisDistance(x, y, Source.X, Source.Y) <= visrange2) { Ret[x, y] = true; if (World[x, y]) { if (x - 1 >= 0 && !World[x - 1, y]) { ScanOctant(Source, World, Ret, pDepth + 1, pOctant, pStartSlope, GetSlope(x - 0.5, y - 0.5, Source.X, Source.Y, false), range); } } else { if (x - 1 >= 0 && World[x - 1, y]) { pStartSlope = -GetSlope(x - 0.5, y + 0.5, Source.X, Source.Y, false); } } } x++; } x--; break; case 7: x = Source.X - pDepth; if (x < 0) { return(Ret); } y = Source.Y + Convert.ToInt32((pStartSlope * Convert.ToDouble(pDepth))); if (y >= World.GetLength(1)) { y = World.GetLength(1) - 1; } while (GetSlope(x, y, Source.X, Source.Y, true) <= pEndSlope) { if (GetVisDistance(x, y, Source.X, Source.Y) <= visrange2) { Ret[x, y] = true; if (World[x, y]) { if (y + 1 < World.GetLength(1) && !World[x, y + 1]) { ScanOctant(Source, World, Ret, pDepth + 1, pOctant, pStartSlope, GetSlope(x + 0.5, y + 0.5, Source.X, Source.Y, true), range); } } else { if (y + 1 < World.GetLength(1) && World[x, y + 1]) { pStartSlope = -GetSlope(x - 0.5, y + 0.5, Source.X, Source.Y, true); } } } y--; } y++; break; case 8: //wnw x = Source.X - pDepth; if (x < 0) { return(Ret); } y = Source.Y - Convert.ToInt32((pStartSlope * Convert.ToDouble(pDepth))); if (y < 0) { y = 0; } while (GetSlope(x, y, Source.X, Source.Y, true) >= pEndSlope) { if (GetVisDistance(x, y, Source.X, Source.Y) <= visrange2) { Ret[x, y] = true; if (World[x, y]) { if (y - 1 >= 0 && !World[x, y - 1]) { ScanOctant(Source, World, Ret, pDepth + 1, pOctant, pStartSlope, GetSlope(x + 0.5, y - 0.5, Source.X, Source.Y, true), range); } } else { if (y - 1 >= 0 && World[x, y - 1]) { pStartSlope = GetSlope(x - 0.5, y - 0.5, Source.X, Source.Y, true); } } } y++; } y--; break; } if (x < 0) { x = 0; } else if (x >= World.GetLength(0)) { x = World.GetLength(0) - 1; } if (y < 0) { y = 0; } else if (y >= World.GetLength(1)) { y = World.GetLength(1) - 1; } if (pDepth < range & !World[x, y]) { ScanOctant(Source, World, Ret, pDepth + 1, pOctant, pStartSlope, pEndSlope, range); } return(Ret); }
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 TryTurn_Debug(Polygon myPoly, Polygon StationaryPoly, ref float amt, List <Vector2[]> lines, List <Color> linecolors) { Vector2 CircleCenter = myPoly.Position; Pair <float, bool, float>[] distances; float greatestMine = 0; float lowestOther = -1; ArrayBuilder <Pair <float, bool, float> > build = new ArrayBuilder <Pair <float, bool, float> >(myPoly.NumberOfSides() + StationaryPoly.NumberOfSides()); for (int x = 0; x < myPoly.NumberOfSides(); x++) { float next = LocationManager.getDistance(CircleCenter, myPoly.GetCorner(x)); build.Add(new Pair <float, bool, float>(next, true, LocationManager.getRotation(CircleCenter, myPoly.GetCorner(x)))); if (next > greatestMine) { greatestMine = next; } } for (int x = 0; x < StationaryPoly.NumberOfSides(); x++) { float next = LocationManager.getDistance(CircleCenter, StationaryPoly.GetCorner(x)); build.Add(new Pair <float, bool, float>(next, false, LocationManager.getRotation(CircleCenter, StationaryPoly.GetCorner(x)))); if (lowestOther == -1 || next < lowestOther) { lowestOther = next; } } distances = build.Finish(); float currentMin = amt; for (int i = 0; i < distances.Length; i++) { for (int i2 = 0; i2 < (distances[i].second ? StationaryPoly.NumberOfSides() : myPoly.NumberOfSides()); i2++) { Vector2[] line = (distances[i].second ? StationaryPoly.GetEdge(i2) : myPoly.GetEdge(i2)); float minAngle = distances[i].third; foreach (float f in LocationManager.CircleIntersects_A(line, CircleCenter, distances[i].first)) { lines.Add(new Vector2[] { Vector2.Add(new Vector2(-2, 0), LocationManager.moveByRotation(CircleCenter, distances[i].first, f)), Vector2.Add(new Vector2(2, 0), LocationManager.moveByRotation(CircleCenter, distances[i].first, f)) }); linecolors.Add(Color.Red); lines.Add(new Vector2[] { Vector2.Add(new Vector2(0, -2), LocationManager.moveByRotation(CircleCenter, distances[i].first, f)), Vector2.Add(new Vector2(0, 2), LocationManager.moveByRotation(CircleCenter, distances[i].first, f)) }); linecolors.Add(Color.Red); if (amt > 0) { if (f > minAngle && LocationManager.NormalRelitiveAngle(minAngle, f) < amt) { lines.Add(new Vector2[] { Vector2.Add(new Vector2(-8, 0), LocationManager.moveByRotation(CircleCenter, distances[i].first, f)), Vector2.Add(new Vector2(8, 0), LocationManager.moveByRotation(CircleCenter, distances[i].first, f)) }); linecolors.Add(Color.Blue); lines.Add(new Vector2[] { Vector2.Add(new Vector2(0, -8), LocationManager.moveByRotation(CircleCenter, distances[i].first, f)), Vector2.Add(new Vector2(0, 8), LocationManager.moveByRotation(CircleCenter, distances[i].first, f)) }); linecolors.Add(Color.Blue); } if (f > (minAngle) && LocationManager.NormalRelitiveAngle(minAngle, f) < currentMin) { currentMin = LocationManager.NormalRelitiveAngle(minAngle, f); } } else if (amt < 0) { if (f < minAngle && LocationManager.NormalRelitiveAngle(f, minAngle) < -amt) { lines.Add(new Vector2[] { Vector2.Add(new Vector2(-8, 0), LocationManager.moveByRotation(CircleCenter, distances[i].first, f)), Vector2.Add(new Vector2(8, 0), LocationManager.moveByRotation(CircleCenter, distances[i].first, f)) }); linecolors.Add(Color.Blue); lines.Add(new Vector2[] { Vector2.Add(new Vector2(0, -8), LocationManager.moveByRotation(CircleCenter, distances[i].first, f)), Vector2.Add(new Vector2(0, 8), LocationManager.moveByRotation(CircleCenter, distances[i].first, f)) }); linecolors.Add(Color.Blue); } if (f < minAngle && LocationManager.NormalRelitiveAngle(f, minAngle) < -currentMin) { currentMin = LocationManager.NormalRelitiveAngle(f, minAngle); } } } } } if (currentMin == amt) { myPoly.Rotation += amt; return(false); } else { myPoly.Rotation += currentMin * .9f; amt *= -.9f; return(true); } }
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); }
/// <summary> /// Converts a rectangle into an equivalent polygon /// </summary> /// <param name="r"></param> /// <returns></returns> public static Polygon GetFromRectangle(Rectangle r) { Polygon tmp = new Polygon(UNIT_SQUARE(), LocationManager.getVectorFromPoint(r.Center), 0); tmp.Scale(r.Width, r.Height); return tmp; }