//求散点子集的凸包
        private IPositionSet solveHelp(IPosition p1, IPosition p2, IPositionSet ps)
        {
            //求离p1,p2最远的点
            ps.InitToTraverseSet();
            if (!ps.NextPosition())
            {
                return(ps);
            }
            IPosition p3   = ps.GetPosition();
            double    p3_h = getH(p1, p2, p3);
            PositionSetEdit_ImplementByICollectionTemplate rest = new PositionSetEdit_ImplementByICollectionTemplate();

            while (ps.NextPosition())
            {
                IPosition pt   = ps.GetPosition();
                double    pt_h = getH(p1, p2, pt);
                if (pt_h > p3_h)
                {
                    rest.AddPosition(p3);
                    p3   = pt;
                    p3_h = pt_h;
                }
                else
                {
                    rest.AddPosition(pt);
                }
            }

            //把散点分成几部分
            PositionSetEdit_ImplementByICollectionTemplate leftpart  = new PositionSetEdit_ImplementByICollectionTemplate();
            PositionSetEdit_ImplementByICollectionTemplate rightpart = new PositionSetEdit_ImplementByICollectionTemplate();
            PositionSetEdit_ImplementByICollectionTemplate p1set     = new PositionSetEdit_ImplementByICollectionTemplate();
            PositionSetEdit_ImplementByICollectionTemplate p2set     = new PositionSetEdit_ImplementByICollectionTemplate();

            ps = rest;
            IPosition p11        = new Position_Point(2 * p2.GetX() - p1.GetX(), 2 * p2.GetY() - p1.GetY()); //p1关于p2的对称点
            double    leftangle  = getAngle(p1, p2, p3);
            double    rightangle = getAngle(p2, p11, p3);

            ps.InitToTraverseSet();
            while (ps.NextPosition())
            {
                IPosition p = ps.GetPosition();
                if (p.GetX() == p1.GetX() && p.GetY() == p1.GetY())
                {
                    p1set.AddPosition(p);
                }
                else if (p.GetX() == p2.GetX() && p.GetY() == p2.GetY())
                {
                    p2set.AddPosition(p);
                }
                else if (p.GetX() == p3.GetX() && p.GetY() == p3.GetY())
                {
                    leftpart.AddPosition(p);
                }
                else
                {
                    double a = getAngle(p1, p2, p);
                    if (a > leftangle)
                    {
                        leftpart.AddPosition(p);
                    }
                    a = getAngle(p2, p11, p);
                    if (a < rightangle)
                    {
                        rightpart.AddPosition(p);
                    }
                }
            }

            //对子集求解
            IPositionSet subResult1 = solveHelp(p1, p3, leftpart);
            IPositionSet subResult2 = solveHelp(p3, p2, rightpart);

            //合并各部分解
            PositionSetEdit_ImplementByICollectionTemplate result = new PositionSetEdit_ImplementByICollectionTemplate();

            p1set.InitToTraverseSet();
            while (p1set.NextPosition())
            {
                result.AddPosition(p1set.GetPosition());
            }

            subResult1.InitToTraverseSet();
            while (subResult1.NextPosition())
            {
                result.AddPosition(subResult1.GetPosition());
            }

            result.AddPosition(p3);

            subResult2.InitToTraverseSet();
            while (subResult2.NextPosition())
            {
                result.AddPosition(subResult2.GetPosition());
            }

            p2set.InitToTraverseSet();
            while (p2set.NextPosition())
            {
                result.AddPosition(p2set.GetPosition());
            }

            return(result);
        }