示例#1
0
        public static List <NestPath> polygonOffset(NestPath polygon, double offset)
        {
            List <NestPath> result = new List <NestPath>();

            if (offset == 0 || GeometryUtil.almostEqual(offset, 0))
            {
                /**
                 * return EmptyResult
                 */
                return(result);
            }
            Path p = new Path();

            foreach (Segment s in polygon.getSegments())
            {
                ClipperCoor cc = toClipperCoor(s.getX(), s.getY());
                p.Add(new IntPoint(cc.getX(), cc.getY()));
            }

            int           miterLimit = 2;
            ClipperOffset co         = new ClipperOffset(miterLimit, Config.CURVE_TOLERANCE * Config.CLIIPER_SCALE);

            co.AddPath(p, JoinType.jtRound, EndType.etClosedPolygon);

            Paths newpaths = new Paths();

            co.Execute(ref newpaths, offset * Config.CLIIPER_SCALE);


            /**
             * 这里的length是1的话就是我们想要的
             */
            for (int i = 0; i < newpaths.Count; i++)
            {
                result.Add(CommonUtil.clipperToNestPath(newpaths[i]));
            }

            if (offset > 0)
            {
                NestPath from = result[0];
                if (GeometryUtil.polygonArea(from) > 0)
                {
                    from.reverse();
                }
                from.add(from.get(0)); from.getSegments().RemoveAt(0);
            }


            return(result);
        }
示例#2
0
        /**
         *  开始进行Nest计算
         * @return
         */
        public List <List <Placement> > startNest()
        {
            //去除parts点中有孔的点,只对最外围的零件进行排样
            List <NestPath> tree = CommonUtil.BuildTree(parts, Config.CURVE_TOLERANCE);

            //根据设定的零件之间的距离,将图像由内向外进行偏置
            CommonUtil.offsetTree(tree, 0.5 * config.SPACING);
            binPath.config = config;
            foreach (NestPath nestPath in parts)
            {
                nestPath.config = config;
            }
            //自相交多边形的清理
            NestPath binPolygon = NestPath.cleanNestPath(binPath);
            Bound    binBound   = GeometryUtil.getPolygonBounds(binPolygon);

            //如果零件之间设定了间距,则底板也需要进行偏置
            if (config.SPACING > 0)
            {
                List <NestPath> offsetBin = CommonUtil.polygonOffset(binPolygon, -0.5 * config.SPACING);
                if (offsetBin.Count == 1)
                {
                    binPolygon = offsetBin[0];
                }
            }
            binPolygon.setId(-1);//这个是用来干嘛的?可能是为了让底板的编号特殊一些

            //判断零件是否都能在底板中放置,如果零件的大小超过底板的大小,则直接清除
            List <int>      integers = checkIfCanBePlaced(binPolygon, tree);
            List <NestPath> safeTree = new List <NestPath>();

            foreach (int i in integers)
            {
                safeTree.Add(tree[i]);
            }
            tree = safeTree;
            //计算多边形的面积。如果面积值大于零,说明多边形方向为反方向,需要进行方向转换,但是为什么要做这个操作呢?
            if (GeometryUtil.polygonArea(binPolygon) > 0)
            {
                binPolygon.reverse();
            }

            /**
             * 确保为逆时针
             */
            for (int i = 0; i < tree.Count; i++)
            {
                Segment start = tree[i].get(0);
                Segment end   = tree[i].get(tree[i].size() - 1);
                if (start == end || GeometryUtil.almostEqual(start.x, end.x) && GeometryUtil.almostEqual(start.y, end.y))
                {
                    tree[i].pop();
                }
                if (GeometryUtil.polygonArea(tree[i]) > 0)
                {
                    tree[i].reverse();
                }
            }

            launchcount = 0;
            Result best = null;


            // Tree Modification based on nest4J
            //List<NestPath> modifiedTree = new List<NestPath>();

            //for (int i = 0; i < tree.Count; i++)
            //{
            //    List<Segment> modifiedSegment = new List<Segment>();
            //    NestPath currentTree = tree[i];
            //    List<Segment> currentTreeSegments = currentTree.getSegments();
            //    modifiedSegment.Add(currentTreeSegments[currentTreeSegments.Count-1]);
            //    for (int j = 0; j < currentTreeSegments.Count-1; j++)
            //    {
            //        modifiedSegment.Add(currentTreeSegments[j]);
            //    }
            //    currentTree.setSegments(modifiedSegment);
            //    modifiedTree.Add(currentTree);
            //}
            //tree = modifiedTree;



            for (int i = 0; i < loopCount; i++)
            {
                Result result = launchWorkers(tree, binPolygon, config);

                if (i == 0)
                {
                    best = result;
                }
                else
                {
                    if (best.fitness > result.fitness)
                    {
                        best = result;
                    }
                }
            }
            double sumarea   = 0; //底板多边形的面积
            double totalarea = 0; //放置所有零件的面积

            //placements中的Count数据就代表了使用了几个底板的数量,如果一个底板大小不够放置所有零件,那系统会自动增加一个底板
            for (int i = 0; i < best.placements.Count; i++)
            {
                totalarea += Math.Abs(GeometryUtil.polygonArea(binPolygon));
                for (int j = 0; j < best.placements[i].Count; j++)
                {
                    try
                    {
                        sumarea += Math.Abs(GeometryUtil.polygonArea(tree[best.placements[i][j].id]));
                    }
                    catch (Exception ex)
                    {
                    }
                }
            }
            double rate = (sumarea / totalarea) * 100;
            List <List <Placement> > appliedPlacement = applyPlacement(best, tree);

            return(appliedPlacement);
        }
示例#3
0
        /**
         *  开始进行Nest计算
         * @return
         */
        public List <List <Placement> > startNest()
        {
            List <NestPath> tree = CommonUtil.BuildTree(parts, Config.CURVE_TOLERANCE);

            CommonUtil.offsetTree(tree, 0.5 * config.SPACING);
            binPath.config = config;
            foreach (NestPath nestPath in parts)
            {
                nestPath.config = config;
            }
            NestPath binPolygon = NestPath.cleanNestPath(binPath);
            Bound    binBound   = GeometryUtil.getPolygonBounds(binPolygon);

            if (config.SPACING > 0)
            {
                List <NestPath> offsetBin = CommonUtil.polygonOffset(binPolygon, -0.5 * config.SPACING);
                if (offsetBin.Count == 1)
                {
                    binPolygon = offsetBin[0];
                }
            }
            binPolygon.setId(-1);

            List <int>      integers = checkIfCanBePlaced(binPolygon, tree);
            List <NestPath> safeTree = new List <NestPath>();

            foreach (int i in integers)
            {
                safeTree.Add(tree[i]);
            }
            tree = safeTree;

            double xbinmax = binPolygon.get(0).x;
            double xbinmin = binPolygon.get(0).x;
            double ybinmax = binPolygon.get(0).y;
            double ybinmin = binPolygon.get(0).y;

            for (int i = 1; i < binPolygon.size(); i++)
            {
                if (binPolygon.get(i).x > xbinmax)
                {
                    xbinmax = binPolygon.get(i).x;
                }
                else if (binPolygon.get(i).x < xbinmin)
                {
                    xbinmin = binPolygon.get(i).x;
                }

                if (binPolygon.get(i).y > ybinmax)
                {
                    ybinmax = binPolygon.get(i).y;
                }
                else if (binPolygon.get(i).y < ybinmin)
                {
                    ybinmin = binPolygon.get(i).y;
                }
            }
            for (int i = 0; i < binPolygon.size(); i++)
            {
                binPolygon.get(i).x -= xbinmin;
                binPolygon.get(i).y -= ybinmin;
            }


            double binPolygonWidth  = xbinmax - xbinmin;
            double binPolygonHeight = ybinmax - ybinmin;

            if (GeometryUtil.polygonArea(binPolygon) > 0)
            {
                binPolygon.reverse();
            }

            /**
             * 确保为逆时针
             */
            for (int i = 0; i < tree.Count; i++)
            {
                Segment start = tree[i].get(0);
                Segment end   = tree[i].get(tree[i].size() - 1);
                if (start == end || GeometryUtil.almostEqual(start.x, end.x) && GeometryUtil.almostEqual(start.y, end.y))
                {
                    tree[i].pop();
                }
                if (GeometryUtil.polygonArea(tree[i]) > 0)
                {
                    tree[i].reverse();
                }
            }

            launchcount = 0;
            Result best = null;


            // Tree Modification based on nest4J
            //List<NestPath> modifiedTree = new List<NestPath>();

            //for (int i = 0; i < tree.Count; i++)
            //{
            //    List<Segment> modifiedSegment = new List<Segment>();
            //    NestPath currentTree = tree[i];
            //    List<Segment> currentTreeSegments = currentTree.getSegments();
            //    modifiedSegment.Add(currentTreeSegments[currentTreeSegments.Count-1]);
            //    for (int j = 0; j < currentTreeSegments.Count-1; j++)
            //    {
            //        modifiedSegment.Add(currentTreeSegments[j]);
            //    }
            //    currentTree.setSegments(modifiedSegment);
            //    modifiedTree.Add(currentTree);
            //}
            //tree = modifiedTree;



            for (int i = 0; i < loopCount; i++)
            {
                Result result = launchWorkers(tree, binPolygon, config);

                if (i == 0)
                {
                    best = result;
                }
                else
                {
                    if (best.fitness > result.fitness)
                    {
                        best = result;
                    }
                }
            }
            double sumarea   = 0;
            double totalarea = 0;

            for (int i = 0; i < best.placements.Count; i++)
            {
                totalarea += Math.Abs(GeometryUtil.polygonArea(binPolygon));
                for (int j = 0; j < best.placements[i].Count; j++)
                {
                    try
                    {
                        sumarea += Math.Abs(GeometryUtil.polygonArea(tree[best.placements[i][j].id]));
                    }
                    catch (Exception ex)
                    {
                    }
                }
            }
            double rate = (sumarea / totalarea) * 100;
            List <List <Placement> > appliedPlacement = applyPlacement(best, tree);

            return(appliedPlacement);
        }