Exemple #1
0
        private bool ComputeRowNumberAndLength(Layer2DCylImp 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.Radius;
            double diameter     = 2.0 * layer.Radius;

            // 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);
        }
Exemple #2
0
        public ILayer2D BuildLayer(Packable packable, Vector2D dimContainer, LayerDesc layerDesc, Vector2D actualDimensions, double minSpace)
        {
            ILayer2D     layer   = null;
            LayerPattern pattern = null;

            if (packable.IsBrick)
            {
                LayerDescBox layerDescBox = layerDesc as LayerDescBox;
                // instantiate layer
                layer = new Layer2DBrickImp(packable.OuterDimensions, dimContainer, layerDescBox.PatternName, layerDescBox.AxisOrtho, layerDesc.Swapped)
                {
                    ForcedSpace = minSpace
                };
                // get layer pattern
                pattern = LayerPatternBox.GetByName(layerDesc.PatternName);
            }
            else if (packable.IsCylinder)
            {
                var cylProperties = packable as RevSolidProperties;
                layer = new Layer2DCylImp(cylProperties.RadiusOuter, cylProperties.Height, dimContainer, layerDesc.Swapped);
                // get layer pattern
                pattern = LayerPatternCyl.GetByName(layerDesc.PatternName);
            }
            else
            {
                throw new EngineException(string.Format("Unexpected packable {0} (Type = {1})", packable.Name, packable.GetType().ToString()));
            }

            pattern.GenerateLayer(
                layer
                , layer.Swapped ? actualDimensions.Y : actualDimensions.X
                , layer.Swapped ? actualDimensions.X : actualDimensions.Y
                );
            return(layer);
        }
Exemple #3
0
        public override void GenerateLayer(ILayer2D layer, double actualLength, double actualWidth)
        {
            layer.Clear();
            double palletLength = GetPalletLength(layer);
            double palletWidth  = GetPalletWidth(layer);
            double radius       = GetRadius(layer);

            Layer2DCylImp layerCyl = layer as Layer2DCylImp;

            if (!ComputeRowNumberAndLength(layerCyl
                                           , out int firstRowLength, out int secondRowLength, out int rowNumber
                                           , out actualLength, out actualWidth))
            {
                return;
            }

            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));
                }
            }
        }
Exemple #4
0
        public override bool GetLayerDimensions(ILayer2D layer, out double actualLength, out double actualWidth)
        {
            Layer2DCylImp layerCyl = layer as Layer2DCylImp;

            ComputeRowNumberAndLength(layerCyl
                                      , out int firstRowLength, out int secondRowLength, out int rowNumber
                                      , out actualLength, out actualWidth);
            return((firstRowLength > 0) && (secondRowLength > 0) && (rowNumber > 0));
        }
        public void Draw(Graphics2D graphics, Packable packable, double height, bool selected, bool annotate)
        {
            graphics.NumberOfViews = 1;
            graphics.Clear(selected ? Color.LightBlue : Color.White);
            graphics.SetViewport(0.0f, 0.0f, (float)_layer.Length, (float)_layer.Width);
            graphics.SetCurrentView(0);
            graphics.DrawRectangle(Vector2D.Zero, new Vector2D(_layer.Length, _layer.Width), Color.Black);

            // draw layer (brick)
            if (_layer is Layer2DBrick layer2D)
            {
                uint pickId = 0;
                foreach (var bPosition in layer2D.Positions)
                {
                    Box b = null;
                    if (packable is PackProperties)
                    {
                        b = new Pack(pickId++, packable as PackProperties, bPosition);
                    }
                    else if (packable is PackableBrick)
                    {
                        b = new Box(pickId++, packable as PackableBrick, bPosition);
                    }
                    if (null != b)
                    {
                        b.Draw(graphics);
                    }
                }
            }
            // draw layer (cylinder)
            else if (_layer is Layer2DCylImp)
            {
                Layer2DCylImp layer2DCyl = _layer as Layer2DCylImp;
                uint          pickId     = 0;
                foreach (Vector2D pos in layer2DCyl)
                {
                    Cylinder c = new Cylinder(pickId++, packable as CylinderProperties, new CylPosition(new Vector3D(pos.X, pos.Y, 0.0), HalfAxis.HAxis.AXIS_Z_P));
                    graphics.DrawCylinder(c);
                }
            }
            // draw axes
            bool showAxis = false;

            if (showAxis)
            {
                // draw axis X
                graphics.DrawLine(Vector2D.Zero, new Vector2D(_layer.Length, 0.0), Color.Red);
                // draw axis Y
                graphics.DrawLine(Vector2D.Zero, new Vector2D(0.0, _layer.Width), Color.Green);
            }
            // annotate thumbnail
            if (annotate)
            {
                Annotate(graphics.Graphics, graphics.Size, height);
            }
        }
Exemple #6
0
        private bool ComputeRowNumberAndLength(Layer2DCylImp 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.Radius;
            double diameter     = 2.0 * layer.Radius;

            // 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);
        }
Exemple #7
0
        public List <Layer2DCylImp> BuildLayers(
            double radius, double height
            , Vector2D dimContainer
            , double offsetZ /* e.g. pallet height */
            , ConstraintSetAbstract constraintSet
            , bool keepOnlyBest)
        {
            var listLayers0 = new List <Layer2DCylImp>();

            foreach (LayerPatternCyl pattern in LayerPatternCyl.All)
            {
                // not swapped vs swapped pattern
                for (int iSwapped = 0; iSwapped < 2; ++iSwapped)
                {
                    // does swapping makes sense for this layer pattern ?
                    if (!pattern.CanBeSwapped && (iSwapped == 1))
                    {
                        continue;
                    }
                    // instantiate layer
                    var layer = new Layer2DCylImp(radius, height, dimContainer, iSwapped == 1);
                    layer.PatternName = pattern.Name;

                    double actualLength = 0.0, actualWidth = 0.0;
                    if (!pattern.GetLayerDimensions(layer, out actualLength, out actualWidth))
                    {
                        continue;
                    }
                    pattern.GenerateLayer(layer, actualLength, actualWidth);
                    listLayers0.Add(layer);
                }

                // keep only best layers
                if (keepOnlyBest)
                {
                    // 1. get best count
                    int bestCount = 0;
                    foreach (Layer2DCylImp layer in listLayers0)
                    {
                        bestCount = Math.Max(layer.CountInHeight(constraintSet.OptMaxHeight.Value - offsetZ), bestCount);
                    }

                    // 2. remove any layer that does not match the best count given its orientation
                    listLayers0.RemoveAll(layer =>
                                          !(layer.CountInHeight(constraintSet.OptMaxHeight.Value - offsetZ) >= bestCount));
                }
                listLayers0.Sort(new LayerCylComparerCount(constraintSet.OptMaxHeight.Value - offsetZ));
            }
            return(listLayers0);
        }
Exemple #8
0
        /// <summary>
        /// Used to compute load dimension
        /// </summary>
        public bool GetDimensions(List <LayerDesc> layers, Packable packable, Vector2D dimContainer, double minSpace, ref Vector2D actualDimensions)
        {
            foreach (LayerDesc layerDesc in layers)
            {
                // dimensions
                double actualLength = 0.0, actualWidth = 0.0;

                if (packable.IsBrick)
                {
                    LayerDescBox layerDescBox = layerDesc as LayerDescBox;
                    // instantiate layer
                    var layer = new Layer2DBrickImp(packable.OuterDimensions, dimContainer, layerDescBox.PatternName, layerDescBox.AxisOrtho, layerDesc.Swapped)
                    {
                        ForcedSpace = minSpace
                    };
                    // get layer pattern
                    LayerPatternBox pattern = LayerPatternBox.GetByName(layerDesc.PatternName);
                    // dimensions
                    if (!pattern.GetLayerDimensionsChecked(layer, out actualLength, out actualWidth))
                    {
                        _log.Error(string.Format("Failed to get layer dimension : {0}", pattern.Name));
                        break;
                    }
                }
                else if (packable.IsCylinder)
                {
                    var cylProp = packable as RevSolidProperties;
                    // instantiate layer
                    var layer = new Layer2DCylImp(cylProp.RadiusOuter, cylProp.Height, dimContainer, layerDesc.Swapped);
                    // get layer pattern
                    LayerPatternCyl pattern = LayerPatternCyl.GetByName(layerDesc.PatternName);
                    // dimensions
                    if (!pattern.GetLayerDimensions(layer, out actualLength, out actualWidth))
                    {
                        _log.Error(string.Format("Failed to get layer dimension : {0}", pattern.Name));
                        break;
                    }
                }
                else
                {
                    throw new EngineException(string.Format("Unexpected packable {0} (Type = {1})", packable.Name, packable.GetType().ToString()));
                }

                actualDimensions.X = Math.Max(actualDimensions.X, layerDesc.Swapped ? actualWidth : actualLength);
                actualDimensions.Y = Math.Max(actualDimensions.Y, layerDesc.Swapped ? actualLength : actualWidth);
            }
            return(true);
        }
Exemple #9
0
        public ILayer2D BuildLayer(Packable packable, Vector2D dimContainer, LayerDesc layerDesc, double minSpace)
        {
            ILayer2D layer = null;

            if (packable.IsBrick)
            {
                if (layerDesc is LayerDescBox layerDescBox)
                {
                    // layer instantiation
                    layer = new Layer2DBrickImp(packable.OuterDimensions, dimContainer, layerDesc.PatternName, layerDescBox.AxisOrtho, layerDesc.Swapped)
                    {
                        ForcedSpace = minSpace
                    };
                    // get layer pattern
                    LayerPatternBox pattern = LayerPatternBox.GetByName(layerDesc.PatternName);
                    // dimensions
                    if (!pattern.GetLayerDimensionsChecked(layer as Layer2DBrickImp, out double actualLength, out double actualWidth))
                    {
                        return(null);
                    }
                    pattern.GenerateLayer(
                        layer as Layer2DBrickImp
                        , actualLength
                        , actualWidth);
                }
                return(layer);
            }
            else if (packable.IsCylinder)
            {
                // casts
                var cylProperties = packable as RevSolidProperties;
                // layer instantiation
                layer = new Layer2DCylImp(cylProperties.RadiusOuter, cylProperties.Height, dimContainer, layerDesc.Swapped);
                // get layer pattern
                LayerPatternCyl pattern = LayerPatternCyl.GetByName(layerDesc.PatternName);
                if (!pattern.GetLayerDimensions(layer as Layer2DCylImp, out double actualLength, out double actualWidth))
                {
                    return(null);
                }
                pattern.GenerateLayer(layer as Layer2DCylImp, actualLength, actualWidth);
            }
            else
            {
                throw new EngineException(string.Format("Unexpected packable {0} (Type = {1})", packable.Name, packable.GetType().ToString()));
            }
            return(layer);
        }
Exemple #10
0
        public void Draw(Graphics3D graphics, Packable packable, double height, bool selected, bool annotate)
        {
            graphics.BackgroundColor = selected ? Color.LightBlue : Color.White;
            graphics.CameraPosition  = Graphics3D.Corner_0;

            // draw layer (brick)
            if (_layer is Layer2DBrick layer2D)
            {
                uint pickId = 0;
                foreach (var bPosition in layer2D.Positions)
                {
                    if (packable is PackProperties)
                    {
                        graphics.AddBox(new Pack(pickId++, packable as PackProperties, bPosition));
                    }
                    else if (packable is PackableBrick)
                    {
                        graphics.AddBox(new Box(pickId++, packable as PackableBrick, bPosition));
                    }
                }
            }
            // draw layer (cylinder)
            else if (_layer is Layer2DCylImp)
            {
                Layer2DCylImp layer2DCyl = _layer as Layer2DCylImp;
                uint          pickId     = 0;
                foreach (Vector2D pos in layer2DCyl)
                {
                    Cyl cyl = null;
                    if (packable is CylinderProperties cylProperties)
                    {
                        cyl = new Cylinder(pickId++, cylProperties, new CylPosition(new Vector3D(pos.X, pos.Y, 0.0), HalfAxis.HAxis.AXIS_Z_P));
                    }
                    else if (packable is BottleProperties bottleProperties)
                    {
                        cyl = new Bottle(pickId++, bottleProperties, new CylPosition(new Vector3D(pos.X, pos.Y, 0.0), HalfAxis.HAxis.AXIS_Z_P));
                    }
                    graphics.AddCylinder(cyl);
                }
            }
            graphics.Flush();
            // annotate thumbnail
            if (annotate)
            {
                Annotate(graphics.Graphics, graphics.Size, height);
            }
        }
Exemple #11
0
        public override bool GetLayerDimensions(ILayer2D layer, out double actualLength, out double actualWidth)
        {
            double palletLength = layer.Length;
            double palletWidth  = layer.Width;

            Layer2DCylImp layerCyl = layer as Layer2DCylImp;
            double        radius   = layerCyl.Radius;

            int alignedRowLength = 0, stagRowLength = 0;
            int rowNumber1 = 0, rowNumber2 = 0;

            ComputeRowNumberAndLength(layerCyl
                                      , out alignedRowLength, out rowNumber1
                                      , out stagRowLength, out rowNumber2
                                      , out actualLength, out actualWidth);

            return(rowNumber1 > 0 && rowNumber2 > 0);
        }
Exemple #12
0
        public override void GenerateLayer(ILayer2D layer, double actualLength, double actualWidth)
        {
            layer.Clear();
            double palletLength = GetPalletLength(layer);
            double palletWidth  = GetPalletWidth(layer);
            double radius       = GetRadius(layer);
            double diameter     = 2.0 * radius;

            int           alignedRowLength = 0, stagRowLength = 0;
            int           rowNumber1 = 0, rowNumber2 = 0;
            Layer2DCylImp layerCyl = layer as Layer2DCylImp;

            ComputeRowNumberAndLength(layerCyl
                                      , 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(layerCyl, 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));
                }
            }
        }
Exemple #13
0
        public List <ILayer2D> BuildLayers(
            Packable packable, Vector2D dimContainer,
            double offsetZ, /* e.g. pallet height */
            ConstraintSetAbstract constraintSet, bool keepOnlyBest)
        {
            var listLayers0 = new List <ILayer2D>();

            if (packable is PackableBrick packableBrick)
            {
                // loop through all patterns
                foreach (LayerPatternBox pattern in LayerPatternBox.All)
                {
                    // loop through all orientation
                    HalfAxis.HAxis[] patternAxes = pattern.IsSymetric ? HalfAxis.Positives : HalfAxis.All;
                    foreach (HalfAxis.HAxis axisOrtho in patternAxes)
                    {
                        // is orientation allowed
                        if (!constraintSet.AllowOrientation(Layer2DBrickImp.VerticalAxis(axisOrtho)))
                        {
                            continue;
                        }
                        // not swapped vs swapped pattern
                        for (int iSwapped = 0; iSwapped < 2; ++iSwapped)
                        {
                            try
                            {
                                // does swapping makes sense for this layer pattern ?
                                if (!pattern.CanBeSwapped && (iSwapped == 1))
                                {
                                    continue;
                                }
                                // instantiate layer
                                var layer = new Layer2DBrickImp(packableBrick.OuterDimensions, dimContainer, pattern.Name, axisOrtho, iSwapped == 1)
                                {
                                    ForcedSpace = constraintSet.MinimumSpace.Value
                                };
                                if (layer.NoLayers(constraintSet.OptMaxHeight.Value) < 1)
                                {
                                    continue;
                                }
                                if (!pattern.GetLayerDimensionsChecked(layer, out double actualLength, out double actualWidth))
                                {
                                    continue;
                                }
                                pattern.GenerateLayer(layer, actualLength, actualWidth);
                                if (0 == layer.Count)
                                {
                                    continue;
                                }
                                listLayers0.Add(layer);
                            }
                            catch (Exception ex)
                            {
                                _log.ErrorFormat("Pattern: {0} Orient: {1} Swapped: {2} Message: {3}"
                                                 , pattern.Name
                                                 , axisOrtho.ToString()
                                                 , iSwapped == 1 ? "True" : "False"
                                                 , ex.Message);
                            }
                        }
                    }
                }
            }
            else if (packable is CylinderProperties cylinder)
            {
                // loop through all patterns
                foreach (LayerPatternCyl pattern in LayerPatternCyl.All)
                {
                    // not swapped vs swapped pattern
                    for (int iSwapped = 0; iSwapped < 2; ++iSwapped)
                    {
                        try
                        {
                            var layer = new Layer2DCylImp(cylinder.RadiusOuter, cylinder.Height, dimContainer, iSwapped == 1)
                            {
                                PatternName = pattern.Name
                            };
                            if (!pattern.GetLayerDimensions(layer as Layer2DCylImp, out double actualLength, out double actualWidth))
                            {
                                continue;
                            }
                            pattern.GenerateLayer(layer as Layer2DCylImp, actualLength, actualWidth);
                            if (0 == layer.Count)
                            {
                                continue;
                            }
                            listLayers0.Add(layer);
                        }
                        catch (Exception ex)
                        {
                            _log.ErrorFormat("Pattern: {0} Swapped: {1} Message: {2}"
                                             , pattern.Name
                                             , iSwapped == 1 ? "True" : "False"
                                             , ex.Message);
                        }
                    }
                }
            }
            // keep only best layers
            if (keepOnlyBest)
            {
                // 1. get best count
                int bestCount = 0;
                foreach (ILayer2D layer in listLayers0)
                {
                    bestCount = Math.Max(layer.CountInHeight(constraintSet.OptMaxHeight.Value - offsetZ), bestCount);
                }

                // 2. remove any layer that does not match the best count given its orientation
                var listLayers1 = new List <ILayer2D>();
                foreach (ILayer2D layer in listLayers0)
                {
                    if (layer.CountInHeight(constraintSet.OptMaxHeight.Value - offsetZ) >= bestCount)
                    {
                        listLayers1.Add(layer);
                    }
                }
                // 3. copy back in original list
                listLayers0.Clear();
                listLayers0.AddRange(listLayers1);
            }
            if (constraintSet.OptMaxHeight.Activated)
            {
                listLayers0.Sort(new LayerComparerCount(constraintSet, offsetZ));
            }

            return(listLayers0);
        }
Exemple #14
0
        public override void GenerateLayer(ILayer2D layer, double actualLength, double actualWidth)
        {
            layer.Clear();
            double length   = GetPalletLength(layer);
            double width    = GetPalletWidth(layer);
            double diameter = GetDiameter(layer);
            double radius   = 0.5 * diameter;

            Layer2DCylImp layerCyl = layer as Layer2DCylImp;

            if (!ComputeRowNumberAndLength(layerCyl
                                           , out int number
                                           , out int firstRowLength, out int secondRowLength, out int rowNumber
                                           , out actualLength, out actualWidth))
            {
                return;
            }

            double offsetX = 0.0; //0.5 * (length - actualLength);
            double offsetY = 0.5 * (width - actualWidth);

            if (length < diameter || width < diameter)
            {
            }
            else if (width < 2 * diameter)
            {
                double Y     = width - diameter;
                double X     = diameter * Math.Cos(Math.Asin(Y / diameter));
                double stepX = X;
                if (X <= 0.5 * diameter)
                {
                    stepX = diameter;
                }
                else
                {
                    stepX = 2 * X;
                }
                double   xpos = 0.5 * diameter, ypos = width - 0.5 * diameter;
                Vector2D pLast = Vector2D.Zero;
                while (offsetX + xpos < length - 0.5 * diameter)
                {
                    Vector2D p0 = new Vector2D(offsetX + xpos, offsetY + ypos);
                    Vector2D p1 = new Vector2D(offsetX + xpos + X, offsetY + 0.5 * diameter);

                    AddPosition(layer, p0);
                    if (p1.X < length - 0.5 * diameter)
                    {
                        AddPosition(layer, p1);
                    }
                    pLast = 0.5 * (p0 + p1) + 0.5 * Math.Sqrt(3) * new Vector2D(Y, X);
                    xpos += stepX;
                }

                if (pLast.X <= length - 0.5 * diameter && pLast.Y < width - 0.5 * diameter)
                {
                    AddPosition(layer, pLast);
                }
            }
            else if (width < 3 * diameter)
            {
                double Y     = width - 2 * diameter;
                double X     = 0.0;
                double ydiff = 0.0;
                if (Y >= diameter / 2)
                {
                    Y     = (width - diameter) / 3;
                    X     = diameter * Math.Cos(Math.Asin(Y / diameter));
                    ydiff = -2.0 * Y;
                }
                else
                {
                    Y     = width - 2 * diameter;
                    X     = diameter * Math.Cos(Math.Asin(Y / diameter));
                    ydiff = -diameter;
                }

                // initialize positions
                double   xpos = 0.5 * diameter, ypos = 0.0;
                int      index = 0;
                Vector2D pLast = Vector2D.Zero;
                // add positions until end is reached
                while (xpos < length - 0.5 * diameter)
                {
                    ypos = width - 0.5 * diameter - ((index % 2 == 1) ? Y : 0.0);

                    AddPosition(layer, new Vector2D(offsetX + xpos, offsetY + ypos));
                    AddPosition(layer, new Vector2D(offsetX + xpos, offsetY + ypos + ydiff));

                    pLast = new Vector2D(offsetX + xpos + 0.5 * Math.Sqrt(3.0) * diameter, offsetY + ypos + 0.5 * ydiff);

                    xpos += X;
                    ++index;
                }
                if (pLast.X <= length - 0.5 * diameter)
                {
                    AddPosition(layer, pLast);
                }
            }
            else
            {
                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));
                    }
                }
            }
        }
Exemple #15
0
        private bool ComputeRowNumberAndLength(Layer2DCylImp layer
                                               , out int number
                                               , out int firstRowLength, out int secondRowLength, out int rowNumber
                                               , out double actualLength, out double actualWidth)
        {
            double length   = GetPalletLength(layer);
            double width    = GetPalletWidth(layer);
            double diameter = GetDiameter(layer);

            number         = 0; rowNumber = 0;
            firstRowLength = 0; secondRowLength = 0;
            actualLength   = 0.0; actualWidth = 0.0;

            // sanity check
            if (length < diameter || width < diameter)
            {
                number         = 0; rowNumber = 0;
                firstRowLength = 0; secondRowLength = 0;
                actualLength   = 0.0; actualWidth = 0.0;
                return(false);
            }
            else if (width < 2 * diameter)
            {
                double Y = width - diameter;
                double X = diameter * Math.Cos(Math.Asin(Y / diameter));

                if (X <= diameter / 2.0)
                {
                    int noCols = (int)(Math.Floor((length - diameter - X)) / diameter) + 1;
                    number = 2 * (int)(Math.Floor((length - diameter - X)) / diameter) + 2;
                    bool lastRoll = length - 0.5 * diameter * number - diameter * Math.Cos((Math.PI / 6.0) - Math.Asin(width - diameter / diameter)) > 0.0;
                    number      += lastRoll ? 1 : 0;
                    actualLength = noCols * diameter + X + (lastRoll ? diameter * Math.Cos((Math.PI / 6.0) + Math.Atan(X / Y)) : 0.0);

                    firstRowLength = secondRowLength = noCols;
                }
                else
                {
                    number       = (int)Math.Floor((length - diameter) / X) + 1;
                    actualLength = (number - 1) * X + diameter;

                    firstRowLength  = number / 2;
                    secondRowLength = number / 2 + number % 2;
                }
                actualWidth = width;
                rowNumber   = 2;
            }
            else if (width < 3.0 * diameter)
            {
                double Y = width - 2.0 * diameter;
                if (Y >= diameter / 2.0)
                {
                    Y = (width - diameter) / 3.0;
                    double X = diameter * Math.Cos(Math.Asin(Y / diameter));
                    number       = 2 * (int)Math.Floor(length / X);
                    actualLength = ((number / 2) - 1) * X + diameter;

                    firstRowLength  = number / 4;
                    secondRowLength = number / 4 + (number / 2) % 2;
                }
                else
                {
                    Y = width - 2.0 * diameter;
                    double X      = diameter * Math.Cos(Math.Asin(Y / diameter));
                    int    noCols = (int)Math.Floor(length / X);
                    number = 2 * (int)Math.Floor(length / X);
                    bool lastRoll = length - (X * number / 2.0) - diameter * Math.Cos(Math.PI / 6.0) > 0;
                    number      += lastRoll ? 1 : 0;
                    actualLength = (noCols - 1) * X + diameter * (1.0 + Math.Asin(Math.PI / 6.0));

                    firstRowLength  = noCols;
                    secondRowLength = noCols + number % 2;
                }
                rowNumber   = 4;
                actualWidth = width;
            }
            else
            {
                // first row number
                firstRowLength = (int)Math.Floor(length / diameter);
                // second row
                if ((firstRowLength + 0.5) * diameter < length)
                {
                    secondRowLength = firstRowLength;
                    actualLength    = (firstRowLength + 0.5) * diameter;
                }
                else
                {
                    secondRowLength = firstRowLength - 1;
                    actualLength    = firstRowLength * diameter;
                }
                // numbers of rows
                rowNumber   = (int)Math.Floor(1 + (2.0 * width / diameter - 2.0) / Math.Sqrt(3.0));
                actualWidth = (2.0 + (rowNumber - 1) * Math.Sqrt(3.0)) * 0.5 * diameter;
            }
            return(true);
        }