예제 #1
0
        /// <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;
                }
            }
        }
예제 #2
0
        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;
                    }
                }
            }
        }