/// <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); }
/// <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)); }
/// <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); }
/// <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); }
/// <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); } } } }
/// <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); } }
/// <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]);//加入栈中 } } } }
/// <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]);//加入栈中 } } } } }
/// <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"); } }