/// <summary> /// /// </summary> /// <param name="worldObject"></param> /// <returns>A list of all <see cref="GridLocation"/>s containing the <see cref="IWorldObject"/></returns> public List<GridLocation> Intersects(IWorldObject worldObject) { List<GridLocation> found = new List<GridLocation>(gridSize.X * gridSize.Y); List<GridLocation> missed = new List<GridLocation>(gridSize.X * gridSize.Y); UniqueList<GridLocation> toTest = new UniqueList<GridLocation>(gridSize.X * gridSize.Y); UniqueList<GridLocation> newToBeTested = new UniqueList<GridLocation>(gridSize.X * gridSize.Y); // the GridLocation that contains the center of the object GridLocation hasCenter; // STEP 1 - determine the GridLocation of the object's center Point cellCoord; // Use integer division to find cell coordinates. // Since the grid cell coords are in the upperleft corner // 1 must be subtracted from the division if we are in the negative (left or up) // direction - effectively rounding up in absolute value. if (worldObject.Position.X < 0) cellCoord.X = (Int16)(((Int16)worldObject.Position.X / (Int16)cellSize.X) - 1); else cellCoord.X = (Int16)(((Int16)worldObject.Position.X / (Int16)cellSize.X)); if (worldObject.Position.Y < 0) cellCoord.Y = (Int16)(((Int16)worldObject.Position.Y / (Int16)cellSize.Y) - 1); else cellCoord.Y = (Int16)(((Int16)worldObject.Position.Y / (Int16)cellSize.Y)); // check to makes sure these coordinates are in the world if (minGrid.X <= cellCoord.X && cellCoord.X <= maxGrid.X && minGrid.Y <= cellCoord.Y && cellCoord.Y <= maxGrid.Y) { hasCenter = new GridLocation((Int16)cellCoord.X, (Int16)cellCoord.Y, cellSize); } // if they are not in the world, return the empty list else { return found; } // add it to the found list found.Add(hasCenter); // STEP 2 - determine all surrounding GridLocations that contain the object toTest.UnionWith(GetSurrounding(hasCenter)); while (toTest.Count != 0) { foreach (GridLocation gridLocation in toTest) { // if a surrounding GridLocation intersects the object do 4 things if (worldObject.Bounds.Intersects(gridLocation.Bounds)) { // 1. Add it to the found list found.Add(gridLocation); // 2. Get its surrounding GridLocations newToBeTested.UnionWith(GetSurrounding(gridLocation)); // 3. Remove any that are already known to not contain the object foreach (GridLocation g in missed) { newToBeTested.Remove(g); } // 4. Remove any that are already known to contain the object foreach (GridLocation g in found) { newToBeTested.Remove(g); } } // if a surrounding GridLocation DOES NOT intersect the object add it to missed else { missed.Add(gridLocation); } } // since we have checked everything in toTest flush it toTest.Clear(); // add the newly found surrounding candidates to toTest toTest.UnionWith(newToBeTested); // flush the temp list newToBeTested.Clear(); } return found; }
/// <summary> /// Requests the <see cref="Grid"/> to return a list of all <see cref="IWorldObject"/>s /// which share a GridLocation with the given object. /// </summary> /// <param name="worldObject"></param> /// <returns></returns> public List<IWorldObject> PotentialIntersects(IWorldObject worldObject) { UniqueList<IWorldObject> collidables = new UniqueList<IWorldObject>(); // find all grid locations that contain the object List<GridLocation> IntersectedGridCells = Intersects(worldObject); foreach (GridLocation gridLocation in IntersectedGridCells) { // compile a list of all objects contained in the found Grid Locations collidables.UnionWith(getLocationObjectsOf(gridLocation)); } return collidables; }