Example #1
0
 //进行旋转
 public void applyMatrix(PointMatrix matrix)
 {
     for (int i = 0; i < polygons.Count; i++)
     {
         for (int j = 0; j < polygons[i].Count(); j++)
         {
             polygons[i][j] = matrix.apply(polygons[i][j]);
         }
     }
 }
Example #2
0
        //注意输入和输出类型 ,利用mypoloygons类进行旋转及求交
        /// <summary>
        /// 划分最小格子,并求交集
        /// </summary>
        /// <param name="pgPaths">最小多边形盒子构成的Paths</param>
        /// <param name="rotation"></param>
        /// <param name="side_length"></param>
        /// <param name="rownum"></param>
        /// <param name="colnum"></param>
        /// <returns></returns>
        private List <Paths> GetMeshPologons(Path pgPaths, float rotation, int side_length, int rownum, int colnum)
        {
            PointMatrix matrix = new PointMatrix(rotation);     //生成旋转矩阵

            PointMatrix matrix1 = new PointMatrix(-rotation);   //反旋转矩阵,恢复数据使用

            mypolygons pgPolygons = new mypolygons(pgPaths);

            pgPolygons.applyMatrix(matrix);                    //对多边形轮廓进行旋转
            pgPolygons.calculateAABB();


            mypolygons mmpgPolygons = new mypolygons(mOrignalPaths);

            pgPolygons.applyMatrix(matrix);

            Paths    convPgpaths = pgPolygons.getPologons(); //获得旋转后返回的pologons值
            IntPoint minPoint    = pgPolygons.getMinPoint(); //获得最小包围盒的最小点和最大点
            IntPoint maxPoint    = pgPolygons.getMaxPoint();

            IntPoint[,] IntPointDotMatrix = new IntPoint[rownum + 1, colnum + 1]; //定义点阵存储交点

            List <Paths> meshPath = new List <Paths>();                           //网格输出,每一行一个paths

            //存储数据点矩阵
            for (int i = 0; i < rownum + 1; i++)
            {
                for (int j = 0; j < colnum + 1; j++)
                {
                    if (i < rownum)    //不是最后一行
                    {
                        IntPointDotMatrix[i, j].Y = maxPoint.Y - i * side_length;
                    }
                    else
                    {
                        IntPointDotMatrix[i, j].Y = minPoint.Y;
                    }                                                          //最后一行,直接等于ymin

                    if (j < colnum)
                    {
                        IntPointDotMatrix[i, j].X = minPoint.X + j * side_length;
                    }
                    else
                    {
                        IntPointDotMatrix[i, j].X = maxPoint.X;
                    }                                                          //最后一列
                }
            }


            // 存储网格多边形
            List <maddtionpologonIndex> mtempoutAddtionPathsIndex = new List <maddtionpologonIndex>();

            for (int i = 0; i < rownum; i++)     //行数
            {
                Paths tempPaths = new Paths();   //存储行Paths
                for (int j = 0; j < colnum; j++) //列数
                {
                    Path pathgezi = new Path();
                    pathgezi.Add(IntPointDotMatrix[i, j]);          //逆时针存储
                    pathgezi.Add(IntPointDotMatrix[i + 1, j]);
                    pathgezi.Add(IntPointDotMatrix[i + 1, j + 1]);
                    pathgezi.Add(IntPointDotMatrix[i, j + 1]);
                    tempPaths.Add(pathgezi);
                }
                mypolygons temppgPolygons = new mypolygons(tempPaths);
                temppgPolygons.applyMatrix(matrix1);              //旋转回去,恢复最开始的方向

                ////不求交集时使用
                // meshPath.Add(temppgPolygons.getPologons());

                ////求交集时使用,但是如果temppgPolygons完全在原始多边形内就会被合并了。需修改intersection函数2016_04_21
                //注意在填充时为保证位置上的相邻判断,在结果中添加了空格子占位 2016_04_22
                //Paths m_testOut = temppgPolygons.intersection(mOrignalPaths);
                //meshPath.Add(temppgPolygons.intersection(mOrignalPaths));
                List <maddtionpologonIndex> tempoutAddtionPathsIndex = new List <maddtionpologonIndex> ();
                meshPath.Add(temppgPolygons.intersection(mOrignalPaths, i, ref tempoutAddtionPathsIndex));

                mtempoutAddtionPathsIndex.AddRange(tempoutAddtionPathsIndex);  //给符合的多边形
            }
            outAddtionRectPologons.Add(mtempoutAddtionPathsIndex);
            return(meshPath);
        }
Example #3
0
        /// <summary>
        /// 填充内部区域的
        /// </summary>
        /// <param name="pgPaths"> 输入的多边形</param>
        /// <param name="lineSpacing">线宽</param>
        /// <param name="rotation">旋转角度</param>
        /// Outinfillpath 修改为输出一条路径,之前是输出一条路径集合 //便于画图 2016_04_22
        ///
        public static Path generateLineInfill(Path pgPaths, int lineSpacing, float rotation, ref Path secondinfillpath) //可以是path,也可以是paths,lineSpacing有倍数
        {
            Path Outinfillpath = new Path();                                                                            //内部填充路劲输出

            Console.WriteLine("linespacing 线宽为:{0}", lineSpacing);
            Console.WriteLine("rotation 旋转角度为:{0}", rotation);

            ///先偏置一圈2016_04_22
            Paths orpgPaths = new Paths();

            orpgPaths.Add(pgPaths);
            Paths         solution3 = new Paths(); //产生偏置
            ClipperOffset co        = new ClipperOffset();

            co.AddPaths(orpgPaths, JoinType.jtRound, EndType.etClosedPolygon);



            //偏置时,偏置量需要先扩大Scale倍
            co.Execute(ref solution3, -lineSpacing * 0.4);
            //DrawBitmap(solution2, Color.Green,Color.White, 1.0f, isDrawPologonState);


            PointMatrix matrix     = new PointMatrix(rotation); //生成旋转矩阵
            mypolygons  pgPolygons = new mypolygons(new Path());

            if (solution3.Count > 0) //如果求交后无点
            {
                pgPolygons = new mypolygons(solution3[0]);
            }
            else
            {
                return(new Path());
            }
            pgPolygons.applyMatrix(matrix);                  //对多边形轮廓进行旋转
            pgPolygons.calculateAABB();                      //计算最小包围盒
            Paths    convPgpaths = pgPolygons.getPologons(); //获得旋转后返回的pologons值
            IntPoint minPoint    = pgPolygons.getMinPoint(); //获得最小包围盒的最小点和最大点
            IntPoint maxPoint    = pgPolygons.getMaxPoint();

            int lineCount = (int)(maxPoint.Y - minPoint.Y + (lineSpacing - 1)) / lineSpacing;  //获得线的条数

            Console.WriteLine("线的条数:{0}", lineCount);
            int yuliang = (int)(maxPoint.Y - minPoint.Y) - (lineCount - 1) * lineSpacing;


            //2016-0604调整填充的线的大小
            int lowdoor  = (int)(4 * lineSpacing / 10);
            int highdoor = (int)(8 * lineSpacing / 10);
            int deta     = (int)(1 * lineSpacing / 10);

            //Console.WriteLine("deta的值为{0}",deta);
            if (yuliang > lowdoor && yuliang < highdoor)
            {
                lineSpacing = lineSpacing + (yuliang - deta) / lineCount;
            }
            if (yuliang >= highdoor)
            {
                lineSpacing = (int)(maxPoint.Y - minPoint.Y - deta) / (lineCount + 1);
                lineCount   = lineCount + 1;
            }
            List <List <Int64> > cutList = new List <List <Int64> >();

            for (int n = 0; n < lineCount; n++)            //初始化cutlist
            {
                cutList.Add(new List <Int64>());
            }
            for (int polyNr = 0; polyNr < convPgpaths.Count(); polyNr++)
            {
                IntPoint p1 = convPgpaths[polyNr][convPgpaths[polyNr].Count() - 1];   //获得轮廓的最后一个点
                for (int i = 0; i < convPgpaths[polyNr].Count(); i++)
                {
                    IntPoint p0 = convPgpaths[polyNr][i];
                    int      idx0 = (int)(p0.Y - minPoint.Y) / lineSpacing;   //获得p0p1线段的交点x坐标范围
                    int      idx1 = (int)(p1.Y - minPoint.Y) / lineSpacing;
                    Int64    yMin = p0.Y, yMax = p1.Y;
                    Console.WriteLine(yMin);
                    if (p0.Y > p1.Y)
                    {
                        yMin = p1.Y; yMax = p0.Y;
                    }
                    if (idx0 > idx1)
                    {
                        int tmp = idx0; idx0 = idx1; idx1 = tmp;
                    }                                                             //求最大
                    for (int idx = idx0; idx <= idx1; idx++)
                    {
                        //int x = (int)((idx * lineSpacing) + minPoint.X + lineSpacing / 2);
                        int y = (int)((idx * lineSpacing) + minPoint.Y + 0.04 * deta);  //已经先偏置处理了,第一条线有点偏移即可
                        if (y < yMin)
                        {
                            continue;
                        }
                        if (y >= yMax)
                        {
                            continue;
                        }
                        //int y = (int)(p0.Y + (p1.Y - p0.Y) * (x - p0.X) / (p1.X - p0.X));
                        int x = (int)(p0.X + (p1.X - p0.X) * (y - p0.Y) / (p1.Y - p0.Y));
                        cutList[idx].Add(x);
                        //插入到对应的位置
                    }
                    p1 = p0;
                }
            }
            //进行点的排列,对于凸分区可以直接排列;对于Paths需要更改,凸多边形只有两个交点
            int     index        = 0;          //等同于idx
            Boolean linkDir      = true;
            Path    infillpath   = new Path(); //线段的输出
            Boolean secondeExise = false;

            IntPoint tempPointFir = new IntPoint();
            IntPoint tempPointSec = new IntPoint();

            //for (Int64 x = minPoint.X + lineSpacing / 2; x < maxPoint.X; x += lineSpacing)  //原来的,2016_04_22
            for (Int64 y = minPoint.Y + 1; y < maxPoint.Y; y += lineSpacing)  //还原x
            {
                //qsort(cutList[index].data(), cutList[index].size(), sizeof(int64_t), compare_int64_t); //排序算法暂时不需要使用
                cutList[index].Sort(); // 注意从小到大排序
                // cutList[index].Reverse(); //2018年7月11  翻转
                // Console.WriteLine(cutList[index]);

                int dotnum = cutList[index].Count();
                for (int i = 0; i + 1 < 2; i += 2)
                {
                    if (dotnum < 4)
                    {
                        if (linkDir)
                        {
                            infillpath.Add(matrix.unapply(new IntPoint(y, cutList[index][i])));      //正向链接
                            infillpath.Add(matrix.unapply(new IntPoint(y, cutList[index][dotnum - 1])));
                            tempPointFir = matrix.unapply(new IntPoint(y, cutList[index][dotnum - 1]));
                        }
                        else
                        {
                            infillpath.Add(matrix.unapply(new IntPoint(y, cutList[index][dotnum - 1])));    //反向链接
                            infillpath.Add(matrix.unapply(new IntPoint(y, cutList[index][i])));
                            tempPointFir = matrix.unapply(new IntPoint(y, cutList[index][i]));
                        }
                    }

                    else
                    {
                        IntPoint point_i  = matrix.unapply(new IntPoint(y, cutList[index][i]));     //点i
                        IntPoint point_i1 = matrix.unapply(new IntPoint(y, cutList[index][i + 1])); //点i+1
                        IntPoint point_i2 = matrix.unapply(new IntPoint(y, cutList[index][i + 2])); //点i+2
                        IntPoint point_i3 = matrix.unapply(new IntPoint(y, cutList[index][i + 3])); //点i+3
                        secondeExise = true;
                        continue;
                    }
                }
                index  += 1;
                linkDir = !linkDir;
            }

            Outinfillpath = infillpath;


            return(Outinfillpath);
        }