private static void seeTilesQuad(Seeable[,] world, Vector2 location, Vector2 angles, float distance, int quad, RoundingMode rmode, params object[] parameters) { Queue <SightCol> queue = new Queue <SightCol>(); int tilesize = world[0, 0].getBounds().Width; int curDist = 0; enqueNext(world, location, tilesize, queue, curDist, angles, quad, rmode); while (queue.Count != 0) //Process Row { curDist++; SightCol s = queue.Dequeue(); Vector2 newAngles = new Vector2(0, 0); bool curblock = false; bool topused = false; bool firstblock = true; while (!s.isDone()) { Seeable seb = s.getNextSeeable(); if (LocationManager.distanceCheck(location, new Vector2(seb.getBounds().X, seb.getBounds().Y), distance)) { seb.see(parameters); if (firstblock) { firstblock = false; topused = true; newAngles.X = angles.X; } if (seb.isTransparent() && curblock) { topused = true; curblock = false; newAngles.X = getAngleToNessecaryCorner(location, seb.getBounds(), quad, true); } else if (!seb.isTransparent()) { if (topused && !curblock) { newAngles.Y = getAngleToNessecaryCorner(location, seb.getBounds(), quad, false); enqueNext(world, location, tilesize, queue, s.cDist + 1, newAngles, quad, rmode); } else if (!curblock) { curblock = true; } } } } if (curblock) { newAngles.Y = s.angles.Y; enqueNext(world, location, tilesize, queue, s.cDist + 1, newAngles, quad, rmode); } } }
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); }
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(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); }