コード例 #1
0
        /// <summary>
        /// questo metodo calcola l'hatched area in basso e a sinistra dell'item.
        /// Infine, ritorna la somma delle due.
        /// Ritorna -1 se l'item, per come è posizionato, eccede le dimensioni del bin
        /// </summary>
        /// <param name="feasiblePoint"></param>
        /// <param name="newNestedItem"></param>
        /// <param name="temporaryBin"></param>
        /// <param name="temporaryItem"></param>
        /// <returns></returns>
        private float GetHatchedArea(Tuple feasiblePoint, NestedItem newNestedItem, Bin <Tuple> temporaryBin, Item temporaryItem)
        {
            float downtHatchedArea = PushItemDown(feasiblePoint, temporaryBin, temporaryItem, newNestedItem);
            float leftHatchedArea  = PushItemLeft(feasiblePoint, temporaryBin, temporaryItem, newNestedItem);

            //controllo se l'oggettto, anche essendo stato spostato in basso a sintra, sborda
            if (IsBorderObserved(newNestedItem, temporaryBin.Height, temporaryBin.Width))
            {
                return(downtHatchedArea + leftHatchedArea);
            }
            else
            {
                return(-1);
            }
        }
コード例 #2
0
 /// <summary>
 /// Questo metodo controlla se le dimensione dell'item eccedono quelle del bin
 /// </summary>
 /// <param name="newNestedItem"></param>
 /// <param name="temporaryBinHeight"></param>
 /// <param name="temporaryBinWidth"></param>
 /// <returns></returns>
 bool IsBorderObserved(NestedItem newNestedItem, float temporaryBinHeight, float temporaryBinWidth)
 {
     return(newNestedItem.TLqPosition <= temporaryBinHeight && newNestedItem.BRpPosition <= temporaryBinWidth);
 }
コード例 #3
0
        /// <summary>
        /// metodo per stabilire se è possibile
        /// trovare una posizione in cui nestare
        /// un nuovo item
        /// </summary>
        /// <param name="temporaryBin"></param>
        /// <param name="temporaryItem"></param>
        /// <returns></returns>
        public bool IsBestPositionFound(Bin <Tuple> temporaryBin, Item temporaryItem)
        {
            SetFeasiblePoints(temporaryBin, temporaryItem);

            //se il bin non contiene punti
            if (temporaryBin.Points.Count == 0)
            {
                return(false);
            }
            else if (temporaryBin.Points.Count == 1 && //se il bin contiene 1 solo punto e quel punto è (0,0)
                     temporaryBin.Points.ElementAt(0).Pposition == 0 &&
                     temporaryBin.Points.ElementAt(0).Qposition == 0)
            {
                temporaryBin.NestedItems = new List <NestedItem>
                {
                    new NestedItem(temporaryItem)
                    {
                        BLpPosition = 0,
                        BLqPosition = 0,
                        BRpPosition = temporaryItem.Width,
                        BRqPosition = 0,
                        TLpPosition = 0,
                        TLqPosition = temporaryItem.Height
                    }
                };

                HandleOperationsPostNestedItem(temporaryBin, temporaryItem, temporaryBin.Points.ElementAt(0));
                return(true);
            }
            else if (temporaryBin.Points.Count > 1)//se il bin contiene n punti
            {
                foreach (var feasiblePoint in temporaryBin.Points)
                {
                    if (!feasiblePoint.IsUsed)
                    {
                        //assegno le coordinate di partenza al nuovo item da nestare, poi inzio a muoverlo
                        NestedItem newNestedItem = new NestedItem(temporaryItem)
                        {
                            BLpPosition = feasiblePoint.Pposition,
                            BLqPosition = feasiblePoint.Qposition,
                            BRpPosition = feasiblePoint.Pposition + temporaryItem.Width,
                            BRqPosition = feasiblePoint.Qposition,
                            TLpPosition = feasiblePoint.Pposition,
                            TLqPosition = feasiblePoint.Qposition + temporaryItem.Height
                        };
                        feasiblePoint.HatchedArea = GetHatchedArea(feasiblePoint, newNestedItem, temporaryBin, temporaryItem);
                    }
                }

                //trovo la tupla con lo scarto minore tra quelle ancora disponibili
                //(Where(x => x.HatchedArea >= 0) filtra solo le tuple con hatched area = 0)
                Tuple minHatchedAreaTuple = temporaryBin.Points.Where(x => x.IsUsed == false && x.HatchedArea >= 0)
                                            .OrderBy(x => x.HatchedArea)
                                            .First();

                //controllo se ho più tuple che hanno lo stesso scarto (il minore)
                IList <Tuple> minHatchedAreaPoints = new List <Tuple>();
                foreach (var point in temporaryBin.Points)
                {
                    if (point.HatchedArea == minHatchedAreaTuple.HatchedArea && !point.IsUsed)
                    {
                        minHatchedAreaPoints.Add(point);
                    }
                }

                if (minHatchedAreaPoints.Count == 1)
                {
                    var minHatchedAreaPoint = minHatchedAreaPoints.ElementAt(0);

                    temporaryBin.NestedItems.Add(new NestedItem(temporaryItem)
                    {
                        BLpPosition = minHatchedAreaPoint.PfinalPosition,
                        BLqPosition = minHatchedAreaPoint.QfinalPosition,
                        BRpPosition = minHatchedAreaPoint.PfinalPosition + temporaryItem.Width,
                        BRqPosition = minHatchedAreaPoint.QfinalPosition,
                        TLpPosition = minHatchedAreaPoint.PfinalPosition,
                        TLqPosition = minHatchedAreaPoint.QfinalPosition + temporaryItem.Height
                    });

                    HandleOperationsPostNestedItem(temporaryBin, temporaryItem, minHatchedAreaPoint);
                    return(true);
                }
                else if (minHatchedAreaPoints.Count > 1)
                {
                    Tuple minCoordinatePoint = ApplyRule(minHatchedAreaPoints);

                    temporaryBin.NestedItems.Add(new NestedItem(temporaryItem)
                    {
                        BLpPosition = minCoordinatePoint.PfinalPosition,
                        BLqPosition = minCoordinatePoint.QfinalPosition,
                        BRpPosition = minCoordinatePoint.PfinalPosition + temporaryItem.Width,
                        BRqPosition = minCoordinatePoint.QfinalPosition,
                        TLpPosition = minCoordinatePoint.PfinalPosition,
                        TLqPosition = minCoordinatePoint.QfinalPosition + temporaryItem.Height
                    });

                    HandleOperationsPostNestedItem(temporaryBin, temporaryItem, minCoordinatePoint);
                    return(true);
                }
            }
            return(false);
        }
コード例 #4
0
        /// <summary>
        /// questo metodo spinge a sinistra un nuovo item e
        /// calcolo l'hatched area a sinistra del nuovo iten
        /// </summary>
        /// <param name="feasiblePoint"></param>
        /// <param name="temporaryBin"></param>
        /// <param name="temporaryItem"></param>
        /// <param name="newNestedItem"></param>
        /// <returns></returns>
        private float PushItemLeft(Tuple feasiblePoint, Bin <Tuple> temporaryBin, Item temporaryItem, NestedItem newNestedItem)
        {
            //variabile per l'hatched area che eventualmente rimane a sinistra del nuovo item
            float hatchedArea = 0;

            //lista delle intersezioni tra item nuovo e item già in soluzione
            IList <NestedItem> intersectedItems = new List <NestedItem>();

            bool areIntersectedItemsPresent = false;

            foreach (var nestedItem in temporaryBin.NestedItems)
            {
                if (feasiblePoint.Qposition < nestedItem.TLqPosition &&
                    feasiblePoint.Qposition >= nestedItem.BRqPosition &&
                    feasiblePoint.Pposition >= nestedItem.BRpPosition)
                {
                    intersectedItems.Add(nestedItem);
                }
            }

            //3 possibili risultati
            if (intersectedItems.Count == 0) //non ho intersezioni
            {
                newNestedItem.BLpPosition = 0;
                newNestedItem.TLpPosition = 0;
                newNestedItem.BRpPosition = temporaryItem.Width;
            }
            else
            {
                if (intersectedItems.Count == 1) //1 sola intersezione
                {
                    float delta = feasiblePoint.Pposition - intersectedItems.ElementAt(0).Width;
                    newNestedItem.BLpPosition -= delta;
                    newNestedItem.TLpPosition -= delta;
                    newNestedItem.BRpPosition -= delta;
                }
                else if (intersectedItems.Count > 1) //N intersezioni
                {
                    float widthSum = 0;
                    foreach (var intersectedItem in intersectedItems)
                    {
                        widthSum += intersectedItem.Width;
                    }
                    float delta = feasiblePoint.Pposition - widthSum;
                    newNestedItem.BLpPosition -= delta;
                    newNestedItem.TLpPosition -= delta;
                    newNestedItem.BRpPosition -= delta;
                }

                areIntersectedItemsPresent = true;
            }

            feasiblePoint.PfinalPosition = newNestedItem.BLpPosition;
            if (areIntersectedItemsPresent)
            {
                //altezza della green area
                float greenAreaHeight = newNestedItem.Height;

                //ampiezza dellea green area
                float greenAreaWidth = newNestedItem.BLpPosition;

                //definiso la green area a sintra del nuovo item
                GreenZone greenZone = new GreenZone()
                {
                    BRpPosition = feasiblePoint.PfinalPosition,
                    BRqPosition = feasiblePoint.QfinalPosition,
                    TRpPosition = feasiblePoint.PfinalPosition,
                    TRqPosition = feasiblePoint.QfinalPosition + newNestedItem.Height,
                    BLpPosition = 0,
                    BLqPosition = feasiblePoint.QfinalPosition,
                    TLpPosition = 0,
                    TLqPosition = feasiblePoint.QfinalPosition + newNestedItem.Height,
                    Area        = greenAreaHeight * greenAreaWidth
                };

                //per ogni item già in posizione, che è stato intersecato,
                //calcolo quanta parte di area di esso rientra nella green area e
                //infine sommo tale area all'area totale degli item intersecati
                float itemsInSolutionArea = 0;
                float intersectedHeight   = 0;
                foreach (var intersectedItem in intersectedItems)
                {
                    //guardo se è più in alto l'item intersecato o il nuovo item
                    if (newNestedItem.TLqPosition > intersectedItem.TLqPosition)
                    {
                        intersectedHeight = Math.Abs(intersectedItem.TLqPosition - greenZone.BLqPosition);
                    }
                    else if (newNestedItem.TLqPosition <= intersectedItem.TLqPosition)
                    {
                        intersectedHeight = newNestedItem.Height;
                    }
                    itemsInSolutionArea += (intersectedHeight * intersectedItem.Width);
                }

                hatchedArea = greenZone.Area - itemsInSolutionArea;
            }

            return(hatchedArea);
        }