/// <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 (Tuple 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.HatchedRegion = GetHatchedRegion(feasiblePoint, newNestedItem, temporaryBin, temporaryItem); } } //trovo la tupla con lo scarto minore tra quelle ancora disponibili //(Where(x => x.HatchedRegion >= 0) filtra solo le tuple con hatched region = 0) Tuple minHatchedRegionTuple = temporaryBin.Points.Where(x => x.IsUsed == false && x.HatchedRegion >= 0) .OrderBy(x => x.HatchedRegion) .First(); //controllo se ho più tuple che hanno lo stesso scarto (il minore) IList <Tuple> minHatchedRegionPoints = new List <Tuple>(); foreach (Tuple point in temporaryBin.Points) { if (point.HatchedRegion == minHatchedRegionTuple.HatchedRegion && !point.IsUsed) { minHatchedRegionPoints.Add(point); } } if (minHatchedRegionPoints.Count == 1) { Tuple minHatchedRegionPoint = minHatchedRegionPoints.ElementAt(0); temporaryBin.NestedItems.Add(new NestedItem(temporaryItem) { BLpPosition = minHatchedRegionPoint.PfinalPosition, BLqPosition = minHatchedRegionPoint.QfinalPosition, BRpPosition = minHatchedRegionPoint.PfinalPosition + temporaryItem.Width, BRqPosition = minHatchedRegionPoint.QfinalPosition, TLpPosition = minHatchedRegionPoint.PfinalPosition, TLqPosition = minHatchedRegionPoint.QfinalPosition + temporaryItem.Height }); HandleOperationsPostNestedItem(temporaryBin, temporaryItem, minHatchedRegionPoint); return(true); } else if (minHatchedRegionPoints.Count > 1) { Tuple minCoordinatePoint = ApplyRule(minHatchedRegionPoints); 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); }
/// <summary> /// questo metodo, data la posizione inziale di un item, /// prova a spingerlo in basso e verso sinistra quanto /// più possibile. /// Poi, calcola l'hatched region in basso e a sinistra /// dell'item /// </summary> /// <param name="feasiblePoint"></param> /// <param name="temporaryBin"></param> /// <param name="temporaryItem"></param> /// <returns></returns> private float GetHatchedRegion(Tuple feasiblePoint, NestedItem newNestedItem, Bin <Tuple> temporaryBin, Item temporaryItem) { PushItemDown(feasiblePoint, temporaryBin, temporaryItem, newNestedItem); 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(0); } else { return(-1); } }