Exemple #1
0
        /**
         * 对应于JS项目中的getParts
         */
        public static List <NestPath> BuildTree(List <NestPath> parts, double curve_tolerance)
        {
            List <NestPath> polygons = new List <NestPath>();

            for (int i = 0; i < parts.Count; i++)
            {
                NestPath cleanPoly = NestPath.cleanNestPath(parts[i]);
                cleanPoly.bid = parts[i].bid;
                if (cleanPoly.size() > 2 && Math.Abs(GeometryUtil.polygonArea(cleanPoly)) > curve_tolerance * curve_tolerance)
                {
                    cleanPoly.setSource(i);

                    polygons.Add(cleanPoly);
                }
            }

            CommonUtil.toTree(polygons, 0);
            return(polygons);
        }
Exemple #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);
        }
Exemple #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);
        }