/// <summary>
        /// 构造RRT树上的路径
        /// </summary>
        /// <param name="mRrtTree">从中选择路径的树</param>
        /// <returns>路径</returns>
        protected List <RrtStarNode> BuildPath(HashSet <RrtStarNode> mRrtTree)
        {
            //如果树为空,则返回空
            if ((null == mRrtTree))
            {
                return(null);
            }

            //选取并存储路径
            int                targetNodeIndex = mRrtTree.Max(e => e.NodeIndex);
            RrtStarNode        mTempNode       = mRrtTree.First(e => e.NodeIndex == targetNodeIndex);
            List <RrtStarNode> mTempRrtPath    = new List <RrtStarNode>();

            //循环搜索
            while (mTempNode.ParentNode != null)
            {
                //增加节点
                mTempRrtPath.Add(mTempNode);
                //递增
                mTempNode = mTempNode.ParentNode;
            }
            mTempRrtPath.Add(mTempNode);//实际上是初始节点

            //由于是按照倒序添加,这里将顺序反转
            mTempRrtPath.Reverse();

            //返回值
            return(mTempRrtPath);
        }
 /// <summary>
 /// 计算两个节点之间的距离
 /// </summary>
 /// <param name="mNode1">节点1</param>
 /// <param name="mNode2">节点2</param>
 /// <returns></returns>
 public double DistanceBetweenTwoNode(RrtStarNode mNode1, RrtStarNode mNode2)
 {
     //二维算法使用
     return(FPoint3.DistanceBetweenTwoSpacePointsXY(mNode1.NodeLocation, mNode2.NodeLocation));
     //三维算法使用
     //return FPoint3.DistanceBetweenTwoSpacePoints(mNode1.NodeLocation, mNode2.NodeLocation);
 }
        /// <summary>
        /// 深度搜索更新Childnode 的costfunc
        /// </summary>
        /// <param name="node"></param>
        protected void UpdateChildnodeCostFunc(RrtStarNode node)
        {
            //不论如何都要更新的事情
            if (node.ParentNode != null)
            {
                node.CostFuncValue = node.ParentNode.CostFuncValue + MLineCostFunc(node.ParentNode, node);
            }

            //检查子类是否需要更新
            if (node.ChildNodes == null)
            {
                return;
            }
            else if (node.ChildNodes.Count == 0)
            {
                return;
            }
            else if (node.ChildNodes.Count > 0)
            {
                foreach (var childnode in node.ChildNodes)
                {
                    UpdateChildnodeCostFunc(childnode);
                }
            }
        }
 private void SetDeleted(RrtStarNode topNode)
 {
     topNode.IsAbandoned = true;
     foreach (var item in topNode.ChildNodes)
     {
         SetDeleted(item);
     }
 }
        /// <summary>
        /// 扩展树算法
        /// </summary>
        /// <param name="mRrtStarTree"></param>
        /// <param name="mRrtNearNode"></param>
        /// <param name="mRrtNewSteerNode"></param>
        public void ExpandTree(ref HashSet <RrtStarNode> mRrtStarTree, RrtStarNode mRrtNearNode, RrtStarNode mRrtNewSteerNode, int index)
        {
            //设置是否到达目标的标志
            //bool isReachTarget = false;
            //保存Steer节点信息
            if (mRrtNewSteerNode != null)
            {
                //设置节点编号
                mRrtNewSteerNode.NodeIndex = index;
                //设置父节点
                mRrtNewSteerNode.ParentNode = mRrtNearNode;
                //增加新节点
                mRrtStarTree.Add(mRrtNewSteerNode);
            }
            //创建Near集合
            HashSet <RrtStarNode> nearNodes   = NearNeighbors(ref mRrtStarTree, mRrtNewSteerNode);
            RrtStarNode           minCostNode = mRrtNearNode;
            double minCost = minCostNode.CostFuncValue + MLineCostFunc(minCostNode, mRrtNewSteerNode);

            //记录初始化父节点
            mRrtNewSteerNode.ParentNode = minCostNode;
            //记录初始化最优minCost参数
            mRrtNewSteerNode.CostFuncValue = minCost;

            //寻找安全的Cost函数最小值
            foreach (var node in nearNodes)
            {
                if (_isSafeLine(mRrtNewSteerNode.NodeLocation, node.NodeLocation) && _isSafePoint(mRrtNewSteerNode.NodeLocation) &&
                    node.CostFuncValue + MLineCostFunc(node, mRrtNewSteerNode) < minCost)
                {
                    minCostNode = node;
                    minCost     = node.CostFuncValue + MLineCostFunc(node, mRrtNewSteerNode);
                    //记录父节点
                    mRrtNewSteerNode.ParentNode = minCostNode;
                    //记录临时最优minCost参数
                    mRrtNewSteerNode.CostFuncValue = minCost;
                }
            }

            //更新父节点的childlist
            mRrtNewSteerNode.ParentNode.ChildNodes.Add(mRrtNewSteerNode);
            //Rewrite the tree!
            foreach (var node in nearNodes)
            {
                if (_isSafeLine(mRrtNewSteerNode.NodeLocation, node.NodeLocation) && _isSafePoint(mRrtNewSteerNode.NodeLocation) &&
                    mRrtNewSteerNode.CostFuncValue + MLineCostFunc(mRrtNewSteerNode, node) < node.CostFuncValue)
                {   //新创立的节点可能会影响tree的最优性,所以需要重写局部的连接情况
                    //去掉与原父节点的联系
                    node.ParentNode.ChildNodes.Remove(node);
                    //添加与新父节点的联系
                    node.ParentNode = mRrtNewSteerNode;
                    mRrtNewSteerNode.ChildNodes.Add(node);
                    //更新字节点的costfunc
                    UpdateChildnodeCostFunc(node);
                }
            }
        }
        public void BranchAndBound(ref HashSet <RrtStarNode> mFinalNodeSet, ref HashSet <RrtStarNode> mRrtStarTree)
        {
            var         targetNode   = RrtStarNode.ConvertUavStateToNode(_mInput.UAVTask[ITaskIndex].Stages[IStageIndex].TargetState);
            var         minCost      = mFinalNodeSet.Min(e => e.CostFuncValue + MLineCostFunc(e, targetNode));
            RrtStarNode mOptimalNode = mFinalNodeSet.FirstOrDefault(e => e.CostFuncValue + MLineCostFunc(e, targetNode) == minCost);

            if (mOptimalNode == null)   //default
            {
                return;
            }

            //foreach(var item in mRRTStarTree.Where(e => e.IsValid == true)) //寻找mFinalNodeSet相同内容
            foreach (var item in mFinalNodeSet)
            {
                if (item.NodeIndex == mOptimalNode.NodeIndex)
                {
                    continue;
                }
                //跳过最优值,剩下的都删了

                //TODO
                //Step 1. Find out the GGGGGrandParent that should be abandoned.

                var         topNodeParent = item;
                RrtStarNode topNode       = item; //TopNode的子节点, item 一定是 abandoned 的节点。
                while (topNodeParent.CostFuncValue + MLineCostFunc(topNodeParent, targetNode) > minCost)
                {
                    if (topNodeParent.ParentNode != null)
                    {
                        topNode       = topNodeParent;
                        topNodeParent = topNodeParent.ParentNode;
                    }
                    else
                    {
                        break;
                    }
                }

                //Step 2. Delete ChildNode reference
                if (topNode.ParentNode != null)
                {
                    topNode.ParentNode.ChildNodes.Remove(topNode);
                }

                //Step 3. Set All child as abandoned
                SetDeleted(topNode);
            }

            //Step Finally. Delete! Them! All!
            mRrtStarTree.RemoveWhere(e => e.IsAbandoned);

            mFinalNodeSet.Clear();
            mFinalNodeSet.Add(mOptimalNode);
        }
        /// <summary>
        /// 在探测范围内随机生成一个节点
        /// </summary>
        /// <returns>RRTStarNode</returns>
        private RrtStarNode RandomConfigurationOrigin()
        {
            RrtStarNode mRrtRandNode = new RrtStarNode();

            mRrtRandNode.NodeLocation.X = _mRandom.NextDouble() * _mInput.Scenario.FlightScene.Coordinate.MaxX;
            mRrtRandNode.NodeLocation.Y = _mRandom.NextDouble() * _mInput.Scenario.FlightScene.Coordinate.MaxY;
            mRrtRandNode.NodeLocation.Z = _mInput.Scenario.UAVGroup.GetUAV(_mInput.UAVTask[ITaskIndex].Index).StartState.PointLocation.Z; //m_RRTParameter.MissionAltitude;
            mRrtRandNode.ParentNode     = null;

            //
            return(mRrtRandNode);
        }
        public void MarkingValid(RrtStarNode mRrtCurrentNode, ref HashSet <RrtStarNode> finalNodeSet)
        {
            var targetNode = RrtStarNode.ConvertUavStateToNode(_mInput.UAVTask[ITaskIndex].Stages[IStageIndex].TargetState);

            //路径连通而且距离不长
            if (_isSafeLine(mRrtCurrentNode.NodeLocation, targetNode.NodeLocation))
            //&& DistanceBetweenTwoNode(mRRTCurrentNode, TargetNode) <= RRTParameter.Error)
            {
                //打上 Valid标记(gradually模式用)
                mRrtCurrentNode.IsValid = true;
                finalNodeSet.Add(mRrtCurrentNode);
            }
        }
        /// <summary>
        /// 计算新的节点
        /// </summary>
        /// <param name="mRrtNearNode">距离mRRTRandNode最近的节点</param>
        /// <param name="mRrtRandNode">随机生成的节点</param>
        /// <returns></returns>
        public RrtStarNode Steer(RrtStarNode mRrtNearNode, RrtStarNode mRrtRandNode)
        {
            RrtStarNode mRrtNewNode = new RrtStarNode();

            if (DistanceBetweenTwoNode(mRrtNearNode, mRrtRandNode) <= MRrtParameter.Step)
            {
                mRrtNewNode = mRrtRandNode;
            }
            else
            {
                //生成新点
                mRrtNewNode = NewNode(MRrtParameter.Step, mRrtNearNode, mRrtRandNode);
            }
            return(mRrtNewNode);
        }
        /// <summary>
        /// 计算新的节点
        /// </summary>
        /// <param name="fStep">步长</param>
        /// <param name="mRrtNearNode">距离mRRTRandNode最近的节点</param>
        /// <param name="mRrtRandNode">随机生成的节点</param>
        /// <returns></returns>
        protected RrtStarNode NewNode(double fStep, RrtStarNode mRrtNearNode, RrtStarNode mRrtRandNode)
        {
            //Alex 2018.09.18 修复错误
            //随便吐槽
            //不知道和妹子还能在一起多久,不过还是有点心塞吧。
            RrtStarNode mRrtNewNode = new RrtStarNode();

            mRrtNewNode.NodeLocation.X = mRrtNearNode.NodeLocation.X + (fStep * (mRrtRandNode.NodeLocation.X - mRrtNearNode.NodeLocation.X)) / DistanceBetweenTwoNode(mRrtNearNode, mRrtRandNode);
            mRrtNewNode.NodeLocation.Y = mRrtNearNode.NodeLocation.Y + (fStep * (mRrtRandNode.NodeLocation.Y - mRrtNearNode.NodeLocation.Y)) / DistanceBetweenTwoNode(mRrtNearNode, mRrtRandNode);
            mRrtNewNode.NodeLocation.Z = _mInput.Scenario.UAVGroup.GetUAV(_mInput.UAVTask[ITaskIndex].Index).StartState.PointLocation.Z; //m_RRTParameter.MissionAltitude;

            //DirectionGenerationMethod(mRRTRandNode, mRRTNearNode, mRRTNewNode, fStep);


            return(mRrtNewNode);
        }
        private RrtStarNode BiasRandomConfiguration()
        {
            //新节点
            RrtStarNode mRrtNode = null;

            //是否直接把目标点当作新点
            if (_mRandom.NextDouble() > MRrtParameter.ChooseTargetThreshold)
            {
                mRrtNode = RandomConfigurationOrigin();
            }
            else
            {
                mRrtNode = RrtStarNode.ConvertUavStateToNode(_mInput.UAVTask[ITaskIndex].Stages[IStageIndex].TargetState);
            }

            //
            return(mRrtNode);
        }
        /// <summary>
        /// 寻找树mRRTTree中距离mRRTRandNode最近的节点
        /// </summary>
        /// <param name="mRrtTree">RRT树</param>
        /// <param name="mRrtRandNode">随机生成的节点</param>
        /// <returns></returns>
        public RrtStarNode NearestNeighbor(HashSet <RrtStarNode> mRrtTree, RrtStarNode mRrtRandNode)
        {
            RrtStarNode mRrtNearNode = new RrtStarNode();
            double      fMinDistance = double.MaxValue;
            double      fDistance    = 0;

            foreach (RrtStarNode mRrtNode in mRrtTree)
            {
                fDistance = DistanceBetweenTwoNode(mRrtRandNode, mRrtNode);
                if (fDistance <= fMinDistance)
                {
                    mRrtNearNode = mRrtNode;
                    fMinDistance = fDistance;
                }
            }
            //
            return(mRrtNearNode);
        }
        /// <summary>
        /// 判断新结点到目标连线是否安全, 若安全则直接连接目标点
        /// </summary>
        /// <param name="iTaskIndex">无人机/任务编号</param>
        /// <param name="iStageIndex">阶段编号</param>
        /// <param name="mRrtCurrentNode">当前节点</param>
        /// <param name="mRrtTree">RRT</param>
        /// <returns>1,是否有效(安全); 2,如果有效(安全),是否到达目标</returns>
        public bool DirectlyToTarget(RrtStarNode mRrtCurrentNode, ref HashSet <RrtStarNode> mRrtTree)
        {
            bool isReachTarget = false;

            //进一步判断新结点到目标连线是否安全, 若安全则直接连接目标点
            if (_isSafeLine(mRrtCurrentNode.NodeLocation, _mInput.UAVTask[ITaskIndex].Stages[IStageIndex].TargetState.Location))
            {
                //设置为到达
                isReachTarget = true;
                //设置目标点为最后一个新结点, 并将当前节点设置为她的父节点
                mRrtCurrentNode = RrtStarNode.ConvertUavStateToNode(_mInput.UAVTask[ITaskIndex].Stages[IStageIndex].TargetState, mRrtCurrentNode);
                //设节点编号
                mRrtCurrentNode.NodeIndex = mRrtTree.Count;
                //增加新节点
                mRrtTree.Add(mRrtCurrentNode);
            }

            return(isReachTarget);
        }
        public void GraduallyToTarget(int count, ref HashSet <RrtStarNode> mRrtTree)
        {
            //当count < MaxNodeNumber 的木一个值时有可能之前被 continue掉,所以不能这么写
            //所以应该取count == m_RRTParameter.MaxNodeNumber并在最终异常部分处理
            //判断mRRTCurrentNode是不是有效的.

            var         targetNode = RrtStarNode.ConvertUavStateToNode(_mInput.UAVTask[ITaskIndex].Stages[IStageIndex].TargetState);
            var         finalCost  = mRrtTree.Where(e => e.IsValid).Min(e => e.CostFuncValue + MLineCostFunc(e, targetNode));
            RrtStarNode finalNode  = mRrtTree.FirstOrDefault(e => e.CostFuncValue + MLineCostFunc(e, targetNode) == finalCost);

/*
 *          var TargetNode = RRTStarNode.ConvertUAVStateToNode(m_Input.UAVTask[iTaskIndex].Stages[iStageIndex].TargetState);
 *          RRTStarNode FinalNode = null;
 *          double FinalCost = double.MaxValue;
 *          //寻找最短路径
 *          foreach (var tmpNode in mRRTTree)
 *          {
 *              if (tmpNode.IsValid)
 *              {
 *                  var tmpCost = tmpNode.CostFuncValue + mLineCostFunc(tmpNode, TargetNode);
 *                  if (tmpCost < FinalCost)
 *                  {
 *                      FinalCost = tmpCost;
 *                      FinalNode = tmpNode;
 *                  }
 *              }
 *          }*/

            if (finalNode == null)
            {
                ConstructFailedPath(ref mRrtTree);
            }
            else
            {
                //设置目标点为最后一个新结点, 并将当前节点设置为她的父节点
                var mRrtFinalNode = RrtStarNode.ConvertUavStateToNode(_mInput.UAVTask[ITaskIndex].Stages[IStageIndex].TargetState, finalNode);
                //设节点编号
                mRrtFinalNode.NodeIndex = count;
                //增加新节点
                mRrtTree.Add(mRrtFinalNode);
            }
        }
        private void UpdateTreeNode(RrtStarNode currentNode, ref List <MyTreeNode> resultList)
        {
            MyTreeNode tmp = new MyTreeNode();

            tmp.NodeLocation  = currentNode.NodeLocation;
            tmp.Direction     = double.MinValue;
            tmp.CostFuncValue = currentNode.CostFuncValue;
            tmp.Index         = currentNode.NodeIndex;

            if (currentNode.ParentNode == null)
            {
                tmp.ParentNode = null;
            }
            else
            {
                tmp.ParentNode = resultList.First(e => e.Index == currentNode.ParentNode.NodeIndex);
            }
            resultList.Add(tmp);

            foreach (var node in currentNode.ChildNodes)
            {
                UpdateTreeNode(node, ref resultList);
            }
        }
 /// <summary>
 /// 本DEMO中给出的目标函数的定义,以最短距离为最优目标
 /// </summary>
 /// <param name="lNode"></param>
 /// <param name="rNode"></param>
 /// <returns></returns>
 protected double CostFunc(RrtStarNode lNode, RrtStarNode rNode)
 {
     return(FPoint3.DistanceBetweenTwoSpacePointsXY(lNode.NodeLocation, rNode.NodeLocation));
 }
        /// <summary>
        /// 为单架无人机规划航迹
        /// </summary>
        /// <param name="iTaskIndex">无人机/任务索引</param>
        /// <returns></returns>
        protected virtual MPath BuildPathForSingleUav(int iTaskIndex)
        {
            //实例化航路
            MPath mPath = new MPath();

            mPath.Index     = AlgoInput.UAVTask[iTaskIndex].Index;
            mPath.Waypoints = new List <MWaypoint>();
            int iWaypointIndex = 0;
            //基本RRT函数库
            RrtStarHelper helper = null;

            //定义树
            HashSet <RrtStarNode> mRrtStarTree = null;
            //定义航路
            List <RrtStarNode> mRrtPath = null;
            //定义树节点
            RrtStarNode mRrtNode = null;
            //定义树中间节点
            RrtStarNode mRrtRandNode     = null;
            RrtStarNode mRrtNearNode     = null;
            RrtStarNode mRrtNewSteerNode = null;

            HashSet <RrtStarNode> mFinalNodeSet = null;

            //计数器
            int nCount = 1;

            //对每一个阶段规划航路
            for (int iStageIndex = 0; iStageIndex < AlgoInput.UAVTask[iTaskIndex].Stages.Count; ++iStageIndex)
            {
                //初始化函数库
                helper = new RrtStarHelper(MRandom, MRrtParameter, iTaskIndex, iStageIndex, AlgoInput, IsSafePoint, IsSafeLine);
                //加载委托函数
                helper.MLineCostFunc += CostFunc;

                //实例化
                mRrtStarTree  = new HashSet <RrtStarNode>();
                mFinalNodeSet = new HashSet <RrtStarNode>();

                //初始化计数器
                nCount = 1;

                //加入开始点为第一个点
                mRrtNode = new RrtStarNode(0, AlgoInput.UAVTask[iTaskIndex].Stages[iStageIndex].StartState.Location, nCount, null);
                mRrtStarTree.Add(mRrtNode);


                //是否到达目标 - 初始未到达
                bool isReachTarget = false;


                //循环构建新点 - 到达目标时自动退出
                while (!isReachTarget)
                {
                    //-------------------------------随机生成节点--------------------------------//
                    //随机生成节点
                    mRrtRandNode = helper.RandomConfiguration(mFinalNodeSet.Count == 0);
                    //-----------------------------------end-------------------------------------//

                    //----------------------------搜索距离最近的节点-----------------------------//
                    mRrtNearNode = helper.NearestNeighbor(mRrtStarTree, mRrtRandNode);
                    //-----------------------------------end-------------------------------------//

                    //------------------------------延伸生成新节点-------------------------------//
                    mRrtNewSteerNode = helper.Steer(mRrtNearNode, mRrtRandNode);
                    //-----------------------------------end-------------------------------------//

                    //计数器累加
                    nCount = nCount + 1;

                    //-----------------------如果到达允许的搜索上限,则退出-----------------------//
                    if (nCount >= MRrtParameter.MaxNodeNumber)
                    {
                        Console.WriteLine("MaxNodeNumber!");
                        break;
                    }
                    //-----------------------------------end-------------------------------------//

                    //------------------------------扩展树 - 核心--------------------------------//
                    if (IsSafeLine(mRrtNewSteerNode.NodeLocation, mRrtNearNode.NodeLocation) && IsSafePoint(mRrtNewSteerNode.NodeLocation))
                    {
                        //此处SteerNode已经添加到Tree中
                        helper.ExpandTree(ref mRrtStarTree, mRrtNearNode, mRrtNewSteerNode, nCount);
                    }
                    else
                    {
                        continue;
                    }

                    //-----------------------------------end-------------------------------------//



                    //------------判断新结点到目标连线是否安全, 若安全则直接连接目标点-----------//
                    if (MRrtParameter.ReachMode == TargetReachMode.Direct)
                    {
                        isReachTarget = isReachTarget || helper.DirectlyToTarget(mRrtNewSteerNode, ref mRrtStarTree);
                    }
                    else if (MRrtParameter.ReachMode == TargetReachMode.Gradual)
                    {
                        helper.MarkingValid(mRrtNewSteerNode, ref mFinalNodeSet);
                    }
                    //-----------------------------------end-------------------------------------//


                    //----------------------------Branch and Bound-------------------------------//
                    if (mFinalNodeSet.Count > 10)
                    {
                        helper.BranchAndBound(ref mFinalNodeSet, ref mRrtStarTree);
                    }
                    //-----------------------------------end-------------------------------------//
                }
                if (nCount >= MRrtParameter.MaxNodeNumber)
                {
                    if (MRrtParameter.ReachMode == TargetReachMode.Direct)
                    {
                        helper.ConstructFailedPath(ref mRrtStarTree);
                    }
                    else if (MRrtParameter.ReachMode == TargetReachMode.Gradual)
                    {
                        //GraduallyToTarget方法就是检查当 nCount == m_RRTParameter.MaxNodeNumber 时的结果
                        //所以在本部分需要为IsVailid添加标签。
                        helper.GraduallyToTarget(nCount, ref mRrtStarTree);
                    }
                }
                mRrtPath = BuildPath(mRrtStarTree);


                //为可视化输出保存
                _visualization.MPathForVisualizaition = mRrtStarTree.ToList();
                if (!PathPlaningDataVisualization.PathPlaningDataVisualization.AlgoDataDict.ContainsKey(mPath.Index.ToString() + "-" + iStageIndex.ToString()))
                {
                    //为ResultShowForm分析窗口保存数据
                    //3.30.2018 刘洋添加
                    PathPlaningDataVisualization.PathPlaningDataVisualization.AlgoDataDict.Add(mPath.Index.ToString() + "-" + iStageIndex.ToString(), _visualization.MyTreeNodeConverter(_visualization.MPathForVisualizaition));
                }
                else
                {
                    PathPlaningDataVisualization.PathPlaningDataVisualization.AlgoDataDict[mPath.Index.ToString() + "-" + iStageIndex.ToString()] = _visualization.MyTreeNodeConverter(_visualization.MPathForVisualizaition);
                }


                //添加当前阶段航路到总航路(起始航路点为当前阶段, 目标航路点为下一个阶段, 注意总航路的最后一个航路点属于最后一个阶段)
                for (int k = 0; k < mRrtPath.Count - 1; ++k)
                {
                    mPath.Waypoints.Add(new MWaypoint(iWaypointIndex, RrtStarNode.ConvertNodeToUavState(mRrtPath[k]), iStageIndex));
                    iWaypointIndex = iWaypointIndex + 1;
                }
            }
            //增加最后的目标点
            mPath.Waypoints.Add(new MWaypoint(iWaypointIndex, RrtStarNode.ConvertNodeToUavState(mRrtPath[mRrtPath.Count - 1]),
                                              AlgoInput.UAVTask[iTaskIndex].Stages.Count - 1));

            //返回路径
            return(mPath);
        }
        /// <summary>
        /// 寻找SteerNode 的附近节点
        /// </summary>
        /// <param name="mRrtStarTrees"></param>
        /// <param name="steerNode"></param>
        /// <returns></returns>
        public HashSet <RrtStarNode> NearNeighbors(ref HashSet <RrtStarNode> mRrtStarTrees, RrtStarNode steerNode)
        {
            double Tolerance = 10E-7;
            //原始算法测试结果
            //double radiusConst = m_RRTParameter.Step*1.1;
            //double radius = Math.Max(m_RRTParameter.FixedNearDistanceRatio * Math.Pow(Math.Log(2, mRRTStarTrees.Count) / mRRTStarTrees.Count, 1.0 / 2), radiusConst);

            double radius = MRrtParameter.Step * MRrtParameter.FixedNearDistanceRatio;

            HashSet <RrtStarNode> resultSet = new HashSet <RrtStarNode>();

            resultSet.Clear();

            /*
             * //并行操作优化
             * //貌似会慢1S左右。。。。。
             * ResultSet = mRRTStarTrees.AsParallel().Where(node => DistanceBetweenTwoNode(node, SteerNode) <= radius && node != SteerNode).ToHashSet();
             */

            foreach (var node in mRrtStarTrees)
            {
                if (DistanceBetweenTwoNode(node, steerNode) <= radius && node != steerNode)
                {
                    resultSet.Add(node);
                }
            }


            if (resultSet.Count > MRrtParameter.TriggerNum && MRrtParameter.NearNodesFilter)
            {
                var query        = resultSet.GroupBy(e => e.ParentNode);
                var tmpResultSet = new HashSet <RrtStarNode>();
                foreach (var group in query)
                {
                    var minDis  = group.Min(e => e.CostFuncValue + DistanceBetweenTwoNode(e, steerNode));
                    var minNode = group.First(e => Math.Abs((e.CostFuncValue + DistanceBetweenTwoNode(e, steerNode)) - minDis) <= Tolerance);
                    tmpResultSet.Add(minNode);
                }

//                var tmpResultSet = new HashSet<RrtStarNode>();
//                foreach (var item in resultSet)
//                {
//                    if(item.ParentNode != null)
//                        tmpResultSet.Add(item.ParentNode);
//                }
//                if(tmpResultSet.Count != 0)
//                    resultSet = tmpResultSet;
            }

            return(resultSet);
        }