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();
 }
Beispiel #15
0
        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;
        }