private void UpdateRepositionDirectionsFor(AxisAlignedRectangle newAar)
        {
            // Let's see what is surrounding this rectangle and update it and the surrounding rects appropriately
            float keyValue = GetKeyValue(newAar.X, newAar.Y);

            float keyValueBefore = keyValue - GridSize * 3 / 2.0f;
            float keyValueAfter  = keyValue + GridSize * 3 / 2.0f;

            int before = Rectangles.GetFirstAfter(keyValueBefore, mSortAxis, 0, Rectangles.Count);
            int after  = Rectangles.GetFirstAfter(keyValueAfter, mSortAxis, 0, Rectangles.Count);

            AxisAlignedRectangle leftOf  = GetTileAt(newAar.X - GridSize, newAar.Y, before, after);
            AxisAlignedRectangle rightOf = GetTileAt(newAar.X + GridSize, newAar.Y, before, after);
            AxisAlignedRectangle above   = GetTileAt(newAar.X, newAar.Y + GridSize, before, after);
            AxisAlignedRectangle below   = GetTileAt(newAar.X, newAar.Y - GridSize, before, after);

            RepositionDirections directions = RepositionDirections.All;

            if (leftOf != null)
            {
                directions -= RepositionDirections.Left;
                if ((leftOf.RepositionDirections & RepositionDirections.Right) == RepositionDirections.Right)
                {
                    leftOf.RepositionDirections -= RepositionDirections.Right;
                }
            }
            if (rightOf != null)
            {
                directions -= RepositionDirections.Right;

                if ((rightOf.RepositionDirections & RepositionDirections.Left) == RepositionDirections.Left)
                {
                    rightOf.RepositionDirections -= RepositionDirections.Left;
                }
            }
            if (above != null)
            {
                directions -= RepositionDirections.Up;

                if ((above.RepositionDirections & RepositionDirections.Down) == RepositionDirections.Down)
                {
                    above.RepositionDirections -= RepositionDirections.Down;
                }
            }
            if (below != null)
            {
                directions -= RepositionDirections.Down;
                if ((below.RepositionDirections & RepositionDirections.Up) == RepositionDirections.Up)
                {
                    below.RepositionDirections -= RepositionDirections.Up;
                }
            }

            newAar.RepositionDirections = directions;
        }
        public void RemoveCollisionAtWorld(float x, float y)
        {
            AxisAlignedRectangle existing = GetTileAt(x, y);

            if (existing != null)
            {
                ShapeManager.Remove(existing);

                float keyValue = GetKeyValue(existing.X, existing.Y);

                float keyValueBefore = keyValue - GridSize * 3 / 2.0f;
                float keyValueAfter  = keyValue + GridSize * 3 / 2.0f;

                int before = Rectangles.GetFirstAfter(keyValueBefore, mSortAxis, 0, Rectangles.Count);
                int after  = Rectangles.GetFirstAfter(keyValueAfter, mSortAxis, 0, Rectangles.Count);

                AxisAlignedRectangle leftOf  = GetTileAt(existing.X - GridSize, existing.Y, before, after);
                AxisAlignedRectangle rightOf = GetTileAt(existing.X + GridSize, existing.Y, before, after);
                AxisAlignedRectangle above   = GetTileAt(existing.X, existing.Y + GridSize, before, after);
                AxisAlignedRectangle below   = GetTileAt(existing.X, existing.Y - GridSize, before, after);

                if (leftOf != null && (leftOf.RepositionDirections & RepositionDirections.Right) != RepositionDirections.Right)
                {
                    leftOf.RepositionDirections |= RepositionDirections.Right;
                }
                if (rightOf != null && (rightOf.RepositionDirections & RepositionDirections.Left) != RepositionDirections.Left)
                {
                    rightOf.RepositionDirections |= RepositionDirections.Left;
                }

                if (above != null && (above.RepositionDirections & RepositionDirections.Down) != RepositionDirections.Down)
                {
                    above.RepositionDirections |= RepositionDirections.Down;
                }

                if (below != null && (below.RepositionDirections & RepositionDirections.Up) != RepositionDirections.Up)
                {
                    below.RepositionDirections |= RepositionDirections.Up;
                }
            }
        }
        private RepositionDirections UpdateRepositionForNeighborsAndGetThisRepositionDirection(PositionedObject positionedObject)
        {
            // Let's see what is surrounding this rectangle and update it and the surrounding rects appropriately
            float keyValue = GetCoordinateValueForPartitioning(positionedObject.Position.X, positionedObject.Position.Y);

            float keyValueBefore = keyValue - GridSize * 3 / 2.0f;
            float keyValueAfter  = keyValue + GridSize * 3 / 2.0f;

            int rectanglesBeforeIndex = Rectangles.GetFirstAfter(keyValueBefore, mSortAxis, 0, Rectangles.Count);
            int rectanglesAfterIndex  = Rectangles.GetFirstAfter(keyValueAfter, mSortAxis, 0, Rectangles.Count);

            int polygonsBeforeIndex = Polygons.GetFirstAfter(keyValueBefore, mSortAxis, 0, Polygons.Count);
            int polygonsAfterIndex  = Rectangles.GetFirstAfter(keyValueAfter, mSortAxis, 0, Polygons.Count);


            float leftOfX  = positionedObject.Position.X - GridSize;
            float rightOfX = positionedObject.Position.X + GridSize;
            float middleX  = positionedObject.Position.X;

            float aboveY  = positionedObject.Position.Y + GridSize;
            float belowY  = positionedObject.Position.Y - GridSize;
            float middleY = positionedObject.Position.Y;

            AxisAlignedRectangle rectangleLeftOf  = GetRectangleAtPosition(leftOfX, middleY, rectanglesBeforeIndex, rectanglesAfterIndex);
            AxisAlignedRectangle rectangleRightOf = GetRectangleAtPosition(rightOfX, middleY, rectanglesBeforeIndex, rectanglesAfterIndex);
            AxisAlignedRectangle rectangleAbove   = GetRectangleAtPosition(middleX, aboveY, rectanglesBeforeIndex, rectanglesAfterIndex);
            AxisAlignedRectangle rectangleBelow   = GetRectangleAtPosition(middleX, belowY, rectanglesBeforeIndex, rectanglesAfterIndex);

            RepositionDirections directions = RepositionDirections.All;

            if (rectangleLeftOf != null)
            {
                directions -= RepositionDirections.Left;
                if ((rectangleLeftOf.RepositionDirections & RepositionDirections.Right) == RepositionDirections.Right)
                {
                    rectangleLeftOf.RepositionDirections -= RepositionDirections.Right;
                }
            }
            else
            {
                var polygon = GetPolygonAtPosition(leftOfX, middleY, polygonsBeforeIndex, polygonsAfterIndex);

                if (polygon != null)
                {
                    directions -= RepositionDirections.Left;
                    if ((polygon.RepositionDirections & RepositionDirections.Right) == RepositionDirections.Right)
                    {
                        polygon.RepositionDirections -= RepositionDirections.Right;
                    }
                }
            }

            if (rectangleRightOf != null)
            {
                directions -= RepositionDirections.Right;

                if ((rectangleRightOf.RepositionDirections & RepositionDirections.Left) == RepositionDirections.Left)
                {
                    rectangleRightOf.RepositionDirections -= RepositionDirections.Left;
                }
            }
            else
            {
                var polygon = GetPolygonAtPosition(rightOfX, middleY, polygonsBeforeIndex, polygonsAfterIndex);

                if (polygon != null)
                {
                    directions -= RepositionDirections.Right;
                    if ((polygon.RepositionDirections & RepositionDirections.Left) == RepositionDirections.Left)
                    {
                        polygon.RepositionDirections -= RepositionDirections.Left;
                    }
                }
            }



            if (rectangleAbove != null)
            {
                directions -= RepositionDirections.Up;

                if ((rectangleAbove.RepositionDirections & RepositionDirections.Down) == RepositionDirections.Down)
                {
                    rectangleAbove.RepositionDirections -= RepositionDirections.Down;
                }
            }
            else
            {
                var polygon = GetPolygonAtPosition(middleX, aboveY, polygonsBeforeIndex, polygonsAfterIndex);

                if (polygon != null)
                {
                    directions -= RepositionDirections.Up;

                    if ((polygon.RepositionDirections & RepositionDirections.Down) == RepositionDirections.Down)
                    {
                        polygon.RepositionDirections -= RepositionDirections.Down;
                    }
                }
            }

            if (rectangleBelow != null)
            {
                directions -= RepositionDirections.Down;
                if ((rectangleBelow.RepositionDirections & RepositionDirections.Up) == RepositionDirections.Up)
                {
                    rectangleBelow.RepositionDirections -= RepositionDirections.Up;
                }
            }
            else
            {
                var polygon = GetPolygonAtPosition(middleX, belowY, polygonsBeforeIndex, polygonsAfterIndex);

                if (polygon != null)
                {
                    directions -= RepositionDirections.Down;

                    if ((polygon.RepositionDirections & RepositionDirections.Up) == RepositionDirections.Up)
                    {
                        polygon.RepositionDirections -= RepositionDirections.Up;
                    }
                }
            }

            return(directions);
        }