Пример #1
0
        private LandblockGroup DoTrySplit()
        {
            var landblockGroupSplitHelper = new LandblockGroupSplitHelper();

            var remainingLandblocks = new List <Landblock>(landblocks);

            landblockGroupSplitHelper.Add(remainingLandblocks[remainingLandblocks.Count - 1]);
            remainingLandblocks.RemoveAt(remainingLandblocks.Count - 1);

doAnotherPass:
            bool needsAnotherPass = false;

            for (int i = remainingLandblocks.Count - 1; i >= 0; i--)
            {
                if (landblockGroupSplitHelper.BoundaryDistance(remainingLandblocks[i]) < LandblockGroupMinSpacing)
                {
                    landblockGroupSplitHelper.Add(remainingLandblocks[i]);
                    remainingLandblocks.RemoveAt(i);
                    needsAnotherPass = true;
                }
            }

            if (needsAnotherPass)
            {
                goto doAnotherPass;
            }

            // If they're the same size, there's no split possible
            if (Count == landblockGroupSplitHelper.Count)
            {
                return(null);
            }

            // Split was a success
            var newLandblockGroup = new LandblockGroup();

            foreach (var landblock in landblockGroupSplitHelper)
            {
                // Remove the split landblocks. Do this manually, not through the public Remove() function
                landblocks.Remove(landblock);

                // Add them through the proper .Add() method to the new LandblockGroup
                newLandblockGroup.Add(landblock);
            }

            RecalculateBoundaries();

            // This can result in returning groups that overlap this ones boundary.
            // However, that isn't a problem for processing them on separate threads.
            // In the event a new landblock is added that is within range of both this block and any new block, they will be recombined at that point.

            return(newLandblockGroup);
        }
Пример #2
0
 /// <summary>
 /// This will calculate the distance between the landblock group boarders.<para />
 /// -X = Inside the bounds, where -1 is an overlapping outer perimeter<para />
 ///  0 = Outside of the bounds but adjacent (touching)<para />
 /// +X = Has X landblocks between this and the bounds of the group<para />
 /// Distances are measured horizontally and vertically (not diagonally) pictured here: https://math.stackexchange.com/questions/2724537/finding-the-clear-spacing-distance-between-two-rectangles
 /// </summary>
 public int BoundaryDistance(LandblockGroup landblockGroup)
 {
     return((int)Math.Max(
                Math.Abs(xCenter - landblockGroup.xCenter) - (width + landblockGroup.width) / 2.0,
                Math.Abs(yCenter - landblockGroup.yCenter) - (height + landblockGroup.height) / 2.0));
 }