private static List<Intersection> CutByLineVertical(Vertex s1, Vertex s2, LinkedList<VertexBase> linkC)
        {
            var crossXs = new List<Intersection>();
            var x = s1.X;

            List<VertexBase> shearedPolyC = linkC.ToList();

            var minY = s1.Y > s2.Y ? s2.Y : s1.Y;
            var maxY = s1.Y > s2.Y ? s1.Y : s2.Y;

            int i = -1;
            bool backToHead = false;
            for (var vertex = linkC.First;
                //这样回到头部的线也可以正常被切到
                vertex != null &&
                ((vertex.Value is Vertex && vertex.Next != null) ||
                ((vertex.Value is Intersection) && ((Intersection)vertex.Value).NextC != null) ||
                    (vertex.Value is Vertex && vertex.Next == null && !backToHead) ||
                    (vertex.Value is Intersection && ((Intersection)vertex.Value).NextC == null && !backToHead));
                vertex = vertex.Next)
            {
                i++;
                var c1 = shearedPolyC[i % shearedPolyC.Count];
                var c2 = shearedPolyC[(i + 1)%shearedPolyC.Count];

                // 重合
                if (c1.X == c2.X && c1.X == x) continue;
                //不相交
                if (c1.X > x && c2.X > x) continue;
                if (c1.X < x && c2.X < x) continue;

                var y = LineCrossV(x, c1, c2);

                var inters = new Intersection(x, y);

                VertexBase next = null;
                if ((y > minY && y < maxY) ||
                    (c2.X == x && y == minY) ||
                    (c2.X == x && y == maxY) ||
                    (y == minY && c1.X != x && c2.X != x) ||
                    (y == maxY && c1.X != x && c2.X != x))
                {
                    inters.Name = "I" + Counter.Default.Val++;
                    if (vertex.Next == null)
                    {
                        backToHead = true;
                        next = linkC.First.Value;
                    }
                    else
                    {
                        next = vertex.Next.Value;
                    }

                    WindowLog.Default.Log("切割C的边{0}{1}得到交点{2}", vertex.Value.Name,
                        next.Name, inters.Name);

                    inters.NextC = next;
                    if (vertex.Value is Vertex)
                        (vertex.Value as Vertex).Next = inters;
                    else if (vertex.Value is Intersection)
                        (vertex.Value as Intersection).NextC = inters;
                    linkC.AddAfter(vertex, inters);
                    vertex = vertex.Next;
                    crossXs.Add(inters);
                }

                if (backToHead)
                    break;

                #region log
                var cLinkSb = new StringBuilder();
                var v = linkC.First.Value;
                while (v != null)
                {
                    cLinkSb.Append(v.Name);
                    if (v is Intersection)
                    {
                        var curr = v as Intersection;
                        next = curr.NextC;
                    }
                    else if (v is Vertex)
                    {
                        var curr = v as Vertex;
                        next = curr.Next;
                    }

                    if (next.Equals(linkC.First.Value))
                    {
                        break;
                    }
                    v = next;
                    cLinkSb.Append("->");
                }
                WindowLog.Default.Log("C链表:" + cLinkSb);
                #endregion
            }

            return crossXs;
        }
Exemplo n.º 2
0
        private static List <Intersection> CutByLineVertical(Vertex s1, Vertex s2, LinkedList <VertexBase> linkC)
        {
            var crossXs = new List <Intersection>();
            var x       = s1.X;

            List <VertexBase> shearedPolyC = linkC.ToList();

            var minY = s1.Y > s2.Y ? s2.Y : s1.Y;
            var maxY = s1.Y > s2.Y ? s1.Y : s2.Y;

            int  i          = -1;
            bool backToHead = false;

            for (var vertex = linkC.First;
                 //这样回到头部的线也可以正常被切到
                 vertex != null &&
                 ((vertex.Value is Vertex && vertex.Next != null) ||
                  ((vertex.Value is Intersection) && ((Intersection)vertex.Value).NextC != null) ||
                  (vertex.Value is Vertex && vertex.Next == null && !backToHead) ||
                  (vertex.Value is Intersection && ((Intersection)vertex.Value).NextC == null && !backToHead));
                 vertex = vertex.Next)
            {
                i++;
                var c1 = shearedPolyC[i % shearedPolyC.Count];
                var c2 = shearedPolyC[(i + 1) % shearedPolyC.Count];

                // 重合
                if (c1.X == c2.X && c1.X == x)
                {
                    continue;
                }
                //不相交
                if (c1.X > x && c2.X > x)
                {
                    continue;
                }
                if (c1.X < x && c2.X < x)
                {
                    continue;
                }

                var y = LineCrossV(x, c1, c2);

                var inters = new Intersection(x, y);

                VertexBase next = null;
                if ((y > minY && y < maxY) ||
                    (c2.X == x && y == minY) ||
                    (c2.X == x && y == maxY) ||
                    (y == minY && c1.X != x && c2.X != x) ||
                    (y == maxY && c1.X != x && c2.X != x))
                {
                    inters.Name = "I" + Counter.Default.Val++;
                    if (vertex.Next == null)
                    {
                        backToHead = true;
                        next       = linkC.First.Value;
                    }
                    else
                    {
                        next = vertex.Next.Value;
                    }

                    WindowLog.Default.Log("切割C的边{0}{1}得到交点{2}", vertex.Value.Name,
                                          next.Name, inters.Name);

                    inters.NextC = next;
                    if (vertex.Value is Vertex)
                    {
                        (vertex.Value as Vertex).Next = inters;
                    }
                    else if (vertex.Value is Intersection)
                    {
                        (vertex.Value as Intersection).NextC = inters;
                    }
                    linkC.AddAfter(vertex, inters);
                    vertex = vertex.Next;
                    crossXs.Add(inters);
                }

                if (backToHead)
                {
                    break;
                }

                #region log
                var cLinkSb = new StringBuilder();
                var v       = linkC.First.Value;
                while (v != null)
                {
                    cLinkSb.Append(v.Name);
                    if (v is Intersection)
                    {
                        var curr = v as Intersection;
                        next = curr.NextC;
                    }
                    else if (v is Vertex)
                    {
                        var curr = v as Vertex;
                        next = curr.Next;
                    }

                    if (next.Equals(linkC.First.Value))
                    {
                        break;
                    }
                    v = next;
                    cLinkSb.Append("->");
                }
                WindowLog.Default.Log("C链表:" + cLinkSb);
                #endregion
            }

            return(crossXs);
        }
        /// <summary>
        /// 用实体多边形S的边切割切割多边形C,并插入交点到C中
        /// </summary>
        /// <param name="s1"></param>
        /// <param name="s2"></param>
        /// <param name="linkC"></param>
        /// <returns></returns>
        private static List<Intersection> CutByLine(Vertex s1, Vertex s2, LinkedList<VertexBase> linkC)
        {
            if (s1.X == s2.X)
                return CutByLineVertical(s1, s2, linkC);

            var crossXs = new List<Intersection>();

            double slope = 0, y = s1.Y;

            slope = (s2.Y - s1.Y) / (s1.X - s2.X);//s2.Y == s1.Y不单独判断,反正这里可以正常处理s2.Y == s1.Y即slope==0
            var shearedPolyC = linkC.Select(r => new Vertex(r.X, r.X * slope + r.Y) as VertexBase).ToList();//为了保存错切计算的坐标
            y = s1.X * slope + s1.Y;

            var minX = s1.X > s2.X ? s2.X : s1.X;
            var maxX = s1.X > s2.X ? s1.X : s2.X;

            //LinkedListNode<VertexBase> vertex;
            int i = -1;
            var backToHead = false;
            for (var vertex = linkC.First;
                //这样回到头部的线也可以正常被切到
                vertex != null &&
                ((vertex.Value is Vertex && vertex.Next != null) ||
                ((vertex.Value is Intersection) && ((Intersection)vertex.Value).NextC != null) ||
                    (vertex.Value is Vertex && vertex.Next == null && !backToHead) ||
                    (vertex.Value is Intersection && ((Intersection)vertex.Value).NextC == null && !backToHead));
                    
                 vertex = vertex.Next)
            {
                ++i;
                var c1 = shearedPolyC[i % shearedPolyC.Count];
                var c2 = shearedPolyC[(i + 1) % shearedPolyC.Count];

                // 重合
                if (c1.Y == c2.Y && c1.Y == y) continue;
                //不相交
                if (c1.Y > y && c2.Y > y) continue;
                if (c1.Y < y && c2.Y < y) continue;

                var x = LineCrossH(y, c1, c2);
                var npy = y - x * slope;
                var inters = new Intersection(x, npy);

                VertexBase next = null;
                if ((x > minX && x < maxX) ||
                    (c2.Y == y && x == s2.X) ||
                    (x == minX && c1.Y != y && c2.Y != y) ||
                    (x == maxX && c1.Y != y && c2.Y != y))
                {
                    inters.Name = "I" + Counter.Default.Val++;
                    if (vertex.Next == null)
                    {
                        backToHead = true;
                        next = linkC.First.Value;
                    }
                    else
                    {
                        next = vertex.Next.Value;
                    }

                    WindowLog.Default.Log("切割C的边{0}{1}得到交点{2}", vertex.Value.Name,
                        next.Name, inters.Name);

                    inters.NextC = next;
                    if (vertex.Value is Vertex)
                        ((Vertex)vertex.Value).Next = inters;
                    else if (vertex.Value is Intersection)
                        ((Intersection)vertex.Value).NextC = inters;
                    linkC.AddAfter(vertex, inters);
                    vertex = vertex.Next;
                    crossXs.Add(inters);
                }

                if (backToHead)
                    break;

                #region log
                var cLinkSb = new StringBuilder();
                var v = linkC.First.Value;
                while (v != null)
                {
                    cLinkSb.Append(v.Name);
                    if (v is Intersection)
                    {
                        var curr = v as Intersection;
                        next = curr.NextC;
                    }
                    else if (v is Vertex)
                    {
                        var curr = v as Vertex;
                        next = curr.Next;
                    }

                    if (next.Equals(linkC.First.Value))
                    {
                        break;
                    }
                    v = next;
                    cLinkSb.Append("->");
                }
                WindowLog.Default.Log("C链表:" + cLinkSb);
                #endregion
            }

            return crossXs;
        }
Exemplo n.º 4
0
        /// <summary>
        /// 用实体多边形S的边切割切割多边形C,并插入交点到C中
        /// </summary>
        /// <param name="s1"></param>
        /// <param name="s2"></param>
        /// <param name="linkC"></param>
        /// <returns></returns>
        private static List <Intersection> CutByLine(Vertex s1, Vertex s2, LinkedList <VertexBase> linkC)
        {
            if (s1.X == s2.X)
            {
                return(CutByLineVertical(s1, s2, linkC));
            }

            var crossXs = new List <Intersection>();

            double slope = 0, y = s1.Y;

            slope = (s2.Y - s1.Y) / (s1.X - s2.X);                                                           //s2.Y == s1.Y不单独判断,反正这里可以正常处理s2.Y == s1.Y即slope==0
            var shearedPolyC = linkC.Select(r => new Vertex(r.X, r.X * slope + r.Y) as VertexBase).ToList(); //为了保存错切计算的坐标

            y = s1.X * slope + s1.Y;

            var minX = s1.X > s2.X ? s2.X : s1.X;
            var maxX = s1.X > s2.X ? s1.X : s2.X;

            //LinkedListNode<VertexBase> vertex;
            int i          = -1;
            var backToHead = false;

            for (var vertex = linkC.First;
                 //这样回到头部的线也可以正常被切到
                 vertex != null &&
                 ((vertex.Value is Vertex && vertex.Next != null) ||
                  ((vertex.Value is Intersection) && ((Intersection)vertex.Value).NextC != null) ||
                  (vertex.Value is Vertex && vertex.Next == null && !backToHead) ||
                  (vertex.Value is Intersection && ((Intersection)vertex.Value).NextC == null && !backToHead));

                 vertex = vertex.Next)
            {
                ++i;
                var c1 = shearedPolyC[i % shearedPolyC.Count];
                var c2 = shearedPolyC[(i + 1) % shearedPolyC.Count];

                // 重合
                if (c1.Y == c2.Y && c1.Y == y)
                {
                    continue;
                }
                //不相交
                if (c1.Y > y && c2.Y > y)
                {
                    continue;
                }
                if (c1.Y < y && c2.Y < y)
                {
                    continue;
                }

                var x      = LineCrossH(y, c1, c2);
                var npy    = y - x * slope;
                var inters = new Intersection(x, npy);

                VertexBase next = null;
                if ((x > minX && x < maxX) ||
                    (c2.Y == y && x == s2.X) ||
                    (x == minX && c1.Y != y && c2.Y != y) ||
                    (x == maxX && c1.Y != y && c2.Y != y))
                {
                    inters.Name = "I" + Counter.Default.Val++;
                    if (vertex.Next == null)
                    {
                        backToHead = true;
                        next       = linkC.First.Value;
                    }
                    else
                    {
                        next = vertex.Next.Value;
                    }

                    WindowLog.Default.Log("切割C的边{0}{1}得到交点{2}", vertex.Value.Name,
                                          next.Name, inters.Name);

                    inters.NextC = next;
                    if (vertex.Value is Vertex)
                    {
                        ((Vertex)vertex.Value).Next = inters;
                    }
                    else if (vertex.Value is Intersection)
                    {
                        ((Intersection)vertex.Value).NextC = inters;
                    }
                    linkC.AddAfter(vertex, inters);
                    vertex = vertex.Next;
                    crossXs.Add(inters);
                }

                if (backToHead)
                {
                    break;
                }

                #region log
                var cLinkSb = new StringBuilder();
                var v       = linkC.First.Value;
                while (v != null)
                {
                    cLinkSb.Append(v.Name);
                    if (v is Intersection)
                    {
                        var curr = v as Intersection;
                        next = curr.NextC;
                    }
                    else if (v is Vertex)
                    {
                        var curr = v as Vertex;
                        next = curr.Next;
                    }

                    if (next.Equals(linkC.First.Value))
                    {
                        break;
                    }
                    v = next;
                    cLinkSb.Append("->");
                }
                WindowLog.Default.Log("C链表:" + cLinkSb);
                #endregion
            }

            return(crossXs);
        }