/// <summary>
        /// 给每个点设置相对角度(角度为向量(or_Pnt,rela_Pnt)和(0,1)的夹角)
        /// </summary>
        /// <param name="or_Pnt"></param>
        /// <param name="rela_Pnt"></param>
        private void SetRelaAng(Point_qt or_Pnt, ref Point_qt rela_Pnt)
        {
            double x = rela_Pnt.X - or_Pnt.X;
            double y = rela_Pnt.Y - or_Pnt.Y;

            rela_Pnt.Rela_Ang = y / Math.Sqrt(x * x + y * y);
        }
 /// <summary>
 /// 给list里边的Point设置相对角度
 /// </summary>
 /// <param name="or_Pnt"></param>
 /// <param name="list"></param>
 private void SetListPntAng(Point_qt or_Pnt, ref List <Point_qt> list)
 {
     Point_qt[] ar = list.ToArray();
     for (int i = 0; i < list.Count; i++)
     {
         SetRelaAng(or_Pnt, ref ar[i]);
     }
     list = ar.ToList();
 }
        /// <summary>
        /// 获得向量spnt_epnt在线段上的投影
        /// </summary>
        /// <param name="edge"></param>
        /// <param name="spnt"></param>
        /// <param name="epnt"></param>
        /// <returns></returns>
        private double GetVecProj(Edge_qt edge, Point_qt spnt, Point_qt epnt)
        {
            Point_qt p1 = edge.FromNode;
            Point_qt p2 = edge.ToNode;

            double e1_x = p2.X - p1.X;
            double e1_y = p2.Y - p1.Y;
            double e2_x = spnt.X - epnt.X;
            double e2_y = spnt.Y - epnt.Y;

            return((e1_x * e2_x + e1_y * e2_y) / Math.Sqrt(e1_x * e1_x + e1_y * e1_y));
        }
        /// <summary>
        /// 返回向量P1P2上距离点P1 dis处的坐标
        /// </summary>
        /// <param name="dis"></param>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        /// <returns></returns>
        private Point_qt CalcPnt_Coor(double dis, Point_qt p1, Point_qt p2)
        {
            Point_qt p = new Point_qt();

            double X      = p2.X - p1.X;
            double Y      = p2.Y - p1.Y;
            double length = Math.Sqrt(X * X + Y * Y);

            p.X = p1.X + (p2.X - p1.X) * dis / length;
            p.Y = p1.Y + (p2.Y - p1.Y) * dis / length;

            return(p);
        }
        /// <summary>
        /// 将Geometry里的Point压入List
        /// </summary>
        /// <returns></returns>
        private List <Point_qt> PutPoints2List()
        {
            Point_qt        pnt_qt;
            int             pCnt      = qtGeometry.GetPointCount();
            List <Point_qt> list_pnts = new List <Point_qt>(pCnt);

            for (int i = 0; i < pCnt; i++)
            {
                pnt_qt     = new Point_qt(qtGeometry.GetX(i), qtGeometry.GetY(i), qtGeometry.GetZ(i));
                pnt_qt.PID = i;
                list_pnts.Add(pnt_qt);
            }
            return(list_pnts);
        }
        /// <summary>
        /// 得到点线距
        /// </summary>
        /// <param name="edge"></param>
        /// <param name="pnt"></param>
        /// <returns></returns>
        private double GetD_PL(Edge_qt edge, Point_qt pnt)
        {
            double x = pnt.X;
            double y = pnt.Y;

            Point_qt p1 = edge.FromNode;
            Point_qt p2 = edge.ToNode;

            double m = p2.X - p1.X;
            double n = p2.Y - p1.Y;

            double fenzi = Math.Abs(n * x - n * p1.X - m * y + m * p1.Y);
            double fenmu = Math.Sqrt(n * n + m * m);

            return(fenzi / fenmu);
        }
        /// <summary>
        /// 返回点p使得向量p1p和向量p1p2二维平面垂直(p1p2顺时针旋转90度得到p1p)
        /// p1p的模长为M
        /// </summary>
        /// <param name="M"></param>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        /// <returns></returns>
        private Point_qt ReferencePoint_Clock(double M, Point_qt p1, Point_qt p2)
        {
            Point_qt p    = new Point_qt();
            Vec2     p1p2 = new Vec2(p2.X - p1.X, p2.Y - p1.Y);
            Vec2     p1p  = p1p2.GetCrossVec2();

            if (p1p2 * p1p > 0)
            {
                p1p.X = -p1p.X;
                p1p.Y = -p1p.Y;
            }
            p1p = p1p.GetUnitVec2() * M;
            p.X = p1.X + p1p.X;
            p.Y = p1.Y + p1p.Y;

            return(p);
        }
        /// <summary>
        /// 构建凸包的递归算法
        /// </summary>
        /// <param name="RelaPnt"></param>
        /// <param name="stack"></param>
        private void Foo(Point_qt RelaPnt, Stack <Point_qt> stack)
        {
            Point_qt p2 = stack.Pop();
            Point_qt p1 = stack.Pop();

            if (IsLeft(p1, p2, RelaPnt))
            {
                stack.Push(p1);
                stack.Push(p2);
                stack.Push(RelaPnt);
            }
            else
            {
                stack.Push(p1);
                Foo(RelaPnt, stack);
            }
        }
        /// <summary>
        /// 判断点p3是否在线段p1p2左边
        /// </summary>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        /// <param name="p3"></param>
        /// <returns></returns>
        private bool IsLeft(Point_qt p1, Point_qt p2, Point_qt p3)
        {
            double x_12 = p2.X - p1.X;
            double y_12 = p2.Y - p1.Y;

            double x_13 = p3.X - p1.X;
            double y_13 = p3.Y - p1.Y;

            if ((x_12 * y_13 - y_12 * x_13) < 0)
            {
                return(false);
            }
            else
            {
                return(true);
            }
        }
        /// <summary>
        /// 根据QTGeometry里的点集构建顺序list
        /// </summary>
        /// <returns></returns>
        private List <Point_qt> GetSortedList()
        {
            List <Point_qt> list = PutPoints2List();

            if ((list[0].X - list[list.Count - 1].X) < 0.000001 && (list[0].Y - list[list.Count - 1].Y) < 0.000001)
            {
                list.RemoveAt(0);
            }
            SortByX(ref list);
            orPnt = list[0];                //选出X值最小的点
            list.Remove(orPnt);             //移除orPnt;

            SetListPntAng(orPnt, ref list); //给list里边的Point赋角度值
            SortByAngl(ref list);           //list按角度排序
            DeleSameAng(ref list);          //筛选list中角度相同的点

            return(list);
        }
        public List <Point_qt> GetSMBR()
        {
            Point_qt        p1   = new Point_qt();
            Point_qt        p2   = new Point_qt();
            Point_qt        p3   = new Point_qt();
            Point_qt        p4   = new Point_qt();
            List <Point_qt> list = new List <Point_qt>();

            Edge_qt edge = GetBestEdge();

            p1 = CalcPnt_Coor(edge.minX, edge.FromNode, edge.ToNode);
            p2 = CalcPnt_Coor(edge.MaxX, edge.FromNode, edge.ToNode);
            p3 = ReferencePoint_Clock(edge.MaxY, p2, p1);
            p4 = ReferencePoint_unClock(edge.MaxY, p1, p2);

            list.Add(p1);
            list.Add(p2);
            list.Add(p3);
            list.Add(p4);
            return(list);
        }