Esempio n. 1
0
        /// <summary>
        ///将初始三角形上的各条射线组成射线管模型
        /// </summary>
        ///  <param name="oneRayModels">单射线模型</param>
        /// <returns>射线管模型</returns>
        private Stack <RayTubeModel> GetDivisionModesFromInitialRays(List <OneRayModel>[] oneRayModels)
        {
            Stack <RayTubeModel> triangleUnits = new Stack <RayTubeModel>();

            for (int i = 0; i < oneRayModels.Length - 1; i++)//得到正立的三角面射线管
            {
                for (int j = 0; j < oneRayModels[i].Count; j++)
                {
                    RayTubeModel param = new RayTubeModel(new List <OneRayModel> {
                        oneRayModels[i][j], oneRayModels[i + 1][j],
                        oneRayModels[i + 1][j + 1]
                    }, this.tx.Position);
                    triangleUnits.Push(param);
                }
            }
            if (oneRayModels.Length > 2)//若三角形平分大于2层,得到倒立的三角面射线管
            {
                for (int m = 3; m < oneRayModels.Length; m++)
                {
                    for (int n = 1; n < oneRayModels[m].Count - 1; n++)
                    {
                        RayTubeModel param = new RayTubeModel(new List <OneRayModel> {
                            oneRayModels[m][n], oneRayModels[m - 1][n - 1],
                            oneRayModels[m - 1][n]
                        }, this.tx.Position);
                        triangleUnits.Push(param);
                    }
                }
            }
            return(triangleUnits);
        }
Esempio n. 2
0
        /// <summary>
        ///根据根节点及其子节点的信息,获得路径
        /// </summary>
        /// <param name="root">根节点</param>
        ///  <param name="allPaths">路径List</param>
        ///  <param name="nodes">节点List</param>
        /// <returns></returns>
        private void GetPathsFromFatherNodes(List <Path> allPaths, RayTubeModel reachedTube, ReceiveBall rxBall)
        {
            List <Node> reverseNodes = new List <Node>();
            Node        rx           = new Node
            {
                Position            = rxBall.Receiver,
                RxNum               = rxBall.RxNum,
                UAN                 = rxBall.UAN,
                NodeStyle           = NodeStyle.Rx,
                DistanceToFrontNode = reachedTube.OneRayModels[0].LaunchNode.Position.GetDistance(rxBall.Receiver),
                RayIn               = reachedTube.OneRayModels[0].LaunchRay,
                FatherNode          = reachedTube.OneRayModels[0].LaunchNode
            };

            reverseNodes.Add(rx);
            reverseNodes.Add((Node)reachedTube.OneRayModels[0].LaunchNode.Clone());
            while (reachedTube.FatherRayTube != null)
            {
                reverseNodes.Add((Node)reachedTube.FatherRayTube.OneRayModels[0].LaunchNode.Clone());
                reachedTube = reachedTube.FatherRayTube;
            }
            List <Node> nodes = new List <Node>();

            for (int i = reverseNodes.Count - 1; i >= 0; i--)
            {
                nodes.Add(reverseNodes[i]);
            }
            allPaths.Add(new Path(nodes));
        }
Esempio n. 3
0
        /// <summary>
        ///初始阶段细分正二十面体一个三角面,得到多个射线管模型
        /// </summary>
        /// <param name="tx">发射机</param>
        /// <param name="originModel">初始射线管</param>
        /// <param name="tessellationFrequency">镶嵌次数,等于三角形每条边的细分次数</param>
        /// <returns>射线管模型</returns>
        private Stack <RayTubeModel> GetInitialRayTubeModels(Node tx, RayTubeModel originModel, int tessellationFrequency)
        {
            Point       vertex1              = originModel.OneRayModels[0].LaunchRay.GetPointOnRayVector(10); //取三角形的顶点
            Point       vertex2              = originModel.OneRayModels[1].LaunchRay.GetPointOnRayVector(10); //三角形的顶点
            Point       vertex3              = originModel.OneRayModels[2].LaunchRay.GetPointOnRayVector(10); //三角形的顶点
            RayInfo     rayFromVertex1To2    = new RayInfo(vertex1, new SpectVector(vertex1, vertex2));       //顶点1到2的射线
            SpectVector vectorFromVertex2To3 = new SpectVector(vertex2, vertex3);                             //顶点2到3的射线
            double      unitLength           = vertex1.GetDistance(vertex2) / tessellationFrequency;          //每段的距离

            Point[] pointOfEdge12 = new Point[tessellationFrequency];                                         //存放棱12上的点,不包括顶点1
            for (int i = 0; i < tessellationFrequency; i++)                                                   //按间隔在棱12上去点
            {
                pointOfEdge12[i] = rayFromVertex1To2.GetPointOnRayVector((i + 1) * unitLength);
            }
            List <Point>[] vertexPoints = new List <Point> [tessellationFrequency + 1];//存放三角形内每条平行边上的点
            vertexPoints[0] = new List <Point> {
                vertex1
            };                                               //把顶点1放到数组第一位
            for (int j = 1; j <= tessellationFrequency; j++) //得到三角形切分后每条边上的点
            {
                vertexPoints[j] = this.GetPointListAtRayVectorByLength(vectorFromVertex2To3, pointOfEdge12[j - 1], unitLength, j);
                vertexPoints[j].Insert(0, pointOfEdge12[j - 1]);
            }
            List <OneRayModel>[] newRays       = this.GetDivisionRaysByVertices(tx, tessellationFrequency, vertexPoints); //根据得到的点构造射线
            Stack <RayTubeModel> rayTubeModels = this.GetDivisionModesFromInitialRays(newRays);                           //得到初始追踪完的三角形处理单元

            return(rayTubeModels);
        }
Esempio n. 4
0
        /// <summary>
        ///获得处理单元及其细分单元中的射线
        /// </summary>
        /// <param name="rayTubeModels">射线管的栈</param>
        /// <param name="ter">地形</param>
        /// <param name="rxBall">接收球</param>
        ///  <param name="buildings">建筑物</param>
        /// <returns></returns>
        private List <Path> GetPathsFromRayTubeModels(Stack <RayTubeModel> rayTubeModels, Terrain ter, ReceiveBall rxBall, City buildings)
        {
            if (rayTubeModels == null || rayTubeModels.Count == 0)
            {
                LogFileManager.ObjLog.error("在追踪处理射线管模型时,输入参数为0或者空");
                return(new List <Path>());
            }
            double lengthX = ter.MaxX - ter.MinX;
            double lengthY = ter.MaxY - ter.MinY;
            List <RayTubeModel> allReachedTubes = new List <RayTubeModel>();

            while (rayTubeModels.Count != 0)
            {
                RayTubeModel paramModel = rayTubeModels.Pop();
                paramModel.UpdateTheReveivedFlag(ter, rxBall, buildings); //更新是否到达接收机标记位,并返回接收机节点,若
                if (!paramModel.IsReachingRx)                             //若没有到达接收机
                {
                    if (paramModel.HaveTraced)                            //射线管已完成与地形,建筑物的求交计算
                    {
                        this.HandleTheRayTubeModel(paramModel, rayTubeModels, lengthX, lengthY);
                    }
                    else//该处理单元还未进行与地形,建筑物的求交计算
                    {
                        paramModel.TracingThisRayTubeModel(ter, buildings);//射线求交
                        this.HandleTheRayTubeModel(paramModel, rayTubeModels, lengthX, lengthY);
                    }
                    //Console.WriteLine(rayTubeModels.Count);
                    //if (rayTubeModels.Count > 1300)
                    //{
                    //    int a = 1;
                    //}
                }
                else
                {
                    allReachedTubes.Add(paramModel);
                    if (paramModel.HaveTraced)//射线管已完成与地形,建筑物的求交计算
                    {
                        this.HandleTheRayTubeModel(paramModel, rayTubeModels, lengthX, lengthY);
                    }
                    else//该处理单元还未进行与地形,建筑物的求交计算
                    {
                        paramModel.TracingThisRayTubeModel(ter, buildings);//射线求交
                        this.HandleTheRayTubeModel(paramModel, rayTubeModels, lengthX, lengthY);
                    }
                }
            }
            List <Path> paths = this.GetReceivedPaths(allReachedTubes, rxBall);

            return(paths);
        }
Esempio n. 5
0
        /// <summary>
        /// 判断射线管是否包含虚拟接收点,将包含的点转化为节点,并将节点存储在list中
        /// </summary>
        /// <param name="currentRayTube">射线管</param>
        /// <param name="virtualRxPoint">接收点</param>
        /// <param name="crossNodeInArea">存储相交节点</param>
        /// <returns></returns>
        private void GetAreaNodeIfRayTubeContainPoint(RayTubeModel currentRayTube, AreaNode virtualRxNode, List <Node> pathNodes)
        {
            SpaceFace    verticalFace = new SpaceFace(virtualRxNode.Position, new SpectVector(0, 0, 1));//作一个态势平面,态势层是平行于xoy的矩形
            List <Point> crossPoints  = new List <Point>();

            for (int i = 0; i < currentRayTube.OneRayModels.Count; i++)//求射线管与该平面的交点
            {
                Point crossPoint = currentRayTube.OneRayModels[i].LaunchRay.GetCrossPointWithFace(verticalFace);
                if (crossPoint != null)
                {
                    crossPoints.Add(crossPoint);
                }
            }
            if (crossPoints.Count != 3)
            {
                LogFileManager.ObjLog.error("判断射线管是否与态势层存在交点时出错");
            }
            else
            {
                Face wavefrontFace = new Triangle(crossPoints[0], crossPoints[1], crossPoints[2]);
                if (wavefrontFace.JudgeIfPointInFace(virtualRxNode.Position))                                         ////判断射线管是否包含当前态势点
                {
                    OneRayModel rayModelToRx = currentRayTube.StructureRayModelToTargetPoint(virtualRxNode.Position); //??
                    if (rayModelToRx == null)
                    {
                        LogFileManager.ObjLog.error("判断点是否在从绕射棱发出的射线管内时,构造到接收机的射线时出错");
                    }
                    else
                    {
                        //当前射线管包含态势点,可以生成路径啦~\(≧▽≦)/~
                        //构造接收节点
                        virtualRxNode.RxNum               = 1;
                        virtualRxNode.NodeStyle           = NodeStyle.Rx;
                        virtualRxNode.DistanceToFrontNode = rayModelToRx.LaunchNode.Position.GetDistance(virtualRxNode.Position);
                        virtualRxNode.RayIn               = rayModelToRx.LaunchRay;
                        virtualRxNode.FatherNode          = rayModelToRx.LaunchNode;
                        for (int i = 0; i < currentRayTube.OneRayModels.Count; i++)
                        {
                            currentRayTube.OneRayModels[i].LaunchNode.ChildNodes.Add(virtualRxNode);
                        }
                        virtualRxNode.FatherNode = currentRayTube.OneRayModels[0].LaunchNode;
                        pathNodes.Add(virtualRxNode);                        //得到从发射节点到态势点的完整的路径节点
                        Path onePath = new Path(new List <Node>(pathNodes)); //生成一条新的路径
                        virtualRxNode.paths.Add(onePath);
                        pathNodes.RemoveAt(pathNodes.Count - 1);
                    }
                }
            }
        }
Esempio n. 6
0
        /// <summary>
        /// 获取与态势相交的射线管
        /// </summary>
        /// <param name="rayTubeModels">存放射线管的栈</param>
        /// <param name="ter">地形</param>
        /// <param name="reArea">态势区域</param>
        /// <param name="buildings">建筑物</param>
        /// <returns>按态势层的次序存放与态势层相交的射线管</returns>
        private void GetRayTubesCrossWithAreaSituation(List <RayTubeModel>[] tubesCrossWithAreaSituation, Stack <RayTubeModel> rayTubeModels, Terrain ter, ReceiveArea reArea, City buildings)
        {
            if (rayTubeModels == null || rayTubeModels.Count == 0)
            {
                LogFileManager.ObjLog.error("在追踪处理射线管模型时,输入参数为0或者空");
            }
            double lengthX = ter.MaxX - ter.MinX;
            double lengthY = ter.MaxY - ter.MinY;

            while (rayTubeModels.Count != 0)
            {
                RayTubeModel paramModel = rayTubeModels.Pop();          //从栈中抛出一个射线管进行处理
                if (!paramModel.HaveTraced)                             //判断射线管是否已完成与地形,建筑物的求交计算过程
                {
                    paramModel.TracingThisRayTubeModel(ter, buildings); //进行射线求交
                }
                //对射线管进行处理,包括是否细分、是否到达态势区域、是否满足截止条件
                this.HandleTheRayTubeModel(paramModel, rayTubeModels, reArea, tubesCrossWithAreaSituation, lengthX, lengthY);
            }
        }
Esempio n. 7
0
        /// <summary>
        ///对一个射线管进行处理
        /// </summary>
        /// <param name="paramModel">射线管</param>
        ///  <param name="rayTubeModels">射线管的栈</param>
        /// <returns></returns>
        private void HandleTheRayTubeModel(RayTubeModel paramModel, Stack <RayTubeModel> rayTubeModels, ReceiveArea reArea, List <RayTubeModel>[] newRayTubes,
                                           double lengthX, double lengthY)
        {
            if (paramModel.JudgeIfThisModelNeedToBeDivided())//判断射线管是否需要进行细分
            {
                int divisionNum = paramModel.GetDivisionNumOfLine(lengthX, lengthY);
                List <RayTubeModel> newModels = paramModel.GetDivisionRayTubeModels(divisionNum);//细分后的射线管模型,将细分后的射线管压入栈中
                for (int i = 0; i < newModels.Count; i++)
                {
                    rayTubeModels.Push(newModels[i]);//加入栈中
                }
            }
            else//射线管不需要细分
            {
                //进入此环节的射线管已经完成了与地面和建筑物的求交计算,并且射线管不需要再细分
                //判断射线管有没有到达态势区域
                paramModel.UpdateAreaSituationFlag(reArea);                  //判断射线管有没有到达态势区域
                if (paramModel.IsReachingArea)                               //若射线管到达态势区域
                {
                    for (int i = 0; i < paramModel.crossLayerNum.Count; i++) //依次读取当前射线管中crossLayerNum的信息
                    {
                        int num = paramModel.crossLayerNum[i];
                        newRayTubes[num].Add((RayTubeModel)paramModel.Clone());//将射线管添加到对应的newRayTubes中
                    }
                }

                if (paramModel.ReflectionTracingTimes + paramModel.DiffractionTracingTimes >= 4 ||
                    paramModel.DiffractionTracingTimes >= 2)     //判断射线管是否满足截止条件
                {
                    return;
                }
                else//获取射线管下一阶段的射线管模型
                {
                    List <RayTubeModel> nextModels = paramModel.GetNextRayTubeModels();//下一阶段射线管模型
                    for (int i = 0; i < nextModels.Count; i++)
                    {
                        rayTubeModels.Push(nextModels[i]);//加入栈中
                    }
                }
            }
        }
Esempio n. 8
0
 /// <summary>
 ///对一个射线管进行处理
 /// </summary>
 /// <param name="paramModel">射线管</param>
 ///  <param name="rayTubeModels">射线管的栈</param>
 /// <returns></returns>
 private void HandleTheRayTubeModel(RayTubeModel paramModel, Stack <RayTubeModel> rayTubeModels, double lengthX, double lengthY)
 {
     if (paramModel.JudgeIfThisModelNeedToBeDivided())//若射线管需要进行细分
     {
         int divisionNum = paramModel.GetDivisionNumOfLine(lengthX, lengthY);
         List <RayTubeModel> newModels = paramModel.GetDivisionRayTubeModels(divisionNum);//细分后的射线管模型
         for (int i = 0; i < newModels.Count; i++)
         {
             if (newModels[i].OneRayModels[0].LaunchNode.Position != null && newModels[i].OneRayModels[1].LaunchNode.Position != null &&
                 newModels[i].OneRayModels[2].LaunchNode.Position != null)
             {
                 rayTubeModels.Push(newModels[i]);//加入栈中
                 //CalLog.LogForCal.WriteMsg(newModels[i].OneRayModels[0].LaunchNode.Position.X.ToString("0.#######E+00")
                 //    + "***" + newModels[i].OneRayModels[0].LaunchNode.Position.Y.ToString("0.#######E+00") + "***"
                 //    + newModels[i].OneRayModels[0].LaunchNode.Position.Z.ToString("0.#######E+00") + "////" + "3");
             }
         }
     }
     else//射线管不需要细分
     {
         if (paramModel.ReflectionTracingTimes + paramModel.DiffractionTracingTimes >= 4 ||
             paramModel.DiffractionTracingTimes >= 2 || paramModel.PassTracingTimes >= 10)   //若射线管满足截止条件
         {
             return;
         }
         else//获取射线管下一阶段的射线管模型
         {
             List <RayTubeModel> nextModels = paramModel.GetNextRayTubeModels();//下一阶段射线管模型
             for (int i = 0; i < nextModels.Count; i++)
             {
                 if (nextModels[i].OneRayModels[0].LaunchNode.Position != null && nextModels[i].OneRayModels[1].LaunchNode.Position != null &&
                     nextModels[i].OneRayModels[2].LaunchNode.Position != null)
                 {
                     rayTubeModels.Push(nextModels[i]);//加入栈中
                 }
             }
         }
     }
 }
Esempio n. 9
0
 /// <summary>
 /// 根据打到态势层上的射线管信息,获取从发射点到当前射线管的路径
 /// </summary>
 /// <param name="currentRayTube">当前射线管</param>
 /// <param name="nodes">从发射点到当前射线管的节点链表</param>
 private void GetFrontNodesOfAreaSituationNodes(RayTubeModel currentRayTube, List <Node> nodes)
 {
     //nodes.Add((Node)root.Clone());
     if (currentRayTube.FatherRayTube != null)
     {
         for (int i = 0; i < currentRayTube.OneRayModels.Count; i++)
         {
             if (currentRayTube.OneRayModels[i].LaunchNode.FatherNode != null)
             {
                 nodes.Insert(0, (Node)currentRayTube.OneRayModels[i].LaunchNode.Clone());
                 this.GetFrontNodesOfAreaSituationNodes(currentRayTube.FatherRayTube, nodes);
                 break;
             }
         }
     }
     else if (currentRayTube.OneRayModels[0].LaunchNode.NodeStyle == NodeStyle.Tx)
     {
         nodes.Insert(0, (Node)currentRayTube.OneRayModels[0].LaunchNode.Clone());
     }
     else
     {
         LogFileManager.ObjLog.debug("求当前节点的父节点时出错!\n");
     }
 }