public void AddPosition(LayerCyl layer, Vector2D vPosition) { Matrix4D matRot = Matrix4D.Identity; Vector3D vTranslation = Vector3D.Zero; if (_swapped) { matRot = new Matrix4D( 0.0, -1.0, 0.0, 0.0 , 1.0, 0.0, 0.0, 0.0 , 0.0, 0.0, 1.0, 0.0 , 0.0, 0.0, 0.0, 1.0 ); vTranslation = new Vector3D(layer.PalletLength, 0.0, 0.0); } Transform3D transfRot = new Transform3D(matRot); matRot.M14 = vTranslation[0]; matRot.M24 = vTranslation[1]; matRot.M34 = vTranslation[2]; Transform3D transfRotTranslation = new Transform3D(matRot); Vector3D vPositionSwapped = transfRotTranslation.transform(new Vector3D(vPosition.X, vPosition.Y, 0.0)); if (!layer.IsValidPosition(new Vector2D(vPositionSwapped.X, vPositionSwapped.Y))) { _log.Warn(string.Format("Attempt to add an invalid position in pattern = {0}, Swapped = true", this.Name)); return; } layer.Add(new Vector2D(vPositionSwapped.X, vPositionSwapped.Y)); }
public override void GenerateLayer(LayerCyl layer, double actualLength, double actualWidth) { layer.Clear(); double palletLength = GetPalletLength(layer); double palletWidth = GetPalletWidth(layer); double radius = layer.CylinderRadius; double diameter = 2.0 * layer.CylinderRadius; int sizeX = (int)Math.Floor(palletLength / diameter); int sizeY = (int)Math.Floor(palletWidth / diameter); double offsetX = 0.5 * (palletLength - actualLength); double offsetY = 0.5 * (palletWidth - actualWidth); double spaceX = sizeX > 1 ? (actualLength - sizeX * diameter) / (sizeX - 1) : 0.0; double spaceY = sizeY > 1 ? (actualWidth - sizeY * diameter) / (sizeY - 1) : 0.0; for (int j=0; j<sizeY; ++j) for (int i=0; i<sizeX; ++i) AddPosition( layer, new Vector2D( radius + offsetX + i * (diameter + spaceX) , radius + offsetY + j * (diameter + spaceY) )); }
protected double GetPalletLength(LayerCyl layer) { if (!_swapped) return layer.PalletLength; else return layer.PalletWidth; }
public override void GenerateLayer(LayerCyl layer, double actualLength, double actualWidth) { layer.Clear(); double palletLength = GetPalletLength(layer); double palletWidth = GetPalletWidth(layer); double radius = layer.CylinderRadius; double diameter = 2.0 * layer.CylinderRadius; int alignedRowLength = 0, stagRowLength = 0; int rowNumber1 = 0, rowNumber2 = 0; ComputeRowNumberAndLength(layer , out alignedRowLength, out rowNumber1 , out stagRowLength, out rowNumber2 , out actualLength, out actualWidth); double offsetX = 0.5 * (palletLength - actualLength); double offsetY = 0.5 * (palletWidth - actualWidth); for (int j = 0; j < rowNumber1; ++j) for (int i = 0; i < alignedRowLength; ++i) AddPosition(layer, new Vector2D( radius + offsetX + i * diameter , radius + offsetY + j * diameter )); for (int i = 0; i < rowNumber2; ++i) { double y = radius + offsetY + (rowNumber1 - 1.0) * diameter + (i+1) * radius * Math.Sqrt(3.0); for (int j = 0; j < (i % 2 == 0 ? stagRowLength : alignedRowLength); ++j) AddPosition(layer, new Vector2D(offsetX + ((i % 2 != 0) ? 0.0 : radius) + j * 2.0 * radius + radius, y)); } }
private bool ComputeRowNumberAndLength(LayerCyl layer , out int firstRowLength, out int secondRowLength, out int rowNumber , out double actualLength, out double actualWidth) { double palletLength = GetPalletLength(layer); double palletWidth = GetPalletWidth(layer); double radius = layer.CylinderRadius; double diameter = 2.0 * layer.CylinderRadius; // initialize out parameters firstRowLength = 0; secondRowLength = 0; rowNumber = 0; actualLength = 0.0; actualWidth = 0.0; // sanity check if (diameter > palletLength || diameter > palletWidth) return false; // first row number firstRowLength = (int)Math.Floor(palletLength / diameter); // second row if ((firstRowLength + 0.5) * diameter < palletLength) { secondRowLength = firstRowLength; actualLength = (firstRowLength + 0.5) * diameter; } else { secondRowLength = firstRowLength - 1; actualLength = firstRowLength * diameter; } // numbers of rows rowNumber = (int)Math.Floor(1 + (palletWidth / radius - 2.0) / Math.Sqrt(3.0)); actualWidth = (2.0 + (rowNumber - 1) * Math.Sqrt(3.0)) * radius; return true; }
public override void GetLayerDimensions(LayerCyl layer, out double actualLength, out double actualWidth) { int firstRowLength = 0; int secondRowLength = 0; int rowNumber = 0; ComputeRowNumberAndLength(layer , out firstRowLength, out secondRowLength, out rowNumber , out actualLength, out actualWidth); }
public override void GetLayerDimensions(LayerCyl layer, out double actualLength, out double actualWidth) { double palletLength = layer.PalletLength; double palletWidth = layer.PalletWidth; double radius = layer.CylinderRadius; actualLength = 0.0; actualWidth = 0.0; }
public override void GetLayerDimensions(LayerCyl layer, out double actualLength, out double actualWidth) { double palletLength = GetPalletLength(layer); double palletWidth = GetPalletWidth(layer); double diameter = 2.0 * layer.CylinderRadius; actualLength = Math.Floor(palletLength / diameter) * diameter; ; actualWidth = Math.Floor(palletWidth / diameter) * diameter; }
private bool ComputeRowNumberAndLength(LayerCyl layer , out int alignedRowLength, out int rowNumber1 , out int stagRowLength, out int rowNumber2 , out double actualLength, out double actualWidth) { double palletLength = GetPalletLength(layer); double palletWidth = GetPalletWidth(layer); double radius = layer.CylinderRadius; double diameter = 2.0 * layer.CylinderRadius; // initialize out parameters alignedRowLength = 0; rowNumber1 = 0; stagRowLength = 0; rowNumber2 = 0; actualLength = 0; actualWidth = 0; // sanity check if (diameter > palletLength || diameter > palletWidth) return false; // first row number alignedRowLength = (int)Math.Floor(palletLength / diameter); // second row if ((alignedRowLength + 0.5) * diameter < palletLength) { stagRowLength = alignedRowLength; actualLength = (stagRowLength + 0.5) * diameter; } else { stagRowLength = alignedRowLength - 1; actualLength = stagRowLength * diameter; } actualLength = Math.Max(actualLength, alignedRowLength * diameter); // numbers of rows int rowNumber1Max = (int)Math.Floor(palletWidth / diameter); // optimization int maxCount = 0; for (int i = 1; i < rowNumber1Max - 1; ++i) { int rowNumber1Temp = i; int rowNumber2Temp = (int)Math.Floor(((palletWidth / radius) - 2.0 * rowNumber1Temp) / Math.Sqrt(3.0)); int count = alignedRowLength * rowNumber1Temp + (rowNumber2Temp / 2 + (rowNumber2Temp % 2 == 0 ? 0 : 1)) * stagRowLength + (rowNumber2Temp / 2) * alignedRowLength; if (count >= maxCount) { rowNumber1 = rowNumber1Temp; rowNumber2 = rowNumber2Temp; } } actualWidth = diameter + (rowNumber1 - 1) * diameter + radius * Math.Sqrt(3.0) * rowNumber2; return true; }
public override void GetLayerDimensions(LayerCyl layer, out double actualLength, out double actualWidth) { double palletLength = layer.PalletLength; double palletWidth = layer.PalletWidth; double radius = layer.CylinderRadius; int alignedRowLength = 0, stagRowLength = 0; int rowNumber1 = 0, rowNumber2 = 0; ComputeRowNumberAndLength(layer , out alignedRowLength, out rowNumber1 , out stagRowLength, out rowNumber2 , out actualLength, out actualWidth); }
public override void GenerateLayer(LayerCyl layer, double actualLength, double actualWidth) { layer.Clear(); int firstRowLength = 0; int secondRowLength = 0; int rowNumber = 0; if (!ComputeRowNumberAndLength(layer , out firstRowLength, out secondRowLength, out rowNumber , out actualLength, out actualWidth)) return; double palletLength = GetPalletLength(layer); double palletWidth = GetPalletWidth(layer); double radius = layer.CylinderRadius; double offsetX = 0.5 * (palletLength - actualLength); double offsetY = 0.5 * (palletWidth - actualWidth); for (int i = 0; i < rowNumber; ++i) { double y = (offsetY + radius) + i * radius * Math.Sqrt(3.0); for (int j = 0; j < (i % 2 == 0 ? firstRowLength : secondRowLength); ++j) AddPosition(layer, new Vector2D(offsetX + ((i % 2 == 0) ? 0.0 : radius) + j * 2.0 * radius + radius, y)); } }
public abstract void GetLayerDimensions(LayerCyl layer, out double length, out double width);
public abstract void GenerateLayer(LayerCyl layer, double actualLength, double actualWidth);
public override void GenerateLayer(LayerCyl layer, double actualLength, double actualWidth) { layer.Clear(); throw new NotImplementedException(); }
private List<CylinderPalletSolution> GenerateSolutions() { List<CylinderPalletSolution> solutions = new List<CylinderPalletSolution>(); // loop through all patterns foreach (CylinderLayerPattern pattern in _patterns) { for (int iDir = 0; iDir < (pattern.CanBeSwapped ? 2 : 1); ++iDir) { // alternate pallet direction LayerCyl layer = new LayerCyl(_cylProperties, _palletProperties, _constraintSet); string title = string.Format("{0}-{1}", pattern.Name, iDir); CylinderPalletSolution sol = new CylinderPalletSolution(null, title, true); double actualLength = 0.0, actualWidth = 0.0; pattern.Swapped = (iDir % 2 != 0); pattern.GetLayerDimensions(layer, out actualLength, out actualWidth); try { pattern.GenerateLayer(layer, actualLength, actualWidth); } catch (NotImplementedException ex) { _log.Debug(ex.Message); continue; } catch (Exception ex) { _log.Error(ex.Message); continue; } // stop double zLayer = _palletProperties.Height; bool maxWeightReached = _constraintSet.UseMaximumPalletWeight && (_palletProperties.Weight + _cylProperties.Weight > _constraintSet.MaximumPalletWeight); bool maxHeightReached = _constraintSet.UseMaximumPalletHeight && (zLayer + _cylProperties.Height > _constraintSet.MaximumPalletHeight); bool maxNumberReached = false; int iCount = 0; // insert anti-slip interlayer if (_constraintSet.HasInterlayerAntiSlip) { sol.CreateNewInterlayer(zLayer, 1); zLayer += _interlayerPropertiesAntiSlip.Thickness; } while (!maxWeightReached && !maxHeightReached && !maxNumberReached) { // interlayer if (_constraintSet.HasInterlayer && (sol.Count > 0)) { sol.CreateNewInterlayer(zLayer, 0); zLayer += _interlayerProperties.Thickness; } // select current layer type CylinderLayer cylLayer = sol.CreateNewLayer(zLayer); foreach (Vector2D layerPos in layer) { ++iCount; maxWeightReached = _constraintSet.UseMaximumPalletWeight && ((iCount * _cylProperties.Weight + _palletProperties.Weight) > _constraintSet.MaximumPalletWeight); maxNumberReached = _constraintSet.UseMaximumNumberOfItems && (iCount > _constraintSet.MaximumNumberOfItems); if (!maxWeightReached && !maxNumberReached) cylLayer.Add( new Vector3D( layerPos.X - 0.5 * _constraintSet.OverhangX, layerPos.Y - 0.5 * _constraintSet.OverhangY, zLayer)); } // increment zLayer zLayer += _cylProperties.Height; maxHeightReached = _constraintSet.UseMaximumPalletHeight && (zLayer + _cylProperties.Height > _constraintSet.MaximumPalletHeight); } // limit reached if (maxWeightReached) sol.LimitReached = Limit.LIMIT_MAXWEIGHTREACHED; else if (maxNumberReached) sol.LimitReached = Limit.LIMIT_MAXNUMBERREACHED; else if (maxHeightReached) sol.LimitReached = Limit.LIMIT_MAXHEIGHTREACHED; else sol.LimitReached = Limit.LIMIT_UNKNOWN; solutions.Add(sol); } } // sort solutions solutions.Sort(); return solutions; }