예제 #1
0
        public static bool ComputePositionDefault(IEntityContainer factory, Box2D boxBorder, Vector2D spaceBetween, ref List <BPosition> lPos, ref Box2D bbox)
        {
            if (boxBorder.Width <= 0.0 || boxBorder.Height <= 0.0)
            {
                return(false);
            }

            ImpositionTool tool = Instantiate(factory, new ImpositionSettings(boxBorder.Width, boxBorder.Height));

            tool.SpaceBetween = spaceBetween;
            tool.AllowOrthogonalImposition = true;
            tool.AllowBothDirection        = false;
            tool.HorizontalAlignment       = ImpositionSettings.HAlignment.HALIGN_LEFT;
            tool.VerticalAlignment         = ImpositionSettings.VAlignment.VALIGN_BOTTOM;
            tool.GenerateSortedSolutionList(null, out List <ImpositionSolution> solutions);
            if (solutions.Count > 0)
            {
                ImpositionSolution impSol       = solutions[0];
                Vector2D           cardboardPos = impSol.CardboardPosition;
                foreach (var p in impSol.Positions)
                {
                    BPosition pos = p;
                    pos.Pt += boxBorder.PtMin - cardboardPos;
                    lPos.Add(pos);
                }
                Vector2D ptMin = impSol.Bbox.PtMin + boxBorder.PtMin;
                Vector2D ptMax = impSol.Bbox.PtMax + boxBorder.PtMin;
                bbox = new Box2D(ptMin, ptMax);
            }
            return(lPos.Count > 0);
        }
        public void Translate(Vector2D vecTranslate)
        {
            List <BPosition> tempPositions = new List <BPosition>();

            foreach (BPosition position in _positions)
            {
                BPosition posTemp = position;
                posTemp._pt += vecTranslate;
                tempPositions.Add(posTemp);
            }
            _positions = tempPositions;
        }
예제 #3
0
        private void Translate(Vector2D vecTranslate)
        {
            List <BPosition> tempPositions = new List <BPosition>();

            foreach (BPosition position in Positions)
            {
                BPosition posTemp = position;
                posTemp.Pt += vecTranslate;
                tempPositions.Add(posTemp);
            }
            Positions = tempPositions;
        }
        public void CreateEntities(PicFactory factory)
        {
            // sanity check
            if (_positions.Count == 0)
            {
                return; // solution has no position -> exit
            }
            // get first position
            BPosition pos0 = _positions[0];
            // block
            PicBlock block = factory.AddBlock(_container, pos0.Transformation);

            // blockrefs
            for (int i = 1; i < _positions.Count; ++i) // do not insert first position as the block is now displayed
            {
                BPosition pos = _positions[i];
                factory.AddBlockRef(block, pos.Transformation * pos0.Transformation.Inverse());
            }
        }
        public override void GeneratePattern(IEntityContainer container, Vector2D minDistance, Vector2D impositionOffset, bool ortho)
        {
            using (PicFactory factory = new PicFactory())
            {
                // instantiate block and BlockRef
                PicBlock    block      = factory.AddBlock(container);
                PicBlockRef blockRef00 = factory.AddBlockRef(block, new Vector2D(0.0, 0.0), ortho ? 90.0 : 0.0);

                // compute bounding box
                PicVisitorBoundingBox visitor = new PicVisitorBoundingBox();
                visitor.TakePicBlocksIntoAccount = false;
                factory.ProcessVisitor(visitor, !PicFilter.FilterCotation);
                Box2D boxEntities = visitor.Box;

                // compute default X step
                PicBlockRef blockRef01         = factory.AddBlockRef(block, new Vector2D(5.0 * boxEntities.Width + minDistance.X, 0.0), ortho ? 90.0 : 0.0);
                double      horizontalDistance = 0.0;
                if (!PicBlockRef.Distance(blockRef00, blockRef01, PicBlockRef.DistDirection.HORIZONTAL_RIGHT, out horizontalDistance))
                {
                    throw new Exception("Failed to compute distance between to block refs");
                }
                _patternStep.X = 5.0 * boxEntities.Width - horizontalDistance + 2.0 * minDistance.X;

                // compute default Y step
                PicBlockRef blockRef10       = factory.AddBlockRef(block, new Vector2D(0.0, 5.0 * boxEntities.Height + minDistance.Y), ortho ? 90.0 : 0.0);
                double      verticalDistance = 0.0;
                if (!PicBlockRef.Distance(blockRef00, blockRef10, PicBlockRef.DistDirection.VERTICAL_TOP, out verticalDistance))
                {
                    throw new Exception("Failed to compute distance between to block refs");
                }
                _patternStep.Y = 5.0 * boxEntities.Height - verticalDistance + 2.0 * minDistance.Y;

                // positions
                _relativePositions = new BPosition[1, 1];
                BPosition position = new BPosition(Vector2D.Zero, ortho ? 90.0 : 0.0);
                _relativePositions[0, 0] = position;

                // bboxes
                _bboxes       = new Box2D[1, 1];
                _bboxes[0, 0] = blockRef00.Box;//boxEntities;
            }
        }
 public void Add(BPosition pos)
 {
     _positions.Add(pos);
 }
        public override void GeneratePattern(IEntityContainer container, Vector2D minDistance, Vector2D impositionOffset, bool ortho)
        {
            using (PicFactory factory = new PicFactory())
            {
                // 20 21
                // 10 11 12
                // 00 01 02
                //

                // instantiate block and BlockRef
                PicBlock    block      = factory.AddBlock(container);
                PicBlockRef blockRef00 = factory.AddBlockRef(block, new Vector2D(0.0, 0.0), ortho ? 90.0 : 0.0);

                // compute bounding box
                PicVisitorBoundingBox visitor = new PicVisitorBoundingBox();
                visitor.TakePicBlocksIntoAccount = false;
                factory.ProcessVisitor(visitor, new PicFilter());
                Box2D boxEntities = visitor.Box;

                // compute second entity position
                PicBlockRef blockRef10 = factory.AddBlockRef(block
                                                             , new Vector2D(
                                                                 boxEntities.XMin + boxEntities.XMax + (ortho ? 0.0 : 1.0) * impositionOffset.X
                                                                 , boxEntities.YMin + boxEntities.YMax + 5.0 * boxEntities.Height + minDistance.Y + (ortho ? 1.0 : 0.0) * impositionOffset.Y
                                                                 ), ortho ? 270.0 : 180.0);
                double verticalDistance = 0.0;
                if (!PicBlockRef.Distance(blockRef00, blockRef10, PicBlockRef.DistDirection.VERTICAL_TOP, out verticalDistance))
                {
                    throw new Exception("Failed to compute distance between to block refs");
                }
                Vector2D vecPosition = new Vector2D(
                    boxEntities.XMin + boxEntities.XMax + (ortho ? 0.0 : 1.0) * impositionOffset.X
                    , boxEntities.YMin + boxEntities.YMax + 5.0 * boxEntities.Height + 2.0 * minDistance.Y - verticalDistance + (ortho ? 1.0 : 0.0) * impositionOffset.Y);
                blockRef10.Position = vecPosition;

                // positions
                _relativePositions       = new BPosition[2, 1];
                _relativePositions[0, 0] = new BPosition(Vector2D.Zero, ortho ? 90.0 : 0.0);
                _relativePositions[1, 0] = new BPosition(vecPosition, ortho ? 270.0 : 180.0);
                // bboxes
                _bboxes       = new Box2D[2, 1];
                _bboxes[0, 0] = blockRef00.Box;//boxEntities;
                _bboxes[1, 0] = blockRef10.Box;

                // compute X step (col1 / col0)
                // col0
                List <PicBlockRef> listCol0 = new List <PicBlockRef>();
                listCol0.Add(blockRef00);
                listCol0.Add(blockRef10);

                // col1
                PicBlockRef blockRef01 = factory.AddBlockRef(block
                                                             , new Vector2D(5.0 * boxEntities.Width + minDistance.X, 0.0)
                                                             , ortho ? 90.0 : 0.0);
                PicBlockRef blockRef11 = factory.AddBlockRef(block
                                                             , new Vector2D(5.0 * boxEntities.Width + minDistance.X + vecPosition.X, vecPosition.Y)
                                                             , ortho ? 270.0 : 180.0);
                List <PicBlockRef> listCol1 = new List <PicBlockRef>();
                listCol1.Add(blockRef01);
                listCol1.Add(blockRef11);
                double horizontalDistance = 0.0;
                if (!PicBlockRef.Distance(listCol0, listCol1, PicBlockRef.DistDirection.HORIZONTAL_RIGHT, out horizontalDistance))
                {
                    throw new Exception("Failed to compute distance between to block refs");
                }
                _patternStep.X      = 5.0 * boxEntities.Width - horizontalDistance + 2.0 * minDistance.X;
                blockRef01.Position = vecPosition;
                blockRef11.Position = new Vector2D(vecPosition.X + _patternStep.X, vecPosition.Y);

                // compute Y step (row2 / row1)
                // row1
                List <PicBlockRef> listRow1 = new List <PicBlockRef>();
                listRow1.Add(blockRef10);
                listRow1.Add(blockRef11);

                PicBlockRef blockRef20 = factory.AddBlockRef(block
                                                             , new Vector2D(0.0, 5.0 * (boxEntities.Height + minDistance.Y))
                                                             , ortho ? 90.0 : 0.0);
                PicBlockRef blockRef21 = factory.AddBlockRef(block
                                                             , new Vector2D(_patternStep.X, 5.0 * (boxEntities.Height + minDistance.Y))
                                                             , ortho ? 90.0 : 0.0);

                List <PicBlockRef> listRow2 = new List <PicBlockRef>();
                listRow2.Add(blockRef20);
                listRow2.Add(blockRef21);

                verticalDistance = 0.0;
                if (!PicBlockRef.Distance(listRow1, listRow2, PicBlockRef.DistDirection.VERTICAL_TOP, out verticalDistance))
                {
                    throw new Exception("Failed to compute distance between to block refs");
                }
                _patternStep.Y = 5.0 * boxEntities.Height - verticalDistance + 6.0 * minDistance.Y;
            }
        }
예제 #8
0
        internal override ImpositionSolution GenerateSolution(ImpositionPattern pattern)
        {
            // instantiate solution
            ImpositionSolution solution = new ImpositionSolution(InitialEntities, pattern.Name, pattern.RequiresRotationInRows, pattern.RequiresRotationInColumns);

            // noRows / noCols
            solution.Rows = NoRowsExpected;
            solution.Cols = NoColsExpected;

            // number of each row / col of the pattern
            int[,] rowNumber = new int[pattern.NoRows, pattern.NoCols];
            int[,] colNumber = new int[pattern.NoRows, pattern.NoCols];

            int iCount = 0;

            for (int i = 0; i < pattern.NoRows; ++i)
            {
                for (int j = 0; j < pattern.NoCols; ++j)
                {
                    colNumber[i, j] = NoRowsExpected / pattern.NoRows + (NoRowsExpected % pattern.NoRows) / (i + 1);
                    rowNumber[i, j] = NoColsExpected / pattern.NoCols + (NoColsExpected % pattern.NoCols) / (j + 1);

                    iCount += rowNumber[i, j] * colNumber[i, j];
                }
            }
            // verify count
            System.Diagnostics.Debug.Assert(iCount == NoRowsExpected * NoColsExpected);

            // compute offsets
            Box2D  boxGlobal = pattern.BBox;
            double xOffset   = _margin.X - boxGlobal.XMin;
            double yOffset   = _margin.Y - boxGlobal.YMin;

            _box = new Box2D();
            for (int i = 0; i < pattern.NoRows; ++i)
            {
                for (int j = 0; j < pattern.NoCols; ++j)
                {
                    Box2D localBox = pattern._bboxes[i, j];
                    for (int k = 0; k < rowNumber[i, j]; ++k)
                    {
                        for (int l = 0; l < colNumber[i, j]; ++l)
                        {
                            // insert Box position
                            BPosition pos = pattern._relativePositions[i, j];
                            pos._pt.X = xOffset + k * pattern.PatternStep.X + pos._pt.X;
                            pos._pt.Y = yOffset + l * pattern.PatternStep.Y + pos._pt.Y;
                            solution.Add(pos);
                            // extend bounding box
                            Vector2D vOffset = new Vector2D(xOffset + k * pattern.PatternStep.X, yOffset + l * pattern.PatternStep.Y);
                            _box.Extend(new Box2D(vOffset + localBox.PtMin, vOffset + localBox.PtMax));
                        }
                    }
                }
            }

            // compute actual margin
            solution.CardboardPosition   = new Vector2D(_margin.X, _margin.Y);
            solution.CardboardDimensions = new Vector2D(_box.XMax - _box.XMin + _margin.X + _minMargin.X, _box.YMax - _box.YMin + _margin.Y + _minMargin.Y);
            return(solution);
        }
        internal override ImpositionSolution GenerateSolution(ImpositionPattern pattern, bool orthoImp)
        {
            // instantiate solution
            ImpositionSolution solution = new ImpositionSolution(InitialEntities, pattern.Name, orthoImp, pattern.RequiresRotationInRows, pattern.RequiresRotationInColumns);

            // pattern box
            Box2D boxPattern = pattern.BBox;

            // compute max number of patterns
            int noPatternX = NoPatternX(pattern);
            int noPatternY = NoPatternY(pattern);

            int[,] rowNumber = new int[pattern.NoRows, pattern.NoCols];
            int[,] colNumber = new int[pattern.NoRows, pattern.NoCols];

            int iMax = -1, jMax = -1;

            for (int i = 0; i < pattern.NoRows; ++i)
            {
                for (int j = 0; j < pattern.NoCols; ++j)
                {
                    if (pattern._bboxes[i, j].XMax + noPatternX * pattern.PatternStep.X - boxPattern.XMin < UsableFormat.Width)
                    {
                        rowNumber[i, j] = noPatternX + 1;
                        iMax            = i;
                    }
                    else
                    {
                        rowNumber[i, j] = noPatternX;
                    }

                    if (pattern._bboxes[i, j].YMax + noPatternY * pattern.PatternStep.Y - boxPattern.YMin < UsableFormat.Height)
                    {
                        colNumber[i, j] = noPatternY + 1;
                        jMax            = j;
                    }
                    else
                    {
                        colNumber[i, j] = noPatternY;
                    }
                }
            }

            // compute actual margin
            Box2D boxGen = Box2D.Initial;

            for (int i = 0; i < pattern.NoRows; ++i)
            {
                for (int j = 0; j < pattern.NoCols; ++j)
                {
                    for (int k = 0; k < rowNumber[i, j]; ++k)
                    {
                        for (int l = 0; l < colNumber[i, j]; ++l)
                        {
                            Vector2D vPatternStep = new Vector2D(k * pattern.PatternStep.X, l * pattern.PatternStep.Y);
                            boxGen.Extend(pattern._bboxes[i, j].PtMin + vPatternStep);
                            boxGen.Extend(pattern._bboxes[i, j].PtMax + vPatternStep);
                        }
                    }
                }
            }
            if (!boxGen.IsValid)
            {
                return(solution);
            }

            #region Additional both direction
            // ****
            // get remaining space in length and width
            double remainingX = UsableFormat.Width - boxGen.Width - SpaceBetween.X;
            double remainingY = UsableFormat.Height - boxGen.Height - SpaceBetween.Y;

            // here compute additionnal poses on right
            Box2D            bboxRight = Box2D.Initial;
            List <BPosition> lPosRight = new List <BPosition>();
            if (AllowBothDirection)
            {
                Vector2D vLowerLeft = new Vector2D(boxGen.PtMax.X, boxGen.PtMin.Y);
                Vector2D vTopRight  = vLowerLeft + new Vector2D(remainingX, UsableFormat.Height);
                if (ComputePositionDefault(InitialEntities, new Box2D(vLowerLeft, vTopRight), SpaceBetween, ref lPosRight, ref bboxRight))
                {
                    boxGen.Extend(bboxRight);
                }
            }
            // here compute additionnal poses on top
            Box2D            bboxTop = Box2D.Initial;
            List <BPosition> lPosTop = new List <BPosition>();
            if (AllowBothDirection)
            {
                Vector2D vLowerLeft = new Vector2D(boxGen.PtMin.X, boxGen.PtMax.Y);
                Vector2D vTopRight  = vLowerLeft + new Vector2D(UsableFormat.Width, remainingY);

                if (ComputePositionDefault(InitialEntities, new Box2D(vLowerLeft, vTopRight), SpaceBetween, ref lPosTop, ref bboxTop))
                {
                    boxGen.Extend(bboxTop);
                }
            }
            // ****
            #endregion

            double xMargin = 0.0;
            switch (HorizontalAlignment)
            {
            case ImpositionSettings.HAlignment.HALIGN_LEFT: xMargin = UsableFormat.XMin; break;

            case ImpositionSettings.HAlignment.HALIGN_RIGHT: xMargin = FormatDimensions.X - Margin.X - boxGen.Width; break;

            case ImpositionSettings.HAlignment.HALIGN_CENTER: xMargin = (FormatDimensions.X - boxGen.Width) * 0.5; break;

            default: break;
            }

            double yMargin = 0.0;
            switch (VerticalAlignment)
            {
            case ImpositionSettings.VAlignment.VALIGN_BOTTOM: yMargin = UsableFormat.YMin; break;

            case ImpositionSettings.VAlignment.VALIGN_TOP: yMargin = FormatDimensions.Y - Margin.Y - boxGen.Height; break;

            case ImpositionSettings.VAlignment.VALIGN_CENTER: yMargin = (FormatDimensions.Y - boxGen.Height) * 0.5; break;

            default: break;
            }

            // compute offsets
            Vector2D vOffset = new Vector2D(xMargin - boxPattern.XMin, yMargin - boxPattern.YMin);

            for (int i = 0; i < pattern.NoRows; ++i)
            {
                for (int j = 0; j < pattern.NoCols; ++j)
                {
                    for (int k = 0; k < rowNumber[i, j]; ++k)
                    {
                        for (int l = 0; l < colNumber[i, j]; ++l)
                        {
                            BPosition pos = pattern._relativePositions[i, j];
                            pos.Pt = vOffset + new Vector2D(
                                k * pattern.PatternStep.X + pos.Pt.X
                                , l * pattern.PatternStep.Y + pos.Pt.Y);
                            solution.Add(pos);
                        }
                    }
                }
            }
            foreach (var p in lPosRight)
            {
                solution.Add(new BPosition(p.Pt + vOffset + SpaceBetween.X * Vector2D.XAxis, p.Angle));
            }
            foreach (var p in lPosTop)
            {
                solution.Add(new BPosition(p.Pt + vOffset + SpaceBetween.Y * Vector2D.YAxis, p.Angle));
            }
            // noRows / noCols
            solution.Rows = pattern.NoCols * noPatternX + iMax + 1;
            solution.Cols = pattern.NoRows * noPatternY + jMax + 1;
            // cardboard position
            solution.CardboardPosition   = Vector2D.Zero;
            solution.CardboardDimensions = FormatDimensions;
            return(solution);
        }
        internal override ImpositionSolution GenerateSolution(ImpositionPattern pattern)
        {
            // instantiate solution
            ImpositionSolution solution = new ImpositionSolution(InitialEntities, pattern.Name, pattern.RequiresRotationInRows, pattern.RequiresRotationInColumns);

            // pattern global box
            Box2D boxGlobal = pattern.BBox;

            // compute max number of patterns
            int noPatternX = NoPatternX(pattern);
            int noPatternY = NoPatternY(pattern);

            int[,] rowNumber = new int[pattern.NoRows, pattern.NoCols];
            int[,] colNumber = new int[pattern.NoRows, pattern.NoCols];

            int iMax = -1, jMax = -1;

            for (int i = 0; i < pattern.NoRows; ++i)
            {
                for (int j = 0; j < pattern.NoCols; ++j)
                {
                    if (pattern._bboxes[i, j].XMax + noPatternX * pattern.PatternStep.X - boxGlobal.XMin < UsableFormat.Width)
                    {
                        rowNumber[i, j] = noPatternX + 1;
                        iMax            = i;
                    }
                    else
                    {
                        rowNumber[i, j] = noPatternX;
                    }

                    if (pattern._bboxes[i, j].YMax + noPatternY * pattern.PatternStep.Y - boxGlobal.YMin < UsableFormat.Height)
                    {
                        colNumber[i, j] = noPatternY + 1;
                        jMax            = j;
                    }
                    else
                    {
                        colNumber[i, j] = noPatternY;
                    }
                }
            }
            // compute actual margin
            double xMax = double.MinValue;
            double yMax = double.MinValue;

            for (int i = 0; i < pattern.NoRows; ++i)
            {
                for (int j = 0; j < pattern.NoCols; ++j)
                {
                    xMax = Math.Max(xMax, pattern._bboxes[i, j].XMax + (rowNumber[i, j] - 1) * pattern.PatternStep.X);
                    yMax = Math.Max(yMax, pattern._bboxes[i, j].YMax + (colNumber[i, j] - 1) * pattern.PatternStep.Y);
                }
            }

            double xMargin = 0.0;

            switch (HorizontalAlignment)
            {
            case ImpositionTool.HAlignment.HALIGN_LEFT: xMargin = UsableFormat.XMin; break;

            case ImpositionTool.HAlignment.HALIGN_RIGHT: xMargin = CardboardFormat.Width - Margin.X - xMax + boxGlobal.XMin; break;

            case ImpositionTool.HAlignment.HALIGN_CENTER: xMargin = (CardboardFormat.Width - xMax + boxGlobal.XMin) * 0.5; break;

            default: break;
            }

            double yMargin = 0.0;

            switch (VerticalAlignment)
            {
            case ImpositionTool.VAlignment.VALIGN_BOTTOM: yMargin = UsableFormat.YMin; break;

            case ImpositionTool.VAlignment.VALIGN_TOP: yMargin = CardboardFormat.Height - Margin.Y - yMax + boxGlobal.YMin; break;

            case ImpositionTool.VAlignment.VALIGN_CENTER: yMargin = (CardboardFormat.Height - yMax + boxGlobal.YMin) * 0.5; break;

            default: break;
            }

            // compute offsets
            double xOffset = xMargin - boxGlobal.XMin;
            double yOffset = yMargin - boxGlobal.YMin;

            for (int i = 0; i < pattern.NoRows; ++i)
            {
                for (int j = 0; j < pattern.NoCols; ++j)
                {
                    for (int k = 0; k < rowNumber[i, j]; ++k)
                    {
                        for (int l = 0; l < colNumber[i, j]; ++l)
                        {
                            BPosition pos = pattern._relativePositions[i, j];
                            pos._pt.X = xOffset + k * pattern.PatternStep.X + pos._pt.X;
                            pos._pt.Y = yOffset + l * pattern.PatternStep.Y + pos._pt.Y;
                            solution.Add(pos);
                        }
                    }
                }
            }
            // noRows / noCols
            solution.Rows = pattern.NoCols * noPatternX + iMax + 1;
            solution.Cols = pattern.NoRows * noPatternY + jMax + 1;
            // cardboard position
            solution.CardboardPosition   = new Vector2D(xMargin, yMargin);
            solution.CardboardDimensions = _cardboardFormat.Dimensions;
            return(solution);
        }
예제 #11
0
        public override void GeneratePattern(IEntityContainer container, Vector2D minDistance, Vector2D impositionOffset, bool ortho)
        {
            //
            // 10 11 12
            // 00 01 02
            //
            using (PicFactory factory = new PicFactory())
            {
                // instantiate block and BlockRef
                PicBlock    block      = factory.AddBlock(container);
                PicBlockRef blockRef00 = factory.AddBlockRef(block
                                                             , Vector2D.Zero
                                                             , ortho ? 90.0 : 0.0);

                // compute bounding box
                Box2D boxEntities = Tools.BoundingBox(factory, 0.0, false);

                // compute second entity position on row 0
                PicBlockRef blockRef01 = factory.AddBlockRef(block
                                                             , new Vector2D(
                                                                 boxEntities.XMax + boxEntities.XMin + 5.0 * boxEntities.Width + (ortho ? 1.0 : 0.0) * impositionOffset.X
                                                                 , boxEntities.YMax + boxEntities.YMin + (ortho ? 0.0 : 1.0) * impositionOffset.Y)
                                                             , ortho ? 270.0 : 180.0);
                if (!PicBlockRef.Distance(blockRef00, blockRef01, PicBlockRef.DistDirection.HORIZONTAL_RIGHT, out double horizontalDistance))
                {
                    throw new Exception("Failed to compute distance between to block refs");
                }
                Vector2D vecPosition = new Vector2D(
                    boxEntities.XMax + boxEntities.XMin + 5.0 * boxEntities.Width + minDistance.X - horizontalDistance + (ortho ? 1.0 : 0.0) * impositionOffset.X
                    , boxEntities.YMax + boxEntities.YMin + (ortho ? 0.0 : 1.0) * impositionOffset.Y);
                blockRef01.Position = vecPosition;

                // positions
                _relativePositions       = new BPosition[1, 2];
                _relativePositions[0, 0] = new BPosition(Vector2D.Zero, ortho ? 90.0 : 0.0);
                _relativePositions[0, 1] = new BPosition(vecPosition, ortho ? 270.0 : 180.0);
                // bboxes
                _bboxes       = new Box2D[1, 2];
                _bboxes[0, 0] = blockRef00.Box;//boxEntities;
                _bboxes[0, 1] = blockRef01.Box;

                // compute Y step (row1 / row0)
                // row0
                List <PicBlockRef> listRow0 = new List <PicBlockRef>
                {
                    blockRef00,
                    blockRef01
                };
                // row1
                List <PicBlockRef> listRow1   = new List <PicBlockRef>();
                PicBlockRef        blockRef10 = factory.AddBlockRef(
                    block
                    , new Vector2D(0.0, 5.0 * boxEntities.Height + minDistance.Y)
                    , ortho ? 90.0 : 0.0);
                PicBlockRef blockRef11 = factory.AddBlockRef(
                    block
                    , new Vector2D(vecPosition.X, vecPosition.Y + 5.0 * boxEntities.Height + minDistance.Y)
                    , ortho ? 270.0 : 180.0);
                listRow1.Add(blockRef10);
                listRow1.Add(blockRef11);

                if (!PicBlockRef.Distance(listRow0, listRow1, PicBlockRef.DistDirection.VERTICAL_TOP, out double verticalDistance))
                {
                    throw new Exception("Failed to compute distance between to block refs");
                }
                _patternStep.Y = 5.0 * boxEntities.Height - verticalDistance + 2.0 * minDistance.Y;

                blockRef10.Position = new Vector2D(0.0, _patternStep.Y);
                blockRef11.Position = new Vector2D(vecPosition.X, vecPosition.Y + _patternStep.Y);

                // compute X step (col1 / col2)
                PicBlockRef blockRef02 = factory.AddBlockRef(
                    block
                    , new Vector2D(boxEntities.XMin + 5.0 * boxEntities.Width + minDistance.X
                                   , 0.0)
                    , ortho ? 90.0 : 0.0);
                PicBlockRef blockRef12 = factory.AddBlockRef(
                    block
                    , new Vector2D(boxEntities.XMin + 5.0 * boxEntities.Width + minDistance.X
                                   , _patternStep.Y)
                    , ortho ? 90.0 : 0.0);

                List <PicBlockRef> listCol1 = new List <PicBlockRef> {
                    blockRef01, blockRef11
                };
                List <PicBlockRef> listCol2 = new List <PicBlockRef> {
                    blockRef02, blockRef12
                };

                horizontalDistance = 0.0;
                if (!PicBlockRef.Distance(listCol1, listCol2, PicBlockRef.DistDirection.HORIZONTAL_RIGHT, out horizontalDistance))
                {
                    throw new Exception("Failed to compute distance between to block refs");
                }
                _patternStep.X = boxEntities.XMin + 5.0 * boxEntities.Width - horizontalDistance + 2.0 * minDistance.X;
            }
        }