/// <summary> /// The constructor of the grid spatial partition algorithm /// </summary> /// <param name="maxX">The max x value</param> /// <param name="maxY">The max y value</param> /// <param name="areaSize">The Size of a grid area</param> /// <param name="xOffset"></param> /// <param name="yOffset"></param> /// <param name="distance"></param> public Grid2(int maxX, int maxY, int areaSize, int xOffset, int yOffset, int distance = 0) { if (distance > areaSize) { throw new ArgumentException("Distance shouldn't be larger then area size:"); } this.maxX = maxX + xOffset; this.maxY = maxY + yOffset; this.areaSize = areaSize; this.xOffset = xOffset; this.yOffset = yOffset; this.distance = distance; maxXAreaIndex = this.maxX / areaSize; maxYAreaIndex = this.maxY / areaSize; entityAreas = new GridEntity[maxXAreaIndex][]; for (var i = 0; i < maxXAreaIndex; i++) { entityAreas[i] = new GridEntity[maxYAreaIndex]; for (var j = 0; j < maxYAreaIndex; j++) { entityAreas[i][j] = null; } } }
public override void Add(IEntity entity) { var entityPositionX = entity.Position.X + xOffset; var entityPositionY = entity.Position.Y + yOffset; var range = entity.Range; // we actually have a circle but we use this as a square for performance reasons // we now find all areas that are inside this square var squareMaxX = entityPositionX + range; var squareMaxY = entityPositionY + range; var squareMinX = entityPositionX - range; var squareMinY = entityPositionY - range; // We first use starting y index to start filling var startingYIndex = (int)Math.Floor(squareMinY / areaSize); // We now define starting x index to start filling var startingXIndex = (int)Math.Floor(squareMinX / areaSize); // Also define stopping indexes var stoppingYIndex = (int)Math.Ceiling(squareMaxY / areaSize); var stoppingXIndex = (int)Math.Ceiling(squareMaxX / areaSize); if (startingXIndex < 0) { return; } if (startingYIndex < 0) { return; } if (stoppingXIndex >= maxXAreaIndex) { return; } if (stoppingYIndex >= maxYAreaIndex) { return; } // Now fill all areas from min {x, y} to max {x, y} for (var j = startingXIndex; j <= stoppingXIndex; j++) { var xArr = entityAreas[j]; for (var i = startingYIndex; i <= stoppingYIndex; i++) { var gridEntity = new GridEntity(entity, null, xArr[i]); xArr[i] = gridEntity; if (gridEntity.Next != null) { gridEntity.Next.Prev = gridEntity; } } } }