Exemple #1
0
        /// <summary>
        /// Calculates potential total blocked area by placing object on given position
        /// </summary>
        private double GetBelowUnavaibleArea(Position2D positionToPlace, SkylineContainer2D container2D, int objectWidth)
        {
            double totalBlockedArea = 0.0;

            int endOfObjectWidth = positionToPlace.X + objectWidth;

            foreach (var availableSkyline in container2D.AvailableSkylines.ToList())
            {
                // Checks only skylines below place
                if (availableSkyline.Y <= positionToPlace.Y)
                {
                    // Object completely cover skyline below - no unused space
                    if (availableSkyline.X >= positionToPlace.X &&
                        availableSkyline.X2 <= endOfObjectWidth)
                    {
                        //totalBlockedArea += 0;
                        continue;
                    }

                    // Object partially cover skyline below (left) - unused space on right
                    if (availableSkyline.X < positionToPlace.X &&
                        availableSkyline.X2 <= endOfObjectWidth &&
                        availableSkyline.X2 > positionToPlace.X)
                    {
                        totalBlockedArea += (endOfObjectWidth - availableSkyline.X) * (positionToPlace.Y - availableSkyline.Y);
                        continue;
                    }

                    // Object partially cover skyline below (right) - unused space on left
                    if (availableSkyline.X >= positionToPlace.X &&
                        availableSkyline.X < endOfObjectWidth &&
                        availableSkyline.X2 > endOfObjectWidth)
                    {
                        totalBlockedArea += (availableSkyline.X2 - positionToPlace.X) * (positionToPlace.Y - availableSkyline.Y);
                        continue;
                    }
                    // Object partially cover skyline below from both size -> unused space on left and right
                    if (availableSkyline.X < positionToPlace.X &&
                        availableSkyline.X2 > endOfObjectWidth)
                    {
                        //left
                        totalBlockedArea += (positionToPlace.X - availableSkyline.X) * (availableSkyline.Y * positionToPlace.Y);
                        //right
                        totalBlockedArea += (availableSkyline.X2 - endOfObjectWidth) * (availableSkyline.Y * positionToPlace.Y);
                    }
                }
            }



            return(totalBlockedArea);
        }
        public override void Execute(ObjectSet originalObjects)
        {
            double bestFitResult = Double.MaxValue;
            double currentFitResult;

            int selectedFitContainerIndex = 0;

            Position2D positionToPlace = null;

            SkylineContainer2D selectedContainer = containers.First() as SkylineContainer2D;

            var objectsCopy = originalObjects.ToObjectList();

            while (objectsCopy.Any())
            {
                Object2D selectedObject = objectsCopy.First() as Object2D;

                for (int i = 0; i < containers.Count; i++)
                {
                    currentFitResult = FindBestFitWithinContainer(containers[i] as SkylineContainer2D, selectedObject, bestFitResult, ref positionToPlace);

                    if (currentFitResult < bestFitResult)
                    {
                        bestFitResult             = currentFitResult;
                        selectedFitContainerIndex = i;
                        break;
                    }
                }

                // Object not placed, create new container, place object bottom-left
                if (positionToPlace == null)
                {
                    AddContainer();

                    selectedContainer = containers.Last() as SkylineContainer2D;

                    positionToPlace = new Position2D(0, 0);
                }
                else
                {
                    selectedContainer = containers[selectedFitContainerIndex] as SkylineContainer2D;
                }

                objectsCopy.Remove(selectedObject);
                selectedContainer.PlaceNewObject(selectedObject, positionToPlace);
                selectedFitContainerIndex = 0;
                bestFitResult             = Double.MaxValue;
                positionToPlace           = null;
            }
        }
Exemple #3
0
        public override void Execute(ObjectSet originalObjects)
        {
            int selectedFitContainerIndex = 0;

            Position2D positionToPlace = null;

            SkylineContainer2D selectedContainer = containers.First() as SkylineContainer2D;

            var objectsCopy = originalObjects.ToObjectList();

            while (objectsCopy.Any())
            {
                Object2D selectedObject = objectsCopy.First() as Object2D;

                for (int i = 0; i < containers.Count; i++)
                {
                    positionToPlace = FindMostBottomFittingSkyline(containers[i] as SkylineContainer2D, selectedObject);

                    if (positionToPlace != null)
                    {
                        selectedFitContainerIndex = i;
                        break;
                    }
                }

                // Object not placed, create new container, place object bottom-left
                if (positionToPlace == null)
                {
                    AddContainer();

                    selectedContainer = containers.Last() as SkylineContainer2D;

                    positionToPlace = new Position2D(0, 0);
                }
                else
                {
                    selectedContainer = containers[selectedFitContainerIndex] as SkylineContainer2D;
                }

                objectsCopy.Remove(selectedObject);
                selectedContainer.PlaceNewObject(selectedObject, positionToPlace);
                selectedFitContainerIndex = 0;
            }
        }
Exemple #4
0
        protected Position2D CheckShiftedPositionAvailability(SkylineContainer2D container2D, Object2D objectToPlace, Line currentSkyline)
        {
            //Skylines on left side of currently checked skyline, starting from nearest
            var skylinesOnLeft = container2D.AvailableSkylines.Where(x => x.X < currentSkyline.X).OrderByDescending(x => x.X).ToList();

            Position2D mostLeftPosition = new Position2D(currentSkyline.X, currentSkyline.Y);

            // Look if object can be moved further to left, i.e. skyylines on left are below current skyline
            foreach (Line skyline in skylinesOnLeft)
            {
                if (skyline.Y < currentSkyline.Y)
                {
                    mostLeftPosition.X = skyline.X;
                }
                else
                {
                    break;
                }
            }

            // Part protruding on the right side of current skyline
            int protrudingPartLenght = mostLeftPosition.X + objectToPlace.Width - currentSkyline.X2;

            // If it exceed container width, then break
            if (protrudingPartLenght + currentSkyline.X2 > container2D.Width)
            {
                return(null);
            }

            //Skylines on right side of currently checked skyline covered by protruding part, starting from nearest
            var skylinesOnRight = container2D.AvailableSkylines.Where(x => x.X > currentSkyline.X && x.X < currentSkyline.X2 + protrudingPartLenght).OrderBy(x => x.X).ToList();

            // Check if skylines on right are below object; If yes, it can be placed, otherwise object would overlap
            foreach (Line skyline in skylinesOnRight)
            {
                if (skyline.Y > currentSkyline.Y)
                {
                    mostLeftPosition = null;
                    break;
                }
            }

            return(mostLeftPosition);
        }
Exemple #5
0
        protected double FindBestFitWithinContainer(SkylineContainer2D container2D, Object2D objectToPlace, double globallyBestFit, ref Position2D bestGlobalFitPosition)
        {
            var sortedSkylines = container2D.AvailableSkylines.OrderBy(o => o.Y).ToList();

            Position2D leftShiftedPosition, bestFitPosition = null;
            double     currentFitValue, bestFitValueInContainer = Double.MaxValue;

            foreach (Line skyline in sortedSkylines)
            {
                // Skyline + object is higher than container; As skylines are sorted from lowest, break on first compatible statement
                if (skyline.Y + objectToPlace.Height > container2D.Height)
                {
                    break;
                }


                leftShiftedPosition = CheckShiftedPositionAvailability(container2D, objectToPlace, skyline);
                if (leftShiftedPosition != null)
                {
                    currentFitValue = GetBelowUnavaibleArea(leftShiftedPosition, container2D, objectToPlace.Width);

                    if (currentFitValue < bestFitValueInContainer)
                    {
                        bestFitValueInContainer = currentFitValue;
                        bestFitPosition         = leftShiftedPosition;
                    }
                }
            }

            if (bestFitValueInContainer < globallyBestFit)
            {
                bestGlobalFitPosition = bestFitPosition;
                return(bestFitValueInContainer);
            }
            else
            {
                return(globallyBestFit);
            }
        }
Exemple #6
0
        private Position2D FindMostBottomFittingSkyline(SkylineContainer2D container2D, Object2D objectToPlace)
        {
            var sortedSkylines = container2D.AvailableSkylines.OrderBy(o => o.Y);

            Position2D leftShiftedPosition = null;

            foreach (Line skyline in sortedSkylines)
            {
                // Skyline + object is higher than container; As skylines are sorted from lowest, break on first compatible statement
                if (skyline.Y + objectToPlace.Height > container2D.Height)
                {
                    break;
                }

                // Object is wider than skyline
                leftShiftedPosition = CheckShiftedPositionAvailability(container2D, objectToPlace, skyline);
                if (leftShiftedPosition != null)
                {
                    return(leftShiftedPosition);
                }
            }

            return(null);
        }