/// <summary> ///获得正二十面体的20个三角形处理单元 /// </summary> /// <param name="tx">发射机</param> /// <returns></returns> protected List <RayTracingModel> GetOriginUnitsOfIcosahedron(Node tx) { //求正二十面体顶点坐标的方法参考网址:http://zhidao.baidu.com/link?url=gYy1D8YyS13ZC20yN2kZvrzBc6Ry8oSnJEEZq864yZLwXkNiWjtPqAwIltCDSpTScZvmPnPhAD2ttA-wiL8PU6lQ9aW5FRwRz-xgX-MlTly double PA = 4 / (Math.Sqrt(10 + 2 * Math.Sqrt(5))); double AW = (PA / 2) / Math.Sin(36 * Math.PI / 180); double PW = Math.Sqrt(Math.Pow(PA, 2) - Math.Pow(AW, 2)); Point[] vertex = new Point[12]; //点的顺序为PABCDEQFGKMN vertex[0] = new Point(0, 0, 1); //P vertex[1] = new Point(0, AW, 1 - PW); //A vertex[2] = new Point(AW * Math.Cos(18 * Math.PI / 180), AW * Math.Sin(18 * Math.PI / 180), 1 - PW); //B vertex[3] = new Point(AW * Math.Cos(54 * Math.PI / 180), -AW * Math.Sin(54 * Math.PI / 180), 1 - PW); //C vertex[4] = new Point(-AW * Math.Cos(54 * Math.PI / 180), -AW * Math.Sin(54 * Math.PI / 180), 1 - PW); //D vertex[5] = new Point(-AW * Math.Cos(18 * Math.PI / 180), AW * Math.Sin(18 * Math.PI / 180), 1 - PW); //E vertex[6] = new Point(0, 0, -1); //Q vertex[7] = new Point(-AW * Math.Sin(36 * Math.PI / 180), AW * Math.Cos(36 * Math.PI / 180), -1 + PW); //F vertex[8] = new Point(AW * Math.Cos(54 * Math.PI / 180), AW * Math.Sin(54 * Math.PI / 180), -1 + PW); //G vertex[9] = new Point(AW * Math.Sin(72 * Math.PI / 180), -AW * Math.Cos(72 * Math.PI / 180), -1 + PW); //K vertex[10] = new Point(0, -AW, -1 + PW); //M vertex[11] = new Point(-AW * Math.Cos(18 * Math.PI / 180), -AW * Math.Sin(18 * Math.PI / 180), -1 + PW); //N // ClassNewRay[] originRay = new ClassNewRay[12]; for (int i = 0; i < 12; i++) { originRay[i] = new ClassNewRay(tx.Position, new SpectVector(vertex[i].X, vertex[i].Y, vertex[i].Z), false); } List <RayTracingModel> originUnits = new List <RayTracingModel>(); //正二十面体上层三角面 for (int j = 1; j < 5; j++) { originUnits.Add(new RayTracingModel(originRay[0], originRay[j], originRay[j + 1])); } originUnits.Add(new RayTracingModel(originRay[0], originRay[5], originRay[1])); //正二十面体下层三角面 for (int k = 7; k < 11; k++) { originUnits.Add(new RayTracingModel(originRay[6], originRay[k], originRay[k + 1])); } originUnits.Add(new RayTracingModel(originRay[6], originRay[11], originRay[7])); //正二十面体中层三角面 for (int l = 1; l < 5; l++) { originUnits.Add(new RayTracingModel(originRay[l], originRay[l + 1], originRay[l + 7])); } for (int m = 7; m < 11; m++) { originUnits.Add(new RayTracingModel(originRay[m], originRay[m + 1], originRay[m - 6])); } originUnits.Add(new RayTracingModel(originRay[5], originRay[1], originRay[7])); originUnits.Add(new RayTracingModel(originRay[11], originRay[7], originRay[5])); return(originUnits); }
/// <summary> ///获取射线3的细分单元 /// </summary> protected List <RayTracingModel> GetThirdRayUnits(RayTracingModel unit) { ClassNewRay ray3 = (ClassNewRay)unit.ThirdRay.Clone(); ClassNewRay ray4 = new ClassNewRay(unit.ThirdRay.Origin, GetMiddleVectorOfTwoVectors(unit.FirstRay.SVector, unit.SecondRay.SVector), false); ClassNewRay ray5 = new ClassNewRay(unit.ThirdRay.Origin, GetMiddleVectorOfTwoVectors(unit.FirstRay.SVector, unit.ThirdRay.SVector), false); ClassNewRay ray6 = new ClassNewRay(unit.ThirdRay.Origin, GetMiddleVectorOfTwoVectors(unit.SecondRay.SVector, unit.ThirdRay.SVector), false); List <RayTracingModel> divideUnits = new List <RayTracingModel>(); divideUnits.Add(new RayTracingModel(ray3, ray5, ray6)); divideUnits.Add(new RayTracingModel(ray4, ray5, ray6)); divideUnits.Add(new RayTracingModel(unit.FirstRay, ray4, ray5, true)); divideUnits.Add(new RayTracingModel(unit.SecondRay, ray4, ray6, true)); return(divideUnits); }
/// <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); }
private ClassNewRay[,] NewInit(Node tx, int cellAngle, Terrain ter, ReceiveArea reArea, List <FrequencyBand> TxFrequencyBand) { double radius = 1; Point target; SpectVector vector; int cellTheta = 180 / cellAngle; int cellPhi = 360 / cellAngle; ClassNewRay[,] initNewRay = new ClassNewRay[cellPhi, cellTheta]; for (int i = 0; i < cellPhi; i++) { for (int j = 0; j < cellTheta; j++) { target = new Point(radius * Math.Sin(Math.PI / 180 * j * cellAngle) * Math.Cos(Math.PI / 180 * i * cellAngle), radius * Math.Sin(Math.PI / 180 * j * cellAngle) * Math.Sin(Math.PI / 180 * i * cellAngle), radius * Math.Cos(Math.PI / 180 * j * cellAngle)); vector = new SpectVector(target.X, target.Y, target.Z); List <RayInfo> list1 = new List <RayInfo>(); list1.Add(new RayInfo(tx.Position, vector)); List <Path> pathtemp = GetFanalPath(tx, ter, reArea, TxFrequencyBand, list1); initNewRay[i, j] = new ClassNewRay(tx.Position, vector, Ismeat(pathtemp), pathtemp); } } return(initNewRay); }
public List <Path> MultiplyMethod(Node tx, Terrain ter, ReceiveArea reArea, List <FrequencyBand> TxFrequencyBand) { List <Path> pathInfo = new List <Path>(); int cellAngle = 1; double divideAngle = 0.5; // if (tx.Position.x > reArea.OriginPoint.x && tx.Position.x < reArea.OriginPoint.x + reArea.rxLength && tx.Position.y > reArea.OriginPoint.y && tx.Position.y < reArea.OriginPoint.y + reArea.rxwidth)//若发射机在接收区域内或者正上方 if (RayPath.IsInTheArea(tx.Position, reArea))//若发射机在接收区域内 { divideAngle = 1; } // RayInfo.divideAngle = divideAngle; ClassNewRay[,] initArray = new ClassNewRay[360 / cellAngle + 1, 180 / cellAngle + 1]; ClassNewRay[,] temp = NewInit(tx, cellAngle, ter, reArea, TxFrequencyBand); for (int i = 0; i < 360 / cellAngle; i++) { for (int j = 0; j < 180 / cellAngle; j++) { initArray[i, j] = temp[i, j]; } } for (int i = 0; i < 360 / cellAngle; i++) { int temp1 = 180 / cellAngle; initArray[i, temp1] = initArray[i, 0]; } for (int i = 0; i < 180 / cellAngle; i++) { int temp1 = 360 / cellAngle; initArray[temp1, i] = initArray[0, i]; } initArray[360 / cellAngle, 180 / cellAngle] = initArray[0, 0]; for (int i = 0; i < 360 / cellAngle; i++) { for (int j = 0; j < 180 / cellAngle; j++) { if (initArray[i, j].Flag == true || initArray[i + 1, j].Flag == true || initArray[i, j + 1].Flag == true || initArray[i + 1, j + 1].Flag == true) { for (double m = i * cellAngle; m < (i + 1) * cellAngle; m += divideAngle) { for (double n = j * cellAngle; n < (j + 1) * cellAngle; n += divideAngle) { if (m != i * cellAngle || n != j * cellAngle) { SpectVector vector = new SpectVector(Math.Sin(Math.PI / 180 * n) * Math.Cos(Math.PI / 180 * m), Math.Sin(Math.Sin(Math.PI / 180 * n)) * Math.Sin(Math.PI / 180 * m), Math.Cos(Math.PI / 180 * n)); List <RayInfo> list = new List <RayInfo>(); list.Add(new RayInfo(tx.Position, vector)); List <Path> pathtemp = GetFanalPath(tx, ter, reArea, TxFrequencyBand, list); for (int a = 0; a < pathtemp.Count; a++) { pathInfo.Add(pathtemp[a]); } } } } } } } for (int i = 0; i < 360 / cellAngle; i++) { for (int j = 0; j < 180 / cellAngle; j++) { if (initArray[i, j].Flag == true) { pathInfo.AddRange(initArray[i, j].Path); } } } Console.WriteLine("算法完成:" + DateTime.Now); return(pathInfo); }