public static void GetRxTotalPower(List <CalculateModelClasses.Path> Paths, string sPath, string projectName, int txIndex, int txTotol, ReceiveBall rxballtemp, Point txpotemp) { ReceiveBall Rxball = rxballtemp; string Rxname = Rxball.RxName; string groupnum = Convert.ToString(Rxball.RxNum); if (Rxball.RxNum < 10) { groupnum = "0" + groupnum; } FileStream fs = new FileStream(sPath + projectName + "_power" + "_t00" + txIndex + "_0" + txTotol + "_" + "total" + "_r0" + groupnum + ".p2m", FileMode.Create);//如果是接收区域的话,多个接收点组成一组接收机组成一个编号 StreamWriter sw = new StreamWriter(fs); if (Paths.Count != 0) { OutputRxPower(Paths[0].node[Paths[0].node.Count - 1], Rxname, Power.GetTotalPowerInDifferentPhase(Paths), txpotemp.GetDistance(rxballtemp.Receiver)); } else { double distance = Rxball.Receiver.GetDistance(txpotemp); sb.AppendLine("# Receiver Set:" + Rxname); sb.AppendLine("# Rx# X(m) Y(m) Z(m) Distance (m) Power (dBm) Phase (Deg.)"); sb.AppendLine(" " + 1 + " " + Rxball.Receiver.X.ToString("0.#######E+00") + " " + Rxball.Receiver.Y.ToString("0.#######E+00") + " " + Rxball.Receiver.Z.ToString("f3") + " " + distance.ToString("f2") + " " + "-250.00" + " " + "0.00"); } sw.Write(sb); sb.Clear(); sw.Close(); fs.Close(); }
//StringBuilder sb = new StringBuilder(); public static void OutPath(List <CalculateModelClasses.Path> Paths, string sPath, string projectName, int txIndex, int txTotol, ReceiveBall rxballtemp, Point txpotemp, int Frequence, int minFrequence, int maxFrequence)//需要提供一个接受区域所有路径的信息 { ReceiveBall Rxball = rxballtemp; string Rxname = Rxball.RxName; string groupnum = Convert.ToString(Rxball.RxNum); if (Rxball.RxNum < 10) { groupnum = "0" + groupnum; } //sPath += projectName; FileStream fs = new FileStream(sPath + projectName + "_pl" + "_t00" + txIndex + "_0" + txTotol + "_" + Frequence.ToString("D4") + "_" + minFrequence.ToString("D4") + "_" + maxFrequence.ToString("D4") + "_r0" + groupnum + ".p2m", FileMode.Create);//如果是接收区域的话,多个接收点组成一组接收机组成一个编号 StreamWriter sw = new StreamWriter(fs); if (Paths.Count != 0) { OutputRxPathLoss(Paths[0].node[Paths[0].node.Count - 1], Rxname, GetPassLoss(Paths), txpotemp.GetDistance(rxballtemp.Receiver)); } else { double totaldistance = Rxball.Receiver.GetDistance(txpotemp); sb.AppendLine("# Receiver Set:" + Rxname); sb.AppendLine("# Rx# X(m) Y(m) Z(m) Distance (m) Path Loss (dB)"); sb.AppendLine(" " + 1 + " " + Rxball.Receiver.X.ToString("0.#######E+00") + " " + Rxball.Receiver.Y.ToString("0.#######E+00") + " " + Rxball.Receiver.Z.ToString("f3") + " " + totaldistance.ToString("f2") + " " + "250.00"); } sw.Write(sb); sb.Clear(); sw.Close(); fs.Close(); }
/// <summary> ///追踪处理单元中的射线 /// </summary> private void TracingUnitRay(RayTracingModel unit, Node tx, Terrain ter, ReceiveBall rxBall, City cityBuilding, List <FrequencyBand> txFrequencyBand) { double rayBeamAngle = unit.AngleOfRayBeam * Math.PI / 180; //追踪射线1 if (unit.FirstRay.WhetherHaveTraced == false)//若该射线之前还没有追踪 { RayInfo newRay = new RayInfo(unit.FirstRay.Origin, unit.FirstRay.SVector); List <Path> pathtemp = this.GetSingleRayPaths(tx, ter, rxBall, cityBuilding, newRay, rayBeamAngle, txFrequencyBand); unit.FirstRay.Flag = this.JudgeIfArriveRx(pathtemp); unit.FirstRay.Path = pathtemp; unit.FirstRay.WhetherHaveTraced = true; } //追踪射线2 if (unit.SecondRay.WhetherHaveTraced == false)//若该射线之前还没有追踪 { RayInfo newRay = new RayInfo(unit.SecondRay.Origin, unit.SecondRay.SVector); List <Path> pathtemp = this.GetSingleRayPaths(tx, ter, rxBall, cityBuilding, newRay, rayBeamAngle, txFrequencyBand); unit.SecondRay.Flag = this.JudgeIfArriveRx(pathtemp); unit.SecondRay.Path = pathtemp; unit.FirstRay.WhetherHaveTraced = true; } //追踪射线3 if (unit.ThirdRay.WhetherHaveTraced == false)//若该射线之前还没有追踪 { RayInfo newRay = new RayInfo(unit.ThirdRay.Origin, unit.ThirdRay.SVector); List <Path> pathtemp = this.GetSingleRayPaths(tx, ter, rxBall, cityBuilding, newRay, rayBeamAngle, txFrequencyBand); unit.ThirdRay.Flag = this.JudgeIfArriveRx(pathtemp); unit.ThirdRay.Path = pathtemp; unit.FirstRay.WhetherHaveTraced = true; } unit.HaveTraced = true; return; }
/// <summary> ///初始阶段在每个三角形上发出一定的射线 /// </summary> /// <param name="tx">发射机</param> /// <param name="ter">地形</param> /// <param name="rxBall">接收球</param> /// <param name="cityBuilding">建筑物</param> /// <param name="unit">射线处理单元</param> /// <param name="TessellationFrequency">镶嵌次数,等于三角形每条边的细分次数</param> /// <param name="divideAngle">射线束夹角</param> /// <param name="TxFrequencyBand">发射机频段信息</param> /// <returns></returns> private List <RayTracingModel> GetInitialTrianglePath(Node tx, Terrain ter, ReceiveBall rxBall, City cityBuilding, RayTracingModel unit, int TessellationFrequency, double divideAngle, List <FrequencyBand> txFrequencyBand) { Point vertex1 = new Point(unit.FirstRay.SVector); //三角形的顶点 Point vertex2 = new Point(unit.SecondRay.SVector); //三角形的顶点 Point vertex3 = new Point(unit.ThirdRay.SVector); //三角形的顶点 SpectVector vector12 = new SpectVector(vertex1, vertex2); SpectVector vector23 = new SpectVector(vertex2, vertex3); double length = vertex1.GetDistance(vertex2) / TessellationFrequency; //每段的距离 Point[] pointOfEdge12 = new Point[TessellationFrequency]; //存放棱上的点,不包括顶点1 // p1[0] = vertex1; for (int i = 0; i < TessellationFrequency; i++) { pointOfEdge12[i] = new Point(vertex1.X + (i + 1) * (vector12.a / Math.Sqrt(Math.Pow(vector12.a, 2) + Math.Pow(vector12.b, 2) + Math.Pow(vector12.c, 2)) * length), vertex1.Y + (i + 1) * (vector12.b / Math.Sqrt(Math.Pow(vector12.a, 2) + Math.Pow(vector12.b, 2) + Math.Pow(vector12.c, 2)) * length), vertex1.Z + (i + 1) * (vector12.c / Math.Sqrt(Math.Pow(vector12.a, 2) + Math.Pow(vector12.b, 2) + Math.Pow(vector12.c, 2)) * length)); } List <Point>[] vertexPoints = new List <Point> [TessellationFrequency + 1];//存放三角形内每条平行边上的点 vertexPoints[0] = new List <Point> { vertex1 }; //把顶点1放到数组第一位 for (int j = 1; j <= TessellationFrequency; j++) //得到三角形切分后每条边上的点 { vertexPoints[j] = new List <Point>(); vertexPoints[j].Add(pointOfEdge12[j - 1]); this.GetTriangleInternalEdgePoint(vector23, pointOfEdge12[j - 1], length, j, vertexPoints[j]); } List <ClassNewRay>[] raysPath = this.GetEachTriangleRay(tx, ter, rxBall, cityBuilding, TessellationFrequency, divideAngle, txFrequencyBand, vertexPoints); //根据得到的点构造射线 List <RayTracingModel> triangleUnits = this.HandleInitialRayToUnit(raysPath); //得到初始追踪完的三角形处理单元 return(triangleUnits); }
// private static int index2 = 0; // private static List<string> strListTemp = new List<string>(); /// <summary> /// 输出P2M格式的path文件 /// </summary> /// <param name="gridPath">一个发射机和一组接收机所有的路径信息</param> /// <param name="Rxname">接收机的名字(点接收机还是区域接收机)</param> /// <param name="groupnum">这组接收机是第几组</param> public static void OutPath(List <CalculateModelClasses.Path> Paths, string sPath, string projectName, int txIndex, int txTotol, ReceiveBall rxballtemp, Point txpotemp, int Frequence, int minFrequence, int maxFrequence)//需要提供一个接受区域所有路径的信息<加上输入路径参数和工程名> { if (Paths.Count != 0) { ReceiveBall Rxball = rxballtemp; string Rxname = Rxball.RxName; string groupnum = Convert.ToString(Rxball.RxNum); if (Rxball.RxNum < 10) { groupnum = "0" + groupnum; } FileStream fs = new FileStream(sPath + projectName + "_paths" + "_t00" + txIndex + "_0" + txTotol + "_" + Frequence.ToString("D4") + "_" + minFrequence.ToString("D4") + "_" + maxFrequence.ToString("D4") + "_r0" + groupnum + ".p2m", FileMode.Create);//如果是接收区域的话,多个接收点组成一组接收机组成一个编号 StreamWriter sw = new StreamWriter(fs); OutEveryRxPath(Paths, Rxname, 1); sw.Write(sb); sb.Clear(); sw.Close(); fs.Close(); } else { ReceiveBall Rxball = rxballtemp; string groupnum = Convert.ToString(Rxball.RxNum); if (Rxball.RxNum < 10) { groupnum = "0" + groupnum; } FileStream fs = new FileStream(sPath + "PathOutputNull" + "_t00" + txIndex + "_r0" + groupnum + "_" + Frequence.ToString("D4") + "_" + minFrequence.ToString("D4") + "_" + maxFrequence.ToString("D4") + ".p2m", FileMode.Append); StreamWriter sw = new StreamWriter(fs); sw.Close(); fs.Close(); } }
/// <summary> ///进行射线追踪 /// </summary> public List <Node> GetCrossNodes(Terrain ter, ReceiveBall rxBall, City buildings, double rayBeamAngle) { List <Rectangle> shadowRect = ter.lineRect(this.inRay); //记录射线在俯视图投影经过的矩形 Node crossWithTer = this.inRay.GetCrossNodeWithTerrainRects(shadowRect); //记录射线与地形交点、与源点距离、所在面 Node CrossWithReceive = rxBall.GetCrossNodeWithRxBall(this.inRay); //记录射线与接收球交点 Node CrossWithTerEdge = this.inRay.GetCrossNodeWithTerDiffractionEdge(shadowRect, this.fatherNode.RayTracingDistance, rayBeamAngle); //记录射线与地形绕射边的交点,绕射等信息 Node crossWithCity = buildings.GetReflectionNodeWithCity(this.inRay); //记录射线与建筑物交点、与源点距离、所在面 Node CrossWithCityEdge = buildings.GetDiffractionNodeWithBuildings(this.inRay, this.fatherNode.RayTracingDistance, rayBeamAngle); //记录射线与建筑物绕射边的交点,绕射等信息 //把所有交点放到一个list中 if (crossWithTer != null) { this.crossNodes.Add(crossWithTer); } if (CrossWithReceive != null) { this.crossNodes.Add(CrossWithReceive); } if (crossWithCity != null) { this.crossNodes.Add(crossWithCity); } if (CrossWithTerEdge != null) { this.crossNodes.Add(CrossWithTerEdge); } if (CrossWithCityEdge != null) { this.crossNodes.Add(CrossWithCityEdge); } if (crossNodes.Count == 0) { return(crossNodes); } else if (crossNodes.Count == 1) { return(new List <Node> { this.crossNodes[0] }); } else { //若交点大于两个,排序 for (int i = 0; i < this.crossNodes.Count - 1; i++) { for (int j = i + 1; j < this.crossNodes.Count; j++) { if (this.crossNodes[j].DistanceToFrontNode > this.crossNodes[j + 1].DistanceToFrontNode) { Node param = this.crossNodes[j]; this.crossNodes[j] = this.crossNodes[j + 1]; this.crossNodes[j + 1] = param; } } } return(new List <Node> { this.crossNodes[0] }); } }
public static ReceiveBall Instance() { if (instance == null) { instance = new ReceiveBall(); } return(instance); }
private void Awake() { if (instance == null) { instance = this; } else if (instance != this) { Destroy(this.gameObject); } DontDestroyOnLoad(this.gameObject); }
/// <summary> ///求射线与地形,接收球,建筑物的交点,并将交点按照与源点距离进行排序 /// </summary> /// <param name="oneRay">射线</param> /// <param name="rxBall">接收球</param> /// <param name="ter">地形</param> /// <param name="cityBuilding">建筑物</param> /// <param name="TxFrequencyBand">发射机频段信息</param> /// <param name="multiple">绕射圆柱体半径倍数</param> /// <returns>返回交点</returns> private List <Node> GetCrossPointsWithEnvironment(ReceiveBall rxBall, Terrain ter, City cityBuilding, List <FrequencyBand> txFrequencyBand, double multiple) { Node crossWithTer = this.inRay.GetCrossNodeWithTerrainRects(this.terShadowRects); //记录射线与地形交点、与源点距离、所在面 Node CrossWithReceive = rxBall.GetCrossNodeWithRxBall(this.inRay); //记录射线与接收球交点 List <Node> CrossWithTerEdge = this.GetCrossNodeWithTerDiffractionEdge(txFrequencyBand, multiple); //记录射线与地形绕射边的交点,绕射等信息 Node crossWithCity = cityBuilding.GetReflectionNodeWithCity(this.inRay); //记录射线与建筑物交点、与源点距离、所在面 List <Node> CrossWithCityEdge = cityBuilding.GetDiffractionNodeWithCity(this.inRay, txFrequencyBand, multiple); //记录射线与建筑物绕射边的交点,绕射等信息 //把所有交点放到一个list中 List <Node> crossNodes = new List <Node> (); if (crossWithTer != null) { crossNodes.Add(crossWithTer); } if (CrossWithReceive != null) { crossNodes.Add(CrossWithReceive); } if (crossWithCity != null) { crossNodes.Add(crossWithCity); } if (CrossWithTerEdge.Count != 0) { crossNodes.AddRange(CrossWithTerEdge); } if (CrossWithCityEdge.Count != 0) { crossNodes.AddRange(CrossWithCityEdge); } // if (crossNodes.Count > 1)//若交点个数大于2,进行排序 { for (int i = 0; i < crossNodes.Count - 1; i++) { for (int j = 0; j < crossNodes.Count - i - 1; j++) { if (crossNodes[j].DistanceToFrontNode > crossNodes[j + 1].DistanceToFrontNode) { Node param = crossNodes[j]; crossNodes[j] = crossNodes[j + 1]; crossNodes[j + 1] = param; } } } } // this.DeleteSameNode(crossNodes); return(crossNodes); }
/// <summary> ///得到Rx节点,并加入child节点的子节点List中 /// </summary> private void SetRxChildNode(Node childNode, Node rxNode, ReceiveBall rxBall) { rxNode.LayNum = childNode.LayNum + 1; rxNode.DiffractionNum = childNode.DiffractionNum; rxNode.IsReceiver = true; rxNode.IsEnd = true; rxNode.RxNum = rxBall.RxNum; rxNode.RayTracingDistance = childNode.RayTracingDistance; rxNode.RayTracingDistance += rxNode.DistanceToFrontNode; rxNode.NodeName = rxBall.RxName; rxNode.RayIn = this.inRay; rxNode.UAN = rxBall.UAN; rxNode.Position = rxBall.Receiver; childNode.ChildNodes.Add(rxNode); }
/// <summary> ///全向静态发射射线 /// </summary> /// <param name="currentNode">节点</param> /// <param name="ter">地形</param> /// <param name="rxBall">接收球</param> /// <param name="cityBuilding">建筑物</param> /// <param name="TessellationFrequency">细分点个数</param> /// <param name="TxFrequencyBand">发射机频段信息</param> /// <returns></returns> private List <Path> LaunchRaysOmnidirectional(Node tx, ReceiveBall rxBall, Terrain ter, City cityBuilding, int TessellationFrequency, List <FrequencyBand> txFrequencyBand) { RayInfo directRay = new RayInfo(tx.Position, rxBall.Receiver); Node directCrossNode = directRay.GetCrossNodeWithTerrainRects(ter.lineRect(new RayInfo(rxBall.Receiver, new SpectVector(tx.Position, rxBall.Receiver)))); if (directCrossNode != null && directCrossNode.DistanceToFrontNode < tx.Position.GetDistance(rxBall.Receiver))//若直射被阻挡 { DirectCrossNode = directCrossNode; } List <Path> pathInfo = new List <Path>(); List <RayTracingModel> originUnits = GetOriginUnitsOfIcosahedron(tx); this.HandleEachSurface(originUnits, pathInfo, tx, rxBall, ter, cityBuilding, TessellationFrequency, txFrequencyBand); return(pathInfo); }
/// <summary> ///求从辐射源发出的一条射线的所有路径 /// </summary> private List <Path> GetSingleRayPaths(Node tx, Terrain ter, ReceiveBall rxBall, City cityBuilding, RayInfo inRay, double rayBeamAngle, List <FrequencyBand> txFrequencyBand) { // Point test = new AdjacentEdge(new Point(-1111.08, -3527.01, 5000), new Point(-1111.08, 5563.65, 5000), new SpectVector(new Point(-1111.08, -3527.01, 5000), new Point(-1111.08, 5563.65, 5000))).GetDiffractionPoint(tx.Position,rxBall.Receiver); // inRay.RayVector = new SpectVector(tx.Position,test); PunctiformPath pathTracing = new PunctiformPath(inRay, ter); pathTracing.SetPunctiformRayPathNodes(tx, ter, rxBall, cityBuilding, rayBeamAngle, txFrequencyBand); List <Path> temp = new List <Path>(); if (tx.ChildNodes.Count != 0) { temp = this.GetLegalPaths(tx); tx.ChildNodes.Clear(); } return(temp); }
/// <summary> ///进行射线追踪 /// </summary> /// <param name="ter">地形</param> /// <param name="rxBall">接收球</param> /// <param name="buildings">建筑物</param> /// <param name="rayBeamAngle">射线束的夹角</param> /// <returns>交点</returns> public List <Node> GetCrossNodes(Terrain ter, ReceiveBall rxBall, City buildings, double rayBeamAngle) { //获取左右两条射线的追踪结果 List <Node> leftCrossNodes = new LineRay(this.leftRay, this.leftFatherNode).GetCrossNodes(ter, rxBall, buildings, rayBeamAngle); List <Node> rightCrossNodes = new LineRay(this.rightRay, this.leftFatherNode).GetCrossNodes(ter, rxBall, buildings, rayBeamAngle); //把结果放入Dictionary中 if (leftCrossNodes.Count == 0) { rayCrossNodes.Add(this.leftRay, null); } else { rayCrossNodes.Add(this.leftRay, leftCrossNodes[0]); } if (rightCrossNodes.Count == 0) { rayCrossNodes.Add(this.rightRay, null); } else { rayCrossNodes.Add(this.rightRay, rightCrossNodes[0]); } // HandleCrossNodes(this.luanchRay, this.rayCrossNodes, ter, rxBall, buildings, rayBeamAngle); //若射线面打到接收球上,其他交点舍去,不再追踪,同时把空的交点删去 List <Node> crossNodes = this.rayCrossNodes.Values.ToList(); for (int i = crossNodes.Count - 1; i >= 0; i--) { if (crossNodes[i] == null)//交点是null,删去 { crossNodes.RemoveAt(i); continue; } if (crossNodes[i].NodeStyle == NodeStyle.Rx) { return(new List <Node> { crossNodes[i] }); } } return(crossNodes); }
/// <summary> ///获取点状接收机的传播路径信息,功率和传播时延在路径筛选后计算 /// </summary> /// <param name="currentNode">节点</param> /// <param name="rxBall">接收球</param> /// <param name="cityBuilding">建筑物</param> /// <param name="rayBeamAngle">射线束的夹角</param> /// <param name="rays">射线</param> /// <param name="fatherNode">父节点,发射机则没有父节点</param> /// <returns></returns> public void SetPunctiformRayPathNodes(Node currentNode, Terrain ter, ReceiveBall rxBall, City cityBuilding, double rayBeamAngle, List <FrequencyBand> txFrequencyBand) { //设置接受球半径 double rxBallDistance = currentNode.Position.GetDistance(rxBall.Receiver) + currentNode.RayTracingDistance; double errorFactor = 1; // if (rayBeamAngle > 0.5 * Math.PI / 180) // { errorFactor = 2; } if (currentNode.NodeStyle == NodeStyle.DiffractionNode) { errorFactor = 2; } rxBall.Radius = errorFactor * rxBallDistance * rayBeamAngle / Math.Sqrt(3); //求交点 List <Node> crossNodes = GetCrossPointsWithEnvironment(rxBall, ter, cityBuilding, txFrequencyBand, errorFactor * 20); if (crossNodes.Count == 0)//若射线与各个物体都没有交点 { if (currentNode.NodeStyle != NodeStyle.Tx) { currentNode.IsEnd = true; } return; } else { for (int j = 0; j < crossNodes.Count; j++) { if (crossNodes[j].NodeStyle == NodeStyle.ReflectionNode)//若为反射点 { this.SetReflectionChildNode(currentNode, crossNodes[j], ter, cityBuilding, rxBall, rayBeamAngle, txFrequencyBand); break; } else if (crossNodes[j].NodeStyle == NodeStyle.CylinderCrossNode)//若为绕射点,追踪绕射绕射,并继续追踪下一个点 { this.GetDiffractionNode(currentNode, crossNodes[j], ter, cityBuilding, rxBall, rayBeamAngle, txFrequencyBand); } else//若为Rx点 { SetRxChildNode(currentNode, crossNodes[j], rxBall); break; } } } }
/// <summary> ///计算威胁度时,需要把其他的发射机也当接收机来算,从发射机文件中提取接收球 /// </summary> public static List <List <ReceiveBall> > GetTxAsRx(string txpath, string setup, string terpath) { List <List <ReceiveBall> > TxAsRxBalls = new List <List <ReceiveBall> >(); List <TxObject> txForRx = TxReader(txpath); for (int i = 0; i < txForRx.Count; i++) { Point lc = new Point(txForRx[i].Lc.vertical[0], txForRx[i].Lc.vertical[1], txForRx[i].Lc.vertical[2]); lc.Z = txForRx[i].Lc.vertical[2] + txForRx[i].cubesize; List <ReceiveBall> temp = new List <ReceiveBall>(); ReceiveBall rxtemp = new ReceiveBall(lc, txForRx[i].num, txForRx[i].name); // rxtemp.frequence = GetTxCarrierFrequence(txForRx[i], SetupFileProceed.GetSetupFile.GetSetup(setup)); // rxtemp.FrequenceWidth = GetWidth(txForRx[i], SetupFileProceed.GetSetupFile.GetSetup(setup)); rxtemp.UAN = ReadUan.GetUan(txForRx[i], SetupFileProceed.GetSetupFile.GetSetup(setup)); rxtemp.isTx = true; temp.Add(rxtemp); TxAsRxBalls.Add(temp); } return(TxAsRxBalls); }
/// <summary> ///获取所有射线的路径 /// </summary> /// <param name="ter">地形</param> /// <param name="rxBall">接收球</param> /// <param name="buildings">建筑物</param> /// <param name="firstN">初始细分点个数</param> /// <returns></returns> private List <Path> GetPunctiformRxPaths(ReceiveBall rxBall, Terrain ter, City buildings, int firstN) { List <Path> receivedPaths = new List <Path>(); List <RayTubeModel> originalUnits = this.GetOriginUnitsOfIcosahedron();//正二十面体的二十个三角面 LogFileManager.ObjLog.debug("test"); for (int i = 0; i < originalUnits.Count; i++) { Console.WriteLine(DateTime.Now); Stack <RayTubeModel> initialModels = this.GetInitialRayTubeModels(this.tx, originalUnits[i], firstN); receivedPaths.AddRange(this.GetPathsFromRayTubeModels(initialModels, ter, rxBall, buildings)); Console.WriteLine(DateTime.Now); } //Stack<RayTubeModel> initialModels = new Stack<RayTubeModel>(); //OneRayModel ray1 = new OneRayModel(this.tx,new RayInfo(this.tx.Position, new Point(-100, -20, 20))); //OneRayModel ray2 = new OneRayModel(this.tx,new RayInfo(this.tx.Position, new Point(-150, -40, 50))); //OneRayModel ray3 = new OneRayModel(this.tx,new RayInfo(this.tx.Position, new Point(-120, -10, 10))); //initialModels.Push(new RayTubeModel(new List<OneRayModel> { ray1, ray2, ray3 },tx.Position)); //receivedPaths.AddRange(this.GetPathsFromRayTubeModels(initialModels, ter, rxBall, buildings)); return(receivedPaths); }
/// <summary> ///获取所有射线的路径 /// </summary> /// <param name="currentNode">节点</param> /// <param name="ter">地形</param> /// <param name="rxBall">接收球</param> /// <param name="cityBuilding">建筑物</param> /// <param name="firstN">初始细分点个数</param> /// <param name="finalN">最终细分点个数</param> /// <param name="TxFrequencyBand">发射机频段信息</param> /// <returns></returns> private List <Path> GetPunctiformRxPath(Node tx, ReceiveBall rxBall, Terrain ter, City cityBuilding, int firstN, int finalN, List <FrequencyBand> txFrequencyBand) { RayInfo directRay = new RayInfo(tx.Position, rxBall.Receiver); Node directCrossNode = directRay.GetCrossNodeWithTerrainRects(ter.lineRect(new RayInfo(rxBall.Receiver, new SpectVector(tx.Position, rxBall.Receiver)))); if (directCrossNode != null && directCrossNode.DistanceToFrontNode < tx.Position.GetDistance(rxBall.Receiver))//若直射被阻挡 { DirectCrossNode = directCrossNode; } List <Path> pathInfo = new List <Path>(); List <RayTracingModel> originUnits = this.GetOriginUnitsOfIcosahedron(tx); //正二十面体的二十个三角面 double finalDivideAngle = this.GetInitialAngleOfRayBeam(finalN); //最终细分角度,弧度制 double firstDivideAngle = this.GetInitialAngleOfRayBeam(firstN); //最初细分角度,弧度制 for (int i = 0; i < originUnits.Count; i++) { List <RayTracingModel> firstUnits = this.GetInitialTrianglePath(tx, ter, rxBall, cityBuilding, originUnits[i], firstN, firstDivideAngle, txFrequencyBand); this.GetPathOfUnit(firstUnits, pathInfo, tx, ter, rxBall, cityBuilding, finalDivideAngle, txFrequencyBand); } return(pathInfo); }
/// <summary> ///得到正二十面体每个三角形初始细分时的所有射线 /// </summary> /// <param name="tx">发射机</param> /// <param name="ter">地形</param> /// <param name="rxBall">接收球</param> /// <param name="cityBuilding">建筑物</param> /// <param name="unit">射线处理单元</param> /// <param name="TessellationFrequency">镶嵌次数,等于三角形每条边的细分次数</param> /// <param name="divideAngle">射线束夹角</param> /// <param name="TxFrequencyBand">发射机频段信息</param> /// <returns></returns> private List <ClassNewRay>[] GetEachTriangleRay(Node tx, Terrain ter, ReceiveBall rxBall, City cityBuilding, int TessellationFrequency, double divideAngle, List <FrequencyBand> txFrequencyBand, List <Point>[] vertexPoints) { List <ClassNewRay>[] raysPath = new List <ClassNewRay> [TessellationFrequency + 1]; for (int m = 0; m < vertexPoints.Length; m++) { raysPath[m] = new List <ClassNewRay>(); for (int n = 0; n < vertexPoints[m].Count; n++) { ClassNewRay temp = new ClassNewRay();//每个点发射一条射线,并进行追踪 temp.Origin = tx.Position; SpectVector paramVector = new SpectVector(vertexPoints[m][n].X, vertexPoints[m][n].Y, vertexPoints[m][n].Z); RayInfo paramRay = new RayInfo(tx.Position, paramVector); List <Path> path = GetSingleRayPaths(tx, ter, rxBall, cityBuilding, paramRay, divideAngle, txFrequencyBand); temp.Flag = JudgeIfArriveRx(path); temp.Path = path; temp.SVector = paramVector; temp.WhetherHaveTraced = true; raysPath[m].Add(temp); } } return(raysPath); }
/// <summary> ///获取当左侧射线无交点,右侧射线有交点时的追踪交点 /// </summary> /// <param name="outRay">从射线面发出的射线</param> /// <param name="rayCrossNode">射线与交点的dictionary</param> /// <param name="ter">地形</param> /// <param name="rxBall">接收球</param> /// <param name="buildings">建筑物</param> /// <param name="rayBeamAngle">射线束的夹角</param> /// <returns></returns> private void GetCrossNodeWhenLeftFalseRightTrue(List <RayInfo> outRay, Dictionary <RayInfo, Node> rayCrossNode, Terrain ter, ReceiveBall rxBall, City buildings, double rayBeamAngle, ref int i) { //先求出两条射线经过的路径的编号个数的公共值 int minRectNum = (outRay[i].RectID.Count > outRay[i + 1].RectID.Count) ? outRay[i + 1].RectID.Count : outRay[i].RectID.Count; bool isDivided = false; for (int j = 0; j < minRectNum; j++)//进行遍历,如果有一个矩形不是相同或者相邻的话,说明射线面需要进行细分 { if (!(outRay[i].RectID[j].JudgeIsSameID(outRay[i + 1].RectID[j]) || outRay[i].RectID[j].JudgeIsAdjacent(outRay[i + 1].RectID[j]))) { isDivided = true; break; } } if (isDivided)//如果需要细分 { this.SetNewMiddleRay(outRay, rayCrossNode, ter, rxBall, buildings, rayBeamAngle, ref i); } else//如果不需要细分 { if (rayCrossNode[outRay[i]].NodeStyle == NodeStyle.ReflectionNode) { if (rayCrossNode[outRay[i]].ReflectionFace.FaceStyle == FaceType.Terrian) { } else { } } } }
/// <summary> ///返回接收球,如果是区域状则返回多个接收球 /// </summary> public static List <List <ReceiveBall> > GetRx(string rxpath, string setup, string terpath) { List <List <ReceiveBall> > RxBalls = new List <List <ReceiveBall> >(); List <RxObject> Rx = RxReader(rxpath); for (int i = 0; i < Rx.Count; i++) { //这是点状和区域状 if (Rx[i].flag != "<situation>") { if (Rx[i].flag.Equals("<points>")) { Point lc = new Point(Rx[i].Lc.vertical[0], Rx[i].Lc.vertical[1], Rx[i].Lc.vertical[2]); //GetZValue(ter, lc); lc.Z = Rx[i].Lc.vertical[2] + Rx[i].cubesize; List <ReceiveBall> temp = new List <ReceiveBall>(); ReceiveBall rxtemp = new ReceiveBall(lc, Rx[i].num, Rx[i].name); rxtemp.UAN = ReadUan.GetUan(Rx[i], SetupFileProceed.GetSetupFile.GetSetup(setup)); temp.Add(rxtemp); RxBalls.Add(temp); } else //现在不会进入这个分支 { List <ReceiveBall> temp = new List <ReceiveBall>(); double length = (double)Rx[i].Lc.side1; double width = (double)Rx[i].Lc.side2; double space = (double)Rx[i].Lc.spacing; for (int j = 0; j < width / space + 1; j++) { for (int k = 0; k < length / space + 1; k++) { Point lc = new Point(Rx[i].Lc.vertical[0] + k * space, Rx[i].Lc.vertical[1] - j * space, Rx[i].Lc.vertical[2]); //GetZValue(ter, lc); lc.Z += Rx[i].Lc.vertical[2] + Rx[i].cubesize; ReceiveBall rxtemp = new ReceiveBall(lc, Rx[i].num, Rx[i].name); rxtemp.UAN = ReadUan.GetUan(Rx[i], SetupFileProceed.GetSetupFile.GetSetup(setup)); temp.Add(new ReceiveBall(lc, Rx[i].num, Rx[i].name)); } } RxBalls.Add(temp); } } //这是态势显示 else { if ((double)Rx[i].Lc.side1 == 0 || (double)Rx[i].Lc.side2 == 0)//态势区域边长不能为0 { LogFileManager.ObjLog.debug("态势区域边长为0,出错"); } // Rx[i].Lc.spacing = 50; // Spacing = (double)Rx[i].Lc.spacing; List <ReceiveBall> temp = new List <ReceiveBall>(); ReceiveBall receiveArea = new ReceiveArea(); receiveArea.UAN = ReadUan.GetUan(Rx[i], SetupFileProceed.GetSetupFile.GetSetup(setup)); Point lc = new Point(Rx[i].Lc.vertical[0], Rx[i].Lc.vertical[1], Rx[i].Lc.vertical[2]); receiveArea.temp = Rx[i].Lc.vertical[2]; //GetZValue(ter, lc); lc.Z = Rx[i].Lc.vertical[2] + Rx[i].cubesize; //receiveArea.rxLength = (double)Rx[i].Lc.side1; //receiveArea.rxWidth = (double)Rx[i].Lc.side2; //receiveArea.spacing =(double)Rx[i].Lc.spacing; //receiveArea.origen = lc; receiveArea.Instance((double)Rx[i].Lc.side1, (double)Rx[i].Lc.side2, (double)Rx[i].Lc.spacing, lc); receiveArea.RxName = Rx[i].name; receiveArea.RxNum = Rx[i].num; temp.Add(receiveArea); RxBalls.Add(temp); } } return(RxBalls); }
/// <summary> ///获取当右侧射线无交点,左侧射线有交点时的追踪交点 /// </summary> /// <param name="outRay">从射线面发出的射线</param> /// <param name="rayCrossNode">射线与交点的dictionary</param> /// <param name="ter">地形</param> /// <param name="rxBall">接收球</param> /// <param name="buildings">建筑物</param> /// <param name="rayBeamAngle">射线束的夹角</param> /// <returns></returns> private void GetCrossNodeWhenLeftTrueRightFales(List <RayInfo> outRay, Dictionary <RayInfo, Node> rayCrossNode, Terrain ter, ReceiveBall rxBall, City buildings, double rayBeamAngle, ref int i) { int minRectNum = (outRay[i].RectID.Count > outRay[i + 1].RectID.Count) ? outRay[i + 1].RectID.Count : outRay[i].RectID.Count; bool isDivided = true; for (int j = 0; j < minRectNum; j++) { if (!(outRay[i].RectID[j].JudgeIsSameID(outRay[i + 1].RectID[j]) || outRay[i].RectID[j].JudgeIsAdjacent(outRay[i + 1].RectID[j]))) { isDivided = false; break; } } if (isDivided)//如果需要细分 { this.SetNewMiddleRay(outRay, rayCrossNode, ter, rxBall, buildings, rayBeamAngle, ref i); } else//如果不需要细分 { if (rayCrossNode[outRay[i + 1]].NodeStyle == NodeStyle.ReflectionNode) { } } }
/// <summary> ///获取当两侧射线都有交点时的追踪交点 /// </summary> /// <param name="outRay">从射线面发出的射线</param> /// <param name="rayCrossNode">射线与交点的dictionary</param> /// <param name="ter">地形</param> /// <param name="rxBall">接收球</param> /// <param name="buildings">建筑物</param> /// <param name="rayBeamAngle">射线束的夹角</param> /// <returns></returns> private void GetCrossNodeWhenTwoRaysTrue(List <RayInfo> outRay, Dictionary <RayInfo, Node> rayCrossNode, Terrain ter, ReceiveBall rxBall, City buildings, double rayBeamAngle, ref int i) { //两个交点都是反射点 if (rayCrossNode[outRay[i]].NodeStyle == NodeStyle.ReflectionNode && rayCrossNode[outRay[i]].NodeStyle == NodeStyle.ReflectionNode) { //是同一个反射面 if (rayCrossNode[outRay[i]].ReflectionFace.Equals(rayCrossNode[outRay[i + 1]].ReflectionFace)) { return; } else { if (rayCrossNode[outRay[i]].ReflectionFace.FaceStyle == FaceType.Terrian && rayCrossNode[outRay[i + 1]].ReflectionFace.FaceStyle == FaceType.Terrian) { if (rayCrossNode[outRay[i]].ReflectionFace.FaceID.JudgeIsSameID(rayCrossNode[outRay[i + 1]].ReflectionFace.FaceID)) { AdjacentEdge diffractionEdge = new AdjacentEdge(rayCrossNode[outRay[i]].ReflectionFace, rayCrossNode[outRay[i + 1]].ReflectionFace); Point diffractionPoint = new RayInfo(diffractionEdge.StartPoint, diffractionEdge.EndPoint).GetCrossPointWithFace(this.rayFace); if (diffractionEdge.JudgeIfPointInLineRange(diffractionPoint))//若绕射点在棱上 { RayInfo inRay = new RayInfo(this.launchPoint, diffractionPoint); Node lineNode = this.GetLineNode(inRay); Node diffractionNode = this.GetDiffractionNode(lineNode, diffractionPoint, diffractionEdge); rayCrossNode.Add(inRay, diffractionNode); i++; } } else { this.SetNewMiddleRay(outRay, rayCrossNode, ter, rxBall, buildings, rayBeamAngle, ref i); } } else if (rayCrossNode[outRay[i]].ReflectionFace.FaceStyle == FaceType.Terrian && rayCrossNode[outRay[i + 1]].ReflectionFace.FaceStyle == FaceType.Building) { } else if (rayCrossNode[outRay[i]].ReflectionFace.FaceStyle == FaceType.Building && rayCrossNode[outRay[i + 1]].ReflectionFace.FaceStyle == FaceType.Terrian) { } else { } } } //一个交点是反射点,一个交点是绕射点 else if (rayCrossNode[outRay[i]].NodeStyle == NodeStyle.ReflectionNode && rayCrossNode[outRay[i]].NodeStyle == NodeStyle.DiffractionNode) { } //一个交点是反射点,一个交点是绕射点 else if (rayCrossNode[outRay[i]].NodeStyle == NodeStyle.DiffractionNode && rayCrossNode[outRay[i]].NodeStyle == NodeStyle.ReflectionNode) { } else//两个交点都是绕射点 { } }
/// <summary> ///在两条射线中间生成一条新的射线 /// </summary> /// <param name="outRay">从射线面发出的射线</param> /// <param name="rayCrossNode">射线与交点的dictionary</param> /// <param name="ter">地形</param> /// <param name="rxBall">接收球</param> /// <param name="buildings">建筑物</param> /// <param name="rayBeamAngle">射线束的夹角</param> /// <returns></returns> private void SetNewMiddleRay(List <RayInfo> outRay, Dictionary <RayInfo, Node> rayCrossNode, Terrain ter, ReceiveBall rxBall, City buildings, double rayBeamAngle, ref int i) { Point lineMiddlePoint = rayCrossNode[outRay[i]].Position.GetMiddlePointInTwoPoints(rayCrossNode[outRay[i + 1]].Position); RayInfo newRay = new RayInfo(this.launchPoint, lineMiddlePoint); Node lineNode = this.GetLineNode(newRay); List <Node> newCrossNode = new LineRay(newRay, lineNode).GetCrossNodes(ter, rxBall, buildings, rayBeamAngle); if (newCrossNode.Count == 0) { rayCrossNode.Add(newRay, null); } else { rayCrossNode.Add(newRay, newCrossNode[0]); this.lineNodes.Add(newCrossNode[0], lineNode); } outRay.Insert(i + 1, newRay); i--; }