/// <summary> ///获取每个三角形细分的顶点 /// </summary> protected List <Point> GetSubDivisionPoints(RayTracingModel unit, int TessellationFrequency) { List <Point> vertex = new List <Point>(); Point param1 = new Point(unit.FirstRay.SVector); Point param2 = new Point(unit.SecondRay.SVector); Point param3 = new Point(unit.ThirdRay.SVector); vertex.Add(param1); vertex.Add(param2); vertex.Add(param3); SpectVector n1 = new SpectVector(param1, param2); SpectVector n2 = new SpectVector(param1, param3); double length = param1.GetDistance(param2) / TessellationFrequency; Point[] p1 = new Point[TessellationFrequency]; Point[] p2 = new Point[TessellationFrequency]; for (int i = 0; i < TessellationFrequency; i++) { p1[i] = new Point(param1.X + (i + 1) * (n1.a / Math.Sqrt(Math.Pow(n1.a, 2) + Math.Pow(n1.b, 2) + Math.Pow(n1.c, 2)) * length), param1.Y + (i + 1) * (n1.b / Math.Sqrt(Math.Pow(n1.a, 2) + Math.Pow(n1.b, 2) + Math.Pow(n1.c, 2)) * length), param1.Z + (i + 1) * (n1.c / Math.Sqrt(Math.Pow(n1.a, 2) + Math.Pow(n1.b, 2) + Math.Pow(n1.c, 2)) * length)); p2[i] = new Point(param1.X + (i + 1) * (n2.a / Math.Sqrt(Math.Pow(n2.a, 2) + Math.Pow(n2.b, 2) + Math.Pow(n2.c, 2)) * length), param1.Y + (i + 1) * (n2.b / Math.Sqrt(Math.Pow(n2.a, 2) + Math.Pow(n2.b, 2) + Math.Pow(n2.c, 2)) * length), param1.Z + (i + 1) * (n2.c / Math.Sqrt(Math.Pow(n2.a, 2) + Math.Pow(n2.b, 2) + Math.Pow(n2.c, 2)) * length)); vertex.Add(p1[i]); vertex.Add(p2[i]); } for (int j = 0; j < TessellationFrequency; j++) { SpectVector m = new SpectVector(p1[j], p2[j]); GetTrianglePoint(m, p1[j], p2[j], length, vertex); } return(vertex); }
/// <summary> ///求两个向量的中间向量 /// </summary> protected SpectVector GetMiddleVectorOfTwoVectors(SpectVector vector1, SpectVector vector2) { SpectVector unitVector1 = vector1.GetNormalizationVector(); SpectVector unitVector2 = vector2.GetNormalizationVector(); return(new SpectVector((unitVector1.a + unitVector2.a) / 2, (unitVector1.b + unitVector2.b) / 2, (unitVector1.c + unitVector2.c) / 2)); }
/// <summary> /// 求距离参数L,文档公式7 /// </summary> private static double GetDistanceParameter(Point originPoint, Point diffractionPoint, AdjacentEdge sameEdge, Point viewPoint, double waveLength) { SpectVector rayVector = new SpectVector(originPoint, diffractionPoint); double angle = SpectVector.VectorPhase(rayVector, sameEdge.LineVector) * Math.PI / 180;//入射射线与公共棱的夹角 if (((Math.PI / 2) < angle) && (angle < Math.PI)) { angle = Math.PI - angle; } double s1 = originPoint.GetDistance(diffractionPoint); //辐射源到绕射点的距离 double s2 = diffractionPoint.GetDistance(viewPoint); //绕射点到观察点的距离 double distanceOfOriginAndSameLine = originPoint.GetDistanceToLine(sameEdge.StartPoint, sameEdge.LineVector); //辐射源到公共棱的距离 double L; //距离参数 if (distanceOfOriginAndSameLine > (waveLength * 10)) { L = s2 * Math.Pow(Math.Sin(angle), 2);//平面波入射时的距离参数 } else { L = s1 * s2 * Math.Pow(Math.Sin(angle), 2) / (s1 + s2);//球面波入射时的距离参数 } return(L); //柱面波没有写,以后需要可补上 }
/// <summary> /// 求绕射场场强,文档公式1 /// </summary> public static EField GetDiffractionEField(EField RayEFieldAtDiffractionPoint, RayInfo ray, Face diffractionFace1, Face diffractionFace2, Point diffractionPoint, Point viewPoint, double frequence) { if ((RayEFieldAtDiffractionPoint == null) || (ray == null) || (diffractionFace1 == null) || (diffractionFace2 == null) || (diffractionPoint == null) || (viewPoint == null)) { throw new Exception("绕射场强计算输入的参数中有参数是null"); } // AdjacentEdge sameEdge = new AdjacentEdge(diffractionFace1, diffractionFace2); //获取劈边 double waveLength = 300.0 / frequence; //波长 Plural PluralOfVerticalEField = EField.GetVerticalE(RayEFieldAtDiffractionPoint, ray.RayVector, sameEdge.LineVector); //获得电场的垂直分量 Plural PluralOfHorizonalEField = EField.GetHorizonalE(RayEFieldAtDiffractionPoint, ray.RayVector, sameEdge.LineVector); //获得电场的水平分量 double Ad = GetSpreadFactor(ray.Origin, sameEdge, diffractionPoint, viewPoint, waveLength); //获得空间衰减的扩散因子 double k = 2 * Math.PI / waveLength; //波矢量 double s2 = diffractionPoint.GetDistance(viewPoint); //绕射点到观察点的距离 Plural ejks = new Plural(Math.Cos(k * s2), -Math.Sin(k * s2)); //exp(-jks),相位 Plural verticalDiffractionFactor = GetDiffractionFactor(ray, diffractionFace1, diffractionFace2, sameEdge, diffractionPoint, viewPoint, waveLength, true);; //垂直极化波入射时的绕射系数D Plural PluralOfVerticalDiffractionEField = Plural.PluralMultiplyDouble(PluralOfVerticalEField * verticalDiffractionFactor * ejks, Ad); //垂直极化波入射时的绕射场 Plural horizonalDiffractionFactor = GetDiffractionFactor(ray, diffractionFace1, diffractionFace2, sameEdge, diffractionPoint, viewPoint, waveLength, false);; //水平极化波入射时的绕射系数D Plural PluralOfHorizonalDiffractionEField = Plural.PluralMultiplyDouble(horizonalDiffractionFactor * PluralOfHorizonalEField * ejks, Ad); //水平极化波入射时的绕射场 SpectVector vectorOfDiffractionRay = new SpectVector(diffractionPoint, viewPoint); //绕射波的方向 //垂直极化波绕射后的绕射场 SpectVector vectorOfVerticalDiffractionEField = GetVectorOfVerticalEField(vectorOfDiffractionRay, sameEdge.LineVector); //获得电场的垂直分量的方向 EField verticalDiffractionEField = GetXYZComponentOfTotalEField(PluralOfVerticalDiffractionEField, vectorOfVerticalDiffractionEField); //水平极化波绕射后的绕射场 SpectVector vectorOfHorizonalDiffractionEField = GetVectorOfHorizonalEField(vectorOfDiffractionRay, sameEdge.LineVector); //获得电场的水平分量的方向 EField horizonalDiffractionEField = GetXYZComponentOfTotalEField(PluralOfHorizonalDiffractionEField, vectorOfHorizonalDiffractionEField); EField diffractionEField = new EField(verticalDiffractionEField.X + horizonalDiffractionEField.X, verticalDiffractionEField.Y + horizonalDiffractionEField.Y, verticalDiffractionEField.Z + horizonalDiffractionEField.Z); //绕射场 return(diffractionEField); }
/// <summary> /// 将矩形离散成点points /// </summary> /// <param name="rect">矩形</param> /// <param name="rowDiscretedNum">行离散倍数</param> /// <param name="lineDiscretedNum">列离散倍数</param> /// <returns>离散点的链表</returns> private List <Point> GetDiscretePointsFromRect(Rectangle rect, int rowDiscretedNum, int lineDiscretedNum) { List <Point> discretePoints = new List <Point>(); //存储离散的点 Point leftBottomPoint = rect.LeftBottomPoint; //记录矩形的四个点 Point leftTopPoint = rect.LeftTopPoint; Point rightBottomPoint = rect.RightBottomPoint; RayInfo rayFromLeftBottomToTop = new RayInfo(leftBottomPoint, new SpectVector(leftBottomPoint, leftTopPoint)); //构造一条从左下角到左上角的射线 SpectVector vectorFromLeftBottomToRightBottom = new SpectVector(leftBottomPoint, rightBottomPoint); //构造一条从左下角到右下角的方向向量 double lineUnitLength = leftBottomPoint.GetDistance(leftTopPoint) / lineDiscretedNum; //将列离散后每小段的距离 double rowUnitLength = leftBottomPoint.GetDistance(rightBottomPoint) / rowDiscretedNum; //将行离散后每小段的距离 Point[] pointsOfLeftEdge = new Point[lineDiscretedNum + 1]; for (int i = 0; i <= lineDiscretedNum; i++)//等间隔在左边上取点 { pointsOfLeftEdge[i] = rayFromLeftBottomToTop.GetPointOnRayVector(i * lineUnitLength); } List <Point>[] pointsOfEveryEdge = new List <Point> [lineDiscretedNum + 1]; for (int j = 0; j <= lineDiscretedNum; j++) { pointsOfEveryEdge[j] = this.GetPointListAtRayVectorByLength(vectorFromLeftBottomToRightBottom, pointsOfLeftEdge[j], rowUnitLength, rowDiscretedNum); //获得每行的离散点 pointsOfEveryEdge[j].Insert(0, pointsOfLeftEdge[j]); //将这一行最左边的点插入到队列的最前端 discretePoints.AddRange(pointsOfEveryEdge[j]); //将每行离散的点添加到整体的列表中 } return(discretePoints); }
/// <summary> ///求得电场的水平分量的方向 /// </summary> private static SpectVector GetVectorOfHorizonalEField(SpectVector k, SpectVector l) { SpectVector n = SpectVector.VectorCrossMultiply(k, l); //入射面的法向量 SpectVector m = SpectVector.VectorCrossMultiply(k, n); return(m); }
/// <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="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); }
//求反射电场总值 static public EField ReflectEfield(EField e, RayInfo rayIn, RayInfo rayOut, SpectVector l, double Conduct, double Epara, double s1, double s2, double f) { if (rayIn.RayVector.IsParallel(l)) { Plural horiValue = HorizonalReflectance(0, Conduct, f, Epara); Plural A = new Plural(s1 / (s1 + s2)); Plural Xtemp = e.X * horiValue * A * GetPhase(s1, s2, f); Plural Ytemp = e.Y * horiValue * A * GetPhase(s1, s2, f); Plural Ztemp = e.Z * horiValue * A * GetPhase(s1, s2, f); return(new EField(Xtemp, Ytemp, Ztemp)); } else { double ReflectAngle = SpectVector.VectorPhase(rayIn.RayVector, l); if (Math.Abs(ReflectAngle) >= 90) { ReflectAngle = 180 - Math.Abs(ReflectAngle); } EField E = new EField(); EField VerticalE = VerticalEfield(e, rayIn, l, ReflectAngle, Conduct, Epara, s1, s2, f); EField HorizonalE = HorizonalEfield(e, rayIn, rayOut, l, ReflectAngle, Conduct, Epara, s1, s2, f); E.X.Re = VerticalE.X.Re + HorizonalE.X.Re; E.X.Im = VerticalE.X.Im + HorizonalE.X.Im; E.Y.Re = VerticalE.Y.Re + HorizonalE.Y.Re; E.Y.Im = VerticalE.Y.Im + HorizonalE.Y.Im; E.Z.Re = VerticalE.Z.Re + HorizonalE.Z.Re; E.Z.Im = VerticalE.Z.Im + HorizonalE.Z.Im; //string pathtest = "D:\\renwu\\反射" + DateTime.Today.ToString("yy/MM/dd") + ".txt"; //File.WriteAllText(pathtest, E.X.Re + " " + E.X.Im + " | " + E.Y.Re + " " + E.Y.Im + " | " + E.Z.Re + " " + E.Z.Im); return(E); } }
/// <summary> ///得到三角形切分后每条边上的点,但不包括初始端点 /// </summary> /// <param name="vector">方向向量</param> /// <param name="leftPoint">左端点</param> /// <param name="length">长度</param> /// <param name="TessellationFrequency">镶嵌次数,等于三角形每条边的细分次数</param> /// <param name="divideAngle">射线束夹角</param> /// <returns></returns> private void GetTriangleInternalEdgePoint(SpectVector vector, Point leftPoint, double length, int TessellationFrequency, List <Point> vertex) { for (int i = 1; i <= TessellationFrequency; i++)//根据端点和方向向量,得到平行边上每一个点 { Point temp = new Point(leftPoint.X + (vector.a / Math.Sqrt(Math.Pow(vector.a, 2) + Math.Pow(vector.b, 2) + Math.Pow(vector.c, 2)) * length * i), leftPoint.Y + (vector.b / Math.Sqrt(Math.Pow(vector.a, 2) + Math.Pow(vector.b, 2) + Math.Pow(vector.c, 2)) * length * i), leftPoint.Z + (vector.c / Math.Sqrt(Math.Pow(vector.a, 2) + Math.Pow(vector.b, 2) + Math.Pow(vector.c, 2)) * length * i)); vertex.Add(temp); } }
//求反射电场强度的垂直分量 private static EField VerticalEfield(EField e, RayInfo rayIn, SpectVector l, double ReflectAngle, double Conduct, double Epara, double s1, double s2, double f) { Plural VEi = EField.GetVerticalE(e, rayIn.RayVector, l); Plural V = VerticalReflectance(ReflectAngle, Conduct, f, Epara); Plural A = new Plural(s1 / (s1 + s2)); Plural E = VEi * V * A * GetPhase(s1, s2, f); EField Vefield = SpectVector.VectorDotMultiply(E, SpectVector.VectorCrossMultiply(rayIn.RayVector, l)); return(Vefield); }
//求反射电场强度的水平分量 private static EField HorizonalEfield(EField e, RayInfo rayIn, RayInfo rayOut, SpectVector l, double ReflectAngle, double Conduct, double Epara, double s1, double s2, double f) { Plural HEi = EField.GetHorizonalE(e, rayIn.RayVector, l); Plural H = HorizonalReflectance(ReflectAngle, Conduct, f, Epara); Plural A = new Plural(s1 / (s1 + s2)); Plural E = HEi * H * A * GetPhase(s1, s2, f); SpectVector l1 = SpectVector.VectorCrossMultiply(rayOut.RayVector, SpectVector.VectorCrossMultiply(rayIn.RayVector, l)); EField Hefield = SpectVector.VectorDotMultiply(E, l1); return(Hefield); }
/// <summary> ///得到三角形切分后每条边上的点,但不包括初始端点 /// </summary> /// <param name="vector">从开始端点发出的方向向量</param> /// <param name="startPoint">开始端点</param> /// <param name="length">长度</param> /// <param name="TessellationFrequency">镶嵌次数,等于三角形每条边的细分次数</param> /// <param name="divideAngle">射线束夹角</param> /// <returns></returns> private List <Point> GetPointListAtRayVectorByLength(SpectVector vector, Point startPoint, double length, int TessellationFrequency) { List <Point> vertices = new List <Point>(); RayInfo lineRay = new RayInfo(startPoint, vector); for (int i = 1; i <= TessellationFrequency; i++)//根据端点和方向向量,得到在射线方向上每一个点 { Point temp = lineRay.GetPointOnRayVector(i * length); vertices.Add(temp); } return(vertices); }
/// <summary> /// 将一个有方向的场强用XYZ坐标表示 /// </summary> private static EField GetXYZComponentOfTotalEField(Plural totalEField, SpectVector vectorOfEField) { EField componentEField = new EField(); double XComponent = vectorOfEField.a / (Math.Sqrt(Math.Pow(vectorOfEField.a, 2) + Math.Pow(vectorOfEField.b, 2) + Math.Pow(vectorOfEField.c, 2))); double YComponent = vectorOfEField.b / (Math.Sqrt(Math.Pow(vectorOfEField.a, 2) + Math.Pow(vectorOfEField.b, 2) + Math.Pow(vectorOfEField.c, 2))); double ZComponent = vectorOfEField.c / (Math.Sqrt(Math.Pow(vectorOfEField.a, 2) + Math.Pow(vectorOfEField.b, 2) + Math.Pow(vectorOfEField.c, 2))); componentEField.X = Plural.PluralMultiplyDouble(totalEField, XComponent); componentEField.Y = Plural.PluralMultiplyDouble(totalEField, YComponent); componentEField.Z = Plural.PluralMultiplyDouble(totalEField, ZComponent); return(componentEField); }
/// <summary> /// 求圆柱体绕射模型表面的细分三角形 /// </summary> /// <param name="originPoint">辐射源</param> /// <param name="diffractionPoint1">绕射点1</param> /// <param name="diffractionPoint">绕射点2</param> /// <param name="diffractionEdge">绕射棱</param> /// <param name="divisionNumber">细分系数</param> /// <param name="angleOfTwoTers">两个绕射面的夹角</param> /// <returns></returns> private static List <List <Triangle> > GetCirclarTruncatedConeSurfaceDivisionTriangles(Point originPoint, Point diffractionPoint1, Point diffractionPoint2, AdjacentEdge diffractionEdge, int divisionNumber, double angleOfTwoTers) { RayInfo launchRay1 = new RayInfo(originPoint, diffractionPoint1); //从上一节点到绕射点1重新构造一条入射线 RayInfo launchRay2 = new RayInfo(originPoint, diffractionPoint2); //从上一节点到绕射点2重新构造一条入射线 double angleOfRay1AndEdge = launchRay1.GetAngleOfTwoStraightLines(diffractionEdge.SwitchToRay()); //获取射线1与劈边的夹角 double angleOfRay2AndEdge = launchRay2.GetAngleOfTwoStraightLines(diffractionEdge.SwitchToRay()); //获取射线2与劈边的夹角 double distanceToDiffractionPoint1 = originPoint.GetDistance(diffractionPoint1); double distanceToDiffractionPoint2 = originPoint.GetDistance(diffractionPoint2); double circleRadius1, circleRadius2; if (distanceToDiffractionPoint1 > distanceToDiffractionPoint2) { circleRadius1 = (distanceToDiffractionPoint1 - distanceToDiffractionPoint2) * Math.Sin(angleOfRay1AndEdge * Math.PI / 180); circleRadius2 = 2 * (distanceToDiffractionPoint1 - distanceToDiffractionPoint2) * Math.Sin(angleOfRay2AndEdge * Math.PI / 180); } else { circleRadius2 = (distanceToDiffractionPoint2 - distanceToDiffractionPoint1) * Math.Sin(angleOfRay2AndEdge * Math.PI / 180); circleRadius1 = 2 * (distanceToDiffractionPoint2 - distanceToDiffractionPoint1) * Math.Sin(angleOfRay1AndEdge * Math.PI / 180); } Point circleCenterPoint1 = GetCircleCenterPoint(launchRay1, diffractionPoint1, angleOfRay1AndEdge, diffractionEdge, circleRadius1);//在劈边上选一个与绕射射线同向且不是绕射点的点,作为圆盘的圆心 Point circleCenterPoint2 = GetCircleCenterPoint(launchRay2, diffractionPoint2, angleOfRay2AndEdge, diffractionEdge, circleRadius2); //求圆盘面上的一对相互垂直的方向向量 SpectVector circleVectorU = GetVectorInThePlaneOfCircle(diffractionEdge, circleCenterPoint1); //先求圆所在平面上的一个向量 SpectVector circleVectorV = GetQuadratureVectorInTheOfCircle(diffractionEdge, circleVectorU); //再求一个与前面所求向量和劈边向量都正交的向量,该向量也在圆所在的平面上 //圆与三角面的交点 Point crossPointOfFace0AndCircle1 = GetCrossPointOfCircleWithTer(diffractionEdge.AdjacentTriangles[0].SwitchToSpaceFace(), circleCenterPoint1, circleRadius1, circleVectorU, circleVectorV, diffractionEdge.AdjacentTriangles[0].GetPointsOutOfTheLine(diffractionEdge)[0]); //圆与三角面1一侧的交点 Point crossPointOfFace1AndCircle1 = GetCrossPointOfCircleWithTer(diffractionEdge.AdjacentTriangles[1].SwitchToSpaceFace(), circleCenterPoint1, circleRadius1, circleVectorU, circleVectorV, diffractionEdge.AdjacentTriangles[1].GetPointsOutOfTheLine(diffractionEdge)[0]); //圆与三角面2一侧的交点 if (crossPointOfFace0AndCircle1 == null || crossPointOfFace1AndCircle1 == null) { LogFileManager.ObjLog.debug("求圆盘与绕射面的交点时有错"); return(new List <List <Triangle> >()); } SpectVector circlePointVector;//从大的圆盘的圆心指向小的圆盘的圆心 CirclarTruncatedCone circlarTrimcatedCone; if (distanceToDiffractionPoint1 > distanceToDiffractionPoint2) { circlePointVector = new SpectVector(circleCenterPoint2, circleCenterPoint1).GetNormalizationVector(); SetUnitVectorVnCirclePlane(ref circleVectorU, ref circleVectorV, circleCenterPoint1, crossPointOfFace0AndCircle1, crossPointOfFace1AndCircle1, circlePointVector, angleOfTwoTers); circlarTrimcatedCone = new CirclarTruncatedCone(circleCenterPoint2, circleRadius2, circleCenterPoint1, circleRadius1); } else { circlePointVector = new SpectVector(circleCenterPoint1, circleCenterPoint2).GetNormalizationVector(); SetUnitVectorVnCirclePlane(ref circleVectorU, ref circleVectorV, circleCenterPoint1, crossPointOfFace0AndCircle1, crossPointOfFace1AndCircle1, circlePointVector, angleOfTwoTers); circlarTrimcatedCone = new CirclarTruncatedCone(circleCenterPoint1, circleRadius1, circleCenterPoint2, circleRadius2); } return(circlarTrimcatedCone.GetConeSurfaceDivisionTriangles(divisionNumber, 360 - angleOfTwoTers, circleVectorU, circleVectorV)); }
/// <summary> /// 求在圆的平面上的一个向量 /// </summary> private static SpectVector GetVectorInThePlaneOfCircle(AdjacentEdge sameEdge, Point centerPoint) { if (sameEdge.LineVector.a == 0 && sameEdge.LineVector.b == 0) { SpectVector unitCircleVectorU = new SpectVector(1, 0, 0); return(unitCircleVectorU); } else { // SpectVector circleVectorU = new SpectVector(sameEdge.LineVector.b, -sameEdge.LineVector.a, 0);//先求圆所在平面上的一个向量 // return circleVectorU.GetNormalizationVector(); return(sameEdge.AdjacentTriangles[0].NormalVector.GetNormalizationVector()); } }
/// <summary> ///获取三角形内每条平行边上的点 /// </summary> protected void GetTrianglePoint(SpectVector m, Point p1, Point p2, double length, List <Point> vertex) { Point temp = new Point(p1.X + (m.a / Math.Sqrt(Math.Pow(m.a, 2) + Math.Pow(m.b, 2) + Math.Pow(m.c, 2)) * length), p1.Y + (m.b / Math.Sqrt(Math.Pow(m.a, 2) + Math.Pow(m.b, 2) + Math.Pow(m.c, 2)) * length), p1.Z + (m.c / Math.Sqrt(Math.Pow(m.a, 2) + Math.Pow(m.b, 2) + Math.Pow(m.c, 2)) * length)); vertex.Add(temp); if (Math.Abs(temp.GetDistance(p2)) <= 0.0000001) { return; } else { GetTrianglePoint(m, temp, p2, length, vertex); } }
/// <summary> /// 求在圆的平面上的一个与平面法向量,平面某个向量都正交的向量 /// </summary> private static SpectVector GetQuadratureVectorInTheOfCircle(AdjacentEdge sameEdge, SpectVector vectorU) { if (sameEdge.LineVector.a == 0 && sameEdge.LineVector.b == 0) { SpectVector unitCircleVectorV = new SpectVector(0, 1, 0); return(unitCircleVectorV); } else { //再求一个与1和劈边向量都正交的向量,该向量也在圆所在的平面上 SpectVector circleVectorV = new SpectVector(sameEdge.LineVector.b * vectorU.c - sameEdge.LineVector.c * vectorU.b, sameEdge.LineVector.c * vectorU.a - sameEdge.LineVector.a * vectorU.c, sameEdge.LineVector.a * vectorU.b - sameEdge.LineVector.b * vectorU.a); return(circleVectorV.GetNormalizationVector()); } }
/// <summary> ///求两个三角面的夹角 /// </summary> private static double GetAngleOfTwoTers(Face face1, Face face2, AdjacentEdge sameEdge) { //相邻三角面另外两个独立点 Point otherPoint1 = face1.GetPointsOutOfTheLine(sameEdge)[0]; Point otherPoint2 = face2.GetPointsOutOfTheLine(sameEdge)[0]; SpectVector face1Vector1 = new SpectVector(otherPoint1, sameEdge.StartPoint); SpectVector face1Vector2 = new SpectVector(otherPoint1, sameEdge.EndPoint); SpectVector normalVector1 = SpectVector.VectorCrossMultiply(face1Vector1, face1Vector2);//获得第一个三角面的法向量 SpectVector face2Vector1 = new SpectVector(otherPoint2, sameEdge.StartPoint); SpectVector face2Vector2 = new SpectVector(otherPoint2, sameEdge.EndPoint); SpectVector normalVector2 = SpectVector.VectorCrossMultiply(face2Vector1, face2Vector2); //获得第二个三角面的法向量 double angleOfTers = SpectVector.VectorPhase(normalVector1, normalVector2); //两个法向量的夹角 return(angleOfTers); }
/// <summary> /// 根据绕射点和圆上的点得到一个关于绕射射线的list /// </summary> private static List <RayInfo> GetRayListOfDiffraction(Point diffractionPoint, List <Point> filtratingCircumPoints) { List <RayInfo> diffrationRay = new List <RayInfo>();//包含绕射射线的list for (int j = 0; j < filtratingCircumPoints.Count; j++) { SpectVector middleParamVector = new SpectVector(diffractionPoint, filtratingCircumPoints[j]).GetNormalizationVector(); if (middleParamVector.a == 0 && middleParamVector.b == 0 && middleParamVector.c == 0) { LogFileManager.ObjLog.debug("生成绕射射线时,生成的绕射射线的方向向量为0"); } RayInfo middleParamRay = new RayInfo(diffractionPoint, middleParamVector); diffrationRay.Add(middleParamRay); } return(diffrationRay); }
public RayInfo GetRayOut() { if (rayIn.RayVector.IsParallelAndSamedirection(verticalVector)) //判断向量是否和面垂直 { //垂直时求得入射射线的反向向量即为反射向量 return(new RayInfo(rayIn.GetCrossPointWithFace(intersectionFace), rayIn.RayVector.GetReverseVector())); } if (Math.Abs(rayIn.RayVector.DotMultiplied(verticalVector)) < 0.00001)//判断向量是否和面平行 { return(null); } SpectVector rotationVector = rayIn.RayVector.CrossMultiplied(verticalVector).GetReverseVector(); double rotationAngle = 180 - 2 * reflectAngle; SpectVector vectorOfRfraction = rayIn.RayVector.GetRightRotationVector(rotationVector, rotationAngle);//调用向量绕旋转轴向量右旋公式 return(new RayInfo(rayIn.GetCrossPointWithFace(intersectionFace), vectorOfRfraction)); }
public ReflectEfieldCal(RayInfo rayIn, Face intersectionFace, double inputFrequency, EField efield, double outDistance) { this.rayIn = rayIn; this.intersectionFace = intersectionFace; this.inputFrequency = inputFrequency; this.inDistance = rayIn.Origin.GetDistance(rayIn.GetCrossPointBetweenStraightLineAndFace(intersectionFace)); this.outDistance = outDistance; this.Epara = intersectionFace.Material.DielectricLayer[1].Permittivity / intersectionFace.Material.DielectricLayer[0].Permittivity; this.e = efield; //衰减常数公式,见《电磁场与电磁波》(焦其祥主编) 192页,透射波所在介质的衰减常数 this.outerAlphaConstant = 2 * Math.PI * inputFrequency * Math.Sqrt(permeability * intersectionFace.Material.DielectricLayer[0].Permittivity / 2 * (Math.Sqrt(1 + Math.Pow(intersectionFace.Material.DielectricLayer[0].Conductivity, 2) / (Math.Pow(2 * Math.PI * inputFrequency, 2) * Math.Pow(intersectionFace.Material.DielectricLayer[0].Permittivity, 2) )) - 1)); //入射波所在介质的衰减常数 this.reflectAngle = rayIn.RayVector.GetPhaseOfVector(intersectionFace.NormalVector); //角度值 this.verticalVector = intersectionFace.NormalVector; }
/// <summary> /// 求射线射到棱上后得到的绕射射线List /// </summary> public static List <RayInfo> GetDiffractionRays(Point originPoint, Point diffractionPoint, AdjacentEdge diffractionEdge, int numberOfRay) { if ((originPoint == null) || (diffractionPoint == null) || (diffractionEdge == null)) { LogFileManager.ObjLog.debug("求绕射射线的方法中输入的参数有null"); return(new List <RayInfo>()); } double angleOfTwoTers = GetAngleOfTwoTers(diffractionEdge.AdjacentTriangles[0], diffractionEdge.AdjacentTriangles[1], diffractionEdge); //获得两个三角面的夹角 if (angleOfTwoTers > 178) { // LogFileManager.ObjLog.debug("输入的绕射面的 夹角大于178度"); return(new List <RayInfo>()); } else { RayInfo inRay = new RayInfo(originPoint, new SpectVector(originPoint, diffractionPoint)); //从上一节点到绕射点重新构造一条入射线 double angleOfRayAndEdge = inRay.GetAngleOfTwoStraightLines(diffractionEdge.SwitchToRay()); //获取射线与劈边的夹角 Point circleCenterPoint = GetCircleCenterPoint(angleOfRayAndEdge, inRay, diffractionEdge, diffractionPoint); //在劈边上选一个与绕射射线同向且不是绕射点的点,一般选公共棱的某个顶点,当夹角为90度时,绕射射线为圆盘,圆心为绕射点 double circleRadius = GetCircleRadius(angleOfRayAndEdge, diffractionPoint, circleCenterPoint, numberOfRay); //所作圆的半径 SpectVector circleVectorU = GetVectorInThePlaneOfCircle(diffractionEdge, circleCenterPoint); //先求圆所在平面上的一个向量 SpectVector circleVectorV = GetQuadratureVectorInTheOfCircle(diffractionEdge, circleVectorU); //再求一个与前面所求向量和劈边向量都正交的向量,该向量也在圆所在的平面上 //圆与三角面的交点 Point crossPointOfFace0AndCircle = GetCrossPointOfCircleWithTer(diffractionEdge.AdjacentTriangles[0].SwitchToSpaceFace(), diffractionPoint, circleRadius, circleVectorU, circleVectorV, diffractionEdge.AdjacentTriangles[0].GetPointsOutOfTheLine(diffractionEdge)[0]); //圆与三角面1一侧的交点 Point crossPointOfFace1AndCircle = GetCrossPointOfCircleWithTer(diffractionEdge.AdjacentTriangles[1].SwitchToSpaceFace(), diffractionPoint, circleRadius, circleVectorU, circleVectorV, diffractionEdge.AdjacentTriangles[1].GetPointsOutOfTheLine(diffractionEdge)[0]); //圆与三角面2一侧的交点 if (crossPointOfFace0AndCircle == null || crossPointOfFace1AndCircle == null) { LogFileManager.ObjLog.debug("求圆盘与绕射面的交点时有错"); return(new List <RayInfo>()); } SpectVector circlePointVector; if (circleCenterPoint.equal(diffractionPoint)) { circlePointVector = diffractionEdge.LineVector.GetNormalizationVector(); } else { circlePointVector = new SpectVector(diffractionPoint, circleCenterPoint).GetNormalizationVector(); } SetUnitVectorVnCirclePlane(ref circleVectorU, ref circleVectorV, circleCenterPoint, crossPointOfFace0AndCircle, crossPointOfFace1AndCircle, circlePointVector, angleOfTwoTers); List <Point> circumPoints = GetcircumPointOfTheCircle(diffractionEdge, circleCenterPoint, circleRadius, circleVectorU, circleVectorV, 360 - angleOfTwoTers, numberOfRay); //以某个角度划分获得所设圆上的点的list //根据绕射点和所设圆上的点,就可以求出绕射射线 List <RayInfo> diffrationRay = GetRayListOfDiffraction(diffractionPoint, circumPoints); //包含绕射射线的list return(diffrationRay); } }
/// <summary> ///在绕射点范围内取一定个数的点 /// </summary> /// <param name="firstPoint">初始点</param> /// <param name="lastPoint">终点</param> /// <param name="number">采样点个数</param> /// <returns>在绕射点范围内一定个数的点的list</returns> private List <Point> GetSamplingPointsInRange(Point firstPoint, Point lastPoint, double number) { List <Point> samplingPoings = new List <Point>(); SpectVector vector = new SpectVector(firstPoint, lastPoint).GetNormalizationVector(); double spacing = lastPoint.GetDistance(firstPoint) / number; if (lastPoint.GetDistance(firstPoint) / number == 0) { number--; } for (int i = 1; i < number; i++) { samplingPoings.Add(new Point(firstPoint.X + vector.a * spacing * i, firstPoint.Y + vector.b * spacing * i, firstPoint.Z + vector.c * spacing * i)); } samplingPoings.Add(lastPoint); return(samplingPoings); }
//求透射电场强度的垂直分量by Zhuo Liu 2015,3,24: //private Efield GetVerticalEfield(Efield e, RayInfo rayIn, RayInfo rayOut, VectorInSpace lVector, double Conduct, double Epara, double inDistance, double outDistance, double inputFrequency) public EField GetVerticalEfield() { //当入射波和相交面垂直时,求水平分量和垂直分量没有意义 if (rayIn.RayVector.IsParallelAndSamedirection(intersectionFace.NormalVector)) { return(null); } //原static语句:double reflectAngle = SpectVector.VectorPhase(rayIn.RayVector, l); Plural verticalOfE = e.GetVerticalE(rayIn.RayVector, verticalVector); Plural vertiValue = GetVerticalRefractance(); Plural A = new Plural(inDistance / (inDistance + outDistance)); Plural E = verticalOfE * vertiValue * A * GetPhase(); // 原static语句:Efield Vefield = SpectVector .VectorDotMultiply (E, VectorInSpace.VectorCrossMultiply (rayIn .RayVector ,l )); SpectVector tempVector = rayIn.RayVector.CrossMultiplied(verticalVector).GetNormalizationVector(); return(tempVector.DotMultiplied(E)); }
public RayInfo GetRayOut() { if (rayIn.RayVector.IsParallelAndSamedirection(verticalVector))//判断向量是否和面垂直 { return(new RayInfo(rayIn.GetCrossPointWithFace(intersectionFace), rayIn.RayVector)); } if (rayIn.RayVector.DotMultiplied(verticalVector) == 0)//判断向量是否和面平行 { return(null); } SpectVector rotationVector = rayIn.RayVector.CrossMultiplied(verticalVector); double temp = Math.Sin(reflectAngle * Math.PI / 180) / Math.Sqrt(Epara); double refractionAngle = Math.Asin(temp) / Math.PI * 180; double rotationAngle = reflectAngle - refractionAngle; SpectVector vectorOfRfraction = rayIn.RayVector.GetRightRotationVector(rotationVector, rotationAngle);//调用向量绕旋转轴向量右旋公式 return(new RayInfo(rayIn.GetCrossPointWithFace(intersectionFace), vectorOfRfraction)); }
public EField GetHorizonalEfield() { if (rayIn.RayVector.IsParallelAndSamedirection(intersectionFace.NormalVector)) { return(null); } Plural horizonOfE = e.GetHorizonalE(rayIn.RayVector, verticalVector); Plural horiValue = GetHorizonalRefractance(); Plural A = new Plural(inDistance / (inDistance + outDistance)); Plural E = horizonOfE * horiValue * A * GetPhase(); //原static语句:VectorInSpace l1 = VectorInSpace.VectorCrossMultiply(rayOut.RayVector, VectorInSpace.VectorCrossMultiply(rayIn.RayVector, l)); SpectVector temp1 = rayIn.RayVector.CrossMultiplied(verticalVector); SpectVector temp2 = GetRayOut().RayVector; SpectVector tempVector = temp2.CrossMultiplied(temp1).GetNormalizationVector(); return(tempVector.DotMultiplied(E)); }
/// <summary> /// 构建态势区域内的Rx节点 /// </summary> /// <param name="rxNode1">当前节点</param> /// <param name="rxNode2">下一个节点</param> /// <param name="reArea">态势区域</param> /// <param name="distance">与当前节点的距离</param> /// <returns></returns> private Node MakeAreaRxNode(Node rxNode1, Node rxNode2, ReceiveArea reArea, double distance) { SpectVector vector12 = new SpectVector(rxNode1.Position, rxNode2.Position).GetNormalizationVector(); Point position = new Point(rxNode1.Position.X + distance * vector12.a, rxNode1.Position.Y + distance * vector12.b, rxNode1.Position.Z + distance * vector12.c); Node rxNode = new Node(); rxNode.Position = position; rxNode.NodeStyle = NodeStyle.Rx; rxNode.LayNum = rxNode1.LayNum; rxNode.DiffractionNum = rxNode1.DiffractionNum; rxNode.RayIn = rxNode2.RayIn; rxNode.IsReceiver = true; rxNode.IsEnd = false; rxNode.DistanceToFrontNode = distance; rxNode.RxNum = reArea.RxNum; rxNode.RayTracingDistance = rxNode1.RayTracingDistance + rxNode.DistanceToFrontNode; rxNode.NodeName = reArea.RxName; rxNode.UAN = reArea.UAN; return(rxNode); }
/// <summary> /// 求绕射棱与出射射线方向相同的一个点,当绕射点不等于棱的端点时,返回棱的端点,否则返回在对应方向上取的一点 /// </summary> private static Point GetPointAtTheSameSideOfDiffractionRay(RayInfo incidentRay, AdjacentEdge sameEdge, Point diffractionPoint) { if (diffractionPoint.equal(sameEdge.StartPoint))//绕射点与棱的开始端点重合 { Point centerPoint = new RayInfo(sameEdge.StartPoint, new SpectVector(sameEdge.EndPoint, sameEdge.StartPoint)).GetPointOnRayVector(1); if (new SpectVector(sameEdge.StartPoint, incidentRay.Origin).GetPhaseOfVector(new SpectVector(sameEdge.StartPoint, centerPoint)) > 90) { return(centerPoint); } else { return(new RayInfo(sameEdge.StartPoint, sameEdge.EndPoint).GetPointOnRayVector(1)); } } else if (diffractionPoint.equal(sameEdge.EndPoint))//绕射点与棱的结束端点重合 { Point centerPoint = new RayInfo(sameEdge.EndPoint, new SpectVector(sameEdge.StartPoint, sameEdge.EndPoint)).GetPointOnRayVector(1); if (new SpectVector(sameEdge.EndPoint, incidentRay.Origin).GetPhaseOfVector(new SpectVector(sameEdge.EndPoint, centerPoint)) > 90) { return(centerPoint); } else { return(new RayInfo(sameEdge.EndPoint, sameEdge.StartPoint).GetPointOnRayVector(1)); } } else { SpectVector vectorOfDiffrationPointToOriginPoint = new SpectVector(diffractionPoint, incidentRay.Origin); //绕射点到发射点的向量 SpectVector vectorOfDiffrationPointToTerSamePoint = new SpectVector(diffractionPoint, sameEdge.StartPoint); //绕射点到棱上一个顶点的向量 if (vectorOfDiffrationPointToOriginPoint.GetPhaseOfVector(vectorOfDiffrationPointToTerSamePoint) > 90) //将圆心设为与绕射方向同向的一个共同点 { return(sameEdge.StartPoint); } else { return(sameEdge.EndPoint); } } }
/// <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); }