Ejemplo n.º 1
0
        /// <summary>
        /// 图形的扩张与收缩,存在BUG,需要再处理
        /// </summary>
        /// <param name="lines"></param>
        /// <returns></returns>
        public List <Line3D> Elastic(List <Line3D> lines, double range, List <Line3D> neverOffset)
        {
            List <Line3D> NLList = new List <Line3D>();
            //获取当前线段的顺时针排序
            List <Line3D> sortLines = GraphicAlgorithm.Sort(lines);

            //获取当前连续的顶点
            List <Vector3D> PList = new List <Vector3D>();

            //当前直线的方向
            List <Vector3D> DList = new List <Vector3D>();

            //记录所有的点
            sortLines.ForEach(x => {
                PList.Add(x.Start);
                DList.Add(x.Direction);
            });

            //所有点的列表
            List <Vector3D> NPList = new List <Vector3D>();

            int startIndex, endindex;

            //获取所有的点
            for (int i = 0; i < DList.Count; i++)
            {
                startIndex = i == 0 ? DList.Count - 1 : i - 1;
                endindex   = i;
                //两个线之间的夹角
                double sina = DList[startIndex].Cross(DList[endindex]).Modulus();

                //由于偏移出是平行四边形,则要移动的长度为
                var moveLen = -range / sina;

                //移动的方向为
                var movedir = DList[endindex] - DList[startIndex];

                Vector3D np = DList[i] + movedir * moveLen;
                //添加新点
                NPList.Add(np);
            }

            ///形成新的线
            for (int i = 0; i < NPList.Count; i++)
            {
                var index = i == (DList.Count - 1) ? 0 : i + 1;
                NLList.Add(Line3D.Create(NPList[i], NPList[index]));
            }

            return(NLList);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// 按照指定的高度和宽度,对规则矩形进行划分,当前算法,运行的前提条件是,传入的图形是矩形元素
        /// </summary>
        /// <param name="square"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <returns></returns>
        public List <List <Line2D> > Partition(List <Line2D> square, double width, double height, Vector2D offset)
        {
            //根据板子宽度和高度,重新定义偏移量
            var loffset = this.LayoutOffset(width, height, offset);
            //获取要划分的矩形裕兴
            List <Line2D> lines = new List <Line2D>(square);

            //获取当前的划分多边形
            List <List <Line2D> > result = new List <List <Line2D> >();

            //获取图形中的最小点
            List <Vector2D> vst = new List <Vector2D>();

            square.ForEach(x =>
            {
                vst.Add(x.Start);
                vst.Add(x.End);
            });

            //排除相同点
            vst = vst.Distinct(new Vector2DEqualityComparer()).ToList();

            //查找最小角点
            var origin = vst.OrderBy(a =>
            {
                return(Math.Round(a.X, 7));
            }).ThenBy(b =>
            {
                return(Math.Round(b.Y, 7));
            }).FirstOrDefault();
            ////查找最小角点
            //var origin = vst.OrderBy(a => a.X).ThenBy(c => c.Y).FirstOrDefault();
            //逆时针排序,排列出
            List <Line2D> sequeeLines = GraphicAlgorithm.Sort(lines, origin, 1);

            //获取当前矩形的实际宽度和高度
            double sw = sequeeLines[0].Length + loffset.X;
            double sh = sequeeLines[1].Length + loffset.Y;

            //代表需要水平偏移的个数
            var lnx = Math.Ceiling(sw / width);
            //代表垂直偏移的个数
            var lny = Math.Ceiling(sh / height);

            for (int i = 0; i < lnx; i++)
            {
                for (int j = 0; j < lny; j++)
                {
                    Vector2D startPoint = null;
                    if (loffset != null)
                    {
                        startPoint = origin - loffset;
                    }
                    //代表顶点的偏移
                    Vector2D v1 = startPoint.Offset(width * i * sequeeLines[0].Direction).Offset(height * j * sequeeLines[1].Direction);

                    //最右边的顶点偏移
                    Vector2D v2 = startPoint.Offset(width * (i + 1) * sequeeLines[0].Direction).Offset(height * j * sequeeLines[1].Direction);

                    //偏移Y方向的区域,假如超过边界,则取边界值
                    Vector2D v4 = startPoint.Offset(width * i * sequeeLines[0].Direction).Offset(height * (j + 1) * sequeeLines[1].Direction);

                    if (v1.X < origin.X)
                    {
                        v1.X = origin.X;
                    }
                    if (v1.Y < origin.Y)
                    {
                        v1.Y = origin.Y;
                    }
                    //假如超出边界,则取边界值
                    if (v2.X > (origin.X + sequeeLines[0].Length))
                    {
                        v2 = Vector2D.Create(origin.X + sequeeLines[0].Length, v2.Y);
                    }

                    if (v2.Y < origin.Y)
                    {
                        v2.Y = origin.Y;
                    }
                    if (v4.Y > (origin.Y + sequeeLines[1].Length))
                    {
                        v4 = Vector2D.Create(v1.X, origin.Y + sequeeLines[1].Length);
                    }

                    if (v4.X < origin.X)
                    {
                        v4.X = origin.X;
                    }
                    if (v4.Y < origin.Y)
                    {
                        v4.Y = origin.Y;
                    }
                    //计算对角点
                    Vector2D v3 = Vector2D.Create(v2.X, v4.Y);


                    //获取划分的小多边形
                    List <Line2D> line2ds = new List <Line2D>()
                    {
                        Line2D.Create(v1, v2),
                        Line2D.Create(v2, v3),
                        Line2D.Create(v3, v4),
                        Line2D.Create(v4, v1)
                    };
                    result.Add(line2ds);
                }
            }
            return(result);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// 对多边形进行扩张和缩放,range为负数为内缩小,为正数为外扩
        /// </summary>
        /// <param name="lines"></param>
        /// <param name="range"></param>
        /// <returns></returns>
        public List <Line2D> Elastic(List <Line2D> lines, double range, List <Line2D> neverOffset, bool allowDistortion = false)
        {
            if (range < 0)
            {
                //说明会引起多边形形状的变化
                Line2D line = lines.Find(x => x.Length < Math.Abs(range));

                //说明图形已经边型了,需要变形处理
                if (line != null && allowDistortion)
                {
                    //允许变形的缩放
                    this.ElasticDistortion(lines, range);
                }
            }


            List <Line2D> NLList = new List <Line2D>();
            //首先需要对线段进行一次合并,由于多边形可能存在共线的情况,那么偏移会出问题
            var mergelines = GraphicAlgorithm.Merge(lines);
            //获取当前线段的顺时针排序
            List <Line2D> sortLines = GraphicAlgorithm.Sort(mergelines, null, 1);

            //获取当前连续的顶点
            List <Vector2D> PList = new List <Vector2D>();

            //当前直线的方向
            List <Vector2D> DList = new List <Vector2D>();

            //记录所有的点
            sortLines.ForEach(x => {
                PList.Add(x.Start);
                DList.Add(x.Direction);
            });

            //所有点的列表
            List <Vector2D> NPList = new List <Vector2D>();

            int startIndex, endindex;

            //获取所有的点
            for (int i = 0; i < DList.Count; i++)
            {
                startIndex = i == 0 ? DList.Count - 1 : i - 1;
                endindex   = i;
                //两个线之间的夹角
                double sina = DList[startIndex].Cross(DList[endindex]);
                //用于判断当前是阴阳角
                var Corndir = 0;

                if (sina > 0)
                {
                    Corndir = 1;
                }
                else
                {
                    Corndir = -1;
                }
                //由于偏移出是平行四边形,则要移动的长度为
                var moveLen = -range / sina;

                Vector2D movedir = null;
                if (neverOffset != null)
                {
                    var nf = neverOffset.FindAll(x => x.Start.IsAlmostEqualTo(PList[i]) || x.End.IsAlmostEqualTo(PList[i]));

                    if (nf != null && nf.Count == 1)
                    {
                        if (nf[0].Direction.IsAlmostEqualTo(DList[startIndex]) || nf[0].Direction.IsAlmostEqualTo(-DList[startIndex]))
                        {
                            movedir = DList[startIndex];
                            Vector2D npt = PList[i] + movedir * range * Corndir;
                            NPList.Add(npt);
                        }
                        else
                        {
                            movedir = -DList[endindex];
                            Vector2D npt = PList[i] + movedir * range * Corndir;
                            NPList.Add(npt);
                        }

                        continue;
                    }
                    if (nf != null && nf.Count == 2)
                    {
                        NPList.Add(PList[i]);
                        continue;
                    }
                }
                //移动的方向为
                movedir = DList[endindex] - DList[startIndex];
                Vector2D np = PList[i] + movedir * moveLen;
                //添加新点
                NPList.Add(np);
            }

            ///形成新的线
            for (int i = 0; i < NPList.Count; i++)
            {
                var index = i == (NPList.Count - 1) ? 0 : i + 1;
                NLList.Add(Line2D.Create(NPList[i], NPList[index]));
            }

            return(NLList);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// 对指定的进行每个线段进行缩放,并且指定缩放的长度,传入的线,不能共线或者重叠,否则会出现错误
        /// </summary>
        /// <param name="nlist"></param>
        /// <returns></returns>
        public List <Line2D> Elastic2(List <Tuple <Line2D, Double> > nlist)
        {
            List <Line2D> lines = new List <Line2D>();

            //不处理变形的情况
            foreach (var tp in nlist)
            {
                if (tp.Item1.Length < tp.Item2)
                {
                    return(null);
                }
                else
                {
                    lines.Add(tp.Item1);
                }
            }

            //获取当前线段的顺时针排序
            List <Line2D> sortLines = GraphicAlgorithm.Sort(lines, null, 1);

            List <Line2D> moveLines = new List <Line2D>();

            ///开始线段偏移
            for (int i = 0; i < sortLines.Count; i++)
            {
                var v1      = Vector3D.Create(sortLines[i].Start.X, sortLines[i].Start.Y, 0);
                var v2      = Vector3D.Create(sortLines[i].End.X, sortLines[i].End.Y, 0);
                var l1      = Line3D.Create(v1, v2);
                var moveDir = l1.Direction.Cross(Vector3D.BasisZ);
                var tp      = nlist.Find(x => x.Item1.IsAlmostEqualTo(sortLines[i]));
                var nl      = l1.Offset(tp.Item2, -moveDir);
                moveLines.Add(TransformUtil.Projection(nl));
            }
            List <Vector2D> NPList = new List <Vector2D>();

            //开始循环所有的线段
            for (int i = 0; i < moveLines.Count; i++)
            {
                Vector2D v = null;
                if (i == 0)
                {
                    v = moveLines[0].IntersectStraightLine(moveLines[moveLines.Count - 1]);
                }
                else
                {
                    v = moveLines[i].IntersectStraightLine(moveLines[i - 1]);
                }

                if (v == null)
                {
                    return(null);
                }
                else
                {
                    NPList.Add(v);
                }
            }

            List <Line2D> nliset = new List <Line2D>();

            //生成新的多边形
            for (int i = 0; i < NPList.Count; i++)
            {
                if (i == 0)
                {
                    nliset.Add(Line2D.Create(NPList[NPList.Count - 1], NPList[i]));
                }
                else
                {
                    nliset.Add(Line2D.Create(NPList[i - 1], NPList[i]));
                }
            }

            return(nliset);
        }