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;
        }
        private void MoveOver(object sender, MouseEventArgs e)
        {
            _cross.Visible = false;

            var point = e.GetPosition(Canvas);
            PointVec.Text = "坐标位置:" + point.X + "," + point.Y;
            var newVector = new Vertex(point.X, point.Y);

            if (Keyboard.IsKeyDown(Key.LeftShift) && (_drawingPolygonC || _drawingPolygonS))
            {
                VertexBase pointPre = null;
                if (_drawingPolygonS)
                    pointPre = _polyS.PointList[_polygonSVertexNum - 2];
                else if (_drawingPolygonC)
                    pointPre = _polyC.PointList[_polygonCVertexNum - 2];
                var dx = pointPre.X - point.X;
                double tan = 0;
                if (dx != 0)
                {
                    var dy = pointPre.Y - point.Y;
                    tan = Math.Abs(dy / dx);
                }
                else
                {
                    tan = double.MaxValue;
                }
                if (tan <= 1)
                    newVector = new Vertex(point.X, (double)pointPre.Y);
                else if (tan > 1)
                {
                    newVector = new Vertex((double)pointPre.X, point.Y);
                }
            }

            //抓去最近点
            Point nearestPoint = new Point();
            bool hasNearestSite = false;
            if (_drawingPolygonS)
                hasNearestSite = IsCloseToPolygon(point, _polyC, ref nearestPoint);
            else if (_drawingPolygonC)
                hasNearestSite = IsCloseToPolygon(point, _polyS, ref nearestPoint);

            if (hasNearestSite)
            {
                _cross.Center = nearestPoint;
                _cross.Visible = true;
                var screenPoint = Canvas.PointToScreen(nearestPoint);
                SetCursorPos((int)screenPoint.X,(int)screenPoint.Y);
            }

            if (_drawingPolygonS && _polygonSVertexNum > 0)
            {
                _polyS.PointList[_polygonSVertexNum - 1].SetXY(newVector.X, newVector.Y);
                _polyS.Render(Canvas);
            }
            if (_drawingPolygonC && _polygonCVertexNum > 0)
            {
                _polyC.PointList[_polygonCVertexNum - 1].SetXY(newVector.X, newVector.Y);
                _polyC.Render(Canvas);
            }
        }
        /// <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;
        }