/// <summary> ///根据射线与圆柱体的交点确定绕射点范围 /// </summary> /// <param name="crossPoint">射线与圆柱体的交点</param> /// <param name="diffEdge">绕射棱</param> /// <returns>射线与圆柱体的交点确定绕射点范围</returns> private Point[] GetDiffractionNodeRange(Point crossPoint, AdjacentEdge diffEdge) { //a,b,c为棱的方向向量,(x0,y0,z0)为棱上的一点,(x1,y1,z1)为crossPoint //A=a^2+b^2+c^2 //B=2a*(x0-x1)+2b*(y0-y1)+2c*(z0-z1) //C=r^2-(x1^2+y1^2+z1^2)-(x0^2+y0^2+z0^2)+2*xo*x1+2*y0*y1+2*z0*z1; double A = Math.Pow(diffEdge.LineVector.a, 2) + Math.Pow(diffEdge.LineVector.b, 2) + Math.Pow(diffEdge.LineVector.c, 2); double B = 2 * diffEdge.LineVector.a * (diffEdge.StartPoint.X - crossPoint.X) + 2 * diffEdge.LineVector.b * (diffEdge.StartPoint.Y - crossPoint.Y) + 2 * diffEdge.LineVector.c * (diffEdge.StartPoint.Z - crossPoint.Z); double C = -(Math.Pow(diffEdge.DiffCylinderRadius, 2) - (Math.Pow(diffEdge.StartPoint.X, 2) + Math.Pow(diffEdge.StartPoint.Y, 2) + Math.Pow(diffEdge.StartPoint.Z, 2)) - (Math.Pow(crossPoint.X, 2) + Math.Pow(crossPoint.Y, 2) + Math.Pow(crossPoint.Z, 2)) + 2 * diffEdge.StartPoint.X * crossPoint.X + 2 * diffEdge.StartPoint.Y * crossPoint.Y + 2 * diffEdge.StartPoint.Z * crossPoint.Z); double test = Math.Pow(B, 2) - 4 * A * C; if (Math.Pow(B, 2) - 4 * A * C < 0.00000001) { LogFileManager.ObjLog.error("求绕射点范围时出错"); return(null); } else { double t1 = (-B + Math.Sqrt(Math.Pow(B, 2) - 4 * A * C)) / (2 * A); double t2 = (-B - Math.Sqrt(Math.Pow(B, 2) - 4 * A * C)) / (2 * A); return(new Point[2] { new Point(diffEdge.LineVector.a * t1 + diffEdge.StartPoint.X, diffEdge.LineVector.b * t1 + diffEdge.StartPoint.Y, diffEdge.LineVector.c * t1 + diffEdge.StartPoint.Z), new Point(diffEdge.LineVector.a * t2 + diffEdge.StartPoint.X, diffEdge.LineVector.b * t2 + diffEdge.StartPoint.Y, diffEdge.LineVector.c * t2 + diffEdge.StartPoint.Z) }); } }
/// <summary> /// Sets value to the weight of an edge between two vertices in the adjacency list. /// </summary> /// <param name="vStart">The starting vertex.</param> /// <param name="vFinish">The finishing vertex.</param> /// <param name="weight">The weight of the edge.</param> /// <param name="isDirected">Boolean status indicating whether the edge should be directed of undirected.</param> public override void SetEdge(int vStart, int vFinish, double weight, bool isDirected) { if (weight != 0) { AdjacentEdge edge1, edge2; AdjacentEdge edgeToRemove = new AdjacentEdge(); edge1.vertex = vFinish; edge1.weight = weight; edge2.vertex = vStart; edge2.weight = weight; this.EnableVertex(vStart); this.EnableVertex(vFinish); foreach (AdjacentEdge edge in this.list[vStart]) { if (edge.vertex == vFinish) { edgeToRemove = edge; } } this.list[vStart].Remove(edgeToRemove); this.list[vStart].Add(edge1); if (!isDirected) { foreach (AdjacentEdge edge in this.list[vFinish]) { if (edge.vertex == vStart) { edgeToRemove = edge; } } this.list[vFinish].Remove(edgeToRemove); this.list[vFinish].Add(edge2); } } }
/// <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> /// 更新绕射棱范围 /// </summary> /// <param name="triangle">绕射棱前一三角面</param> /// <param name="diffractEdge">要更新的绕射棱</param> /// <param name="point">接收点(与三角面共同确定棱的范围)</param> /// <returns>更新后的绕射棱</returns> private AdjacentEdge GetNewDiffractEdge(Triangle triangle, AdjacentEdge diffractEdge, Point point) { AdjacentEdge newDiffractEdge = new AdjacentEdge(); Point point1 = diffractEdge.GetDiffractionPoint(triangle.Vertices[0], point); Point point2 = diffractEdge.GetDiffractionPoint(triangle.Vertices[1], point); Point point3 = diffractEdge.GetDiffractionPoint(triangle.Vertices[2], point); double distance12 = point1.GetDistance(point2); double distance13 = point1.GetDistance(point3); double distance23 = point2.GetDistance(point3); if (distance12 >= distance13 && distance12 >= distance23) { newDiffractEdge.StartPoint = point1; newDiffractEdge.EndPoint = point2; } else if (distance13 >= distance12 && distance13 >= distance23) { newDiffractEdge.StartPoint = point1; newDiffractEdge.EndPoint = point3; } else { newDiffractEdge.StartPoint = point2; newDiffractEdge.EndPoint = point3; } return(newDiffractEdge); }
/// <inheritdoc /> public override IEnumerator <AdjacentEdge <TEdgeData> > GetEnumerator() { yield return(AdjacentEdge.Create(_destVertexIndex1, _edgeData1)); yield return(AdjacentEdge.Create(_destVertexIndex2, _edgeData2)); yield return(AdjacentEdge.Create(_destVertexIndex3, _edgeData3)); }
/// <inheritdoc /> public override bool AddEdge(ReplaceableVertexFactoryInterface <TEdgeData> vertexFactory, int destVertexIndex, TEdgeData edgeData, out ReplaceableVertexAdjacency <TEdgeData> final) { final = vertexFactory.GetInstance(EnumerableExtensions.Enumerate(AdjacentEdge.Create(destVertexIndex, edgeData)), 1); return(true); }
public void GetDiffractionPointTest7() { AdjacentEdge target = new AdjacentEdge(new Point(0, 0, 1), new Point(0, 0, -1)); // TODO: 初始化为适当的值 Point origin = new Point(-1, 0, 0); // TODO: 初始化为适当的值 Point target1 = new Point(1, 0, 3); // TODO: 初始化为适当的值 Point actual; actual = target.GetDiffractionPoint(origin, target1); Assert.IsTrue(actual == null); }
/// <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//两个交点都是绕射点 { } }
public void GetDiffractionPostionTest8() { Point target = new Point(0, 0, 2); // TODO: 初始化为适当的值 Point otherPoint = new Point(0, 1, 0); // TODO: 初始化为适当的值 AdjacentEdge diffractionEdge = new AdjacentEdge(new Point(0, 0, 1), new Point(0, 0, -1)); // TODO: 初始化为适当的值 Point expected = new Point(0, 0, 0); // TODO: 初始化为适当的值 Point actual; actual = target.GetDiffractionPostion(otherPoint, diffractionEdge); Assert.IsTrue(actual == null); }
public void GetDiffractionPostionTest6() { Point target = new Point(1, 0, 0); // TODO: 初始化为适当的值 Point otherPoint = new Point(0, 0, -1); // TODO: 初始化为适当的值 AdjacentEdge diffractionEdge = new AdjacentEdge(new Point(-1, -1, -1), new Point(1, 1, 1)); // TODO: 初始化为适当的值 Point expected = new Point(0, 0, 0); // TODO: 初始化为适当的值 Point actual; actual = target.GetDiffractionPostion(otherPoint, diffractionEdge); Assert.IsTrue(Math.Abs(expected.X - actual.X) < 0.000001 && Math.Abs(expected.Y - actual.Y) < 0.000001 && Math.Abs(expected.Z - actual.Z) < 0.000001); }
public void GetDiffractionPointTest2() { AdjacentEdge target = new AdjacentEdge(new Point(0, 0, 1), new Point(0, 0, -1)); // TODO: 初始化为适当的值 Point origin = new Point(-1, 0, 0); // TODO: 初始化为适当的值 Point target1 = new Point(-1, 1, 0); // TODO: 初始化为适当的值 Point expected = new Point(0, 0, 0); // TODO: 初始化为适当的值 Point actual; actual = target.GetDiffractionPoint(origin, target1); Assert.IsTrue(Math.Abs(expected.X - actual.X) < 0.000001 && Math.Abs(expected.Y - actual.Y) < 0.000001 && Math.Abs(expected.Z - actual.Z) < 0.000001); }
public void getVectorFromEdge2EdgeWithAngleTest6() { AdjacentEdge target = new AdjacentEdge(new Point(0, 0, 1), new Point(0, 0, -1)); // TODO: 初始化为适当的值 Point beginPoint = new Point(0, 0, -1); // TODO: 初始化为适当的值 double angle = 60; // TODO: 初始化为适当的值 AdjacentEdge targetEdge = new AdjacentEdge(new Point(1, 1, 0), new Point(1, -1, 0)); // TODO: 初始化为适当的值 //RayInfo actual; List <RayInfo> list = new List <RayInfo>(); list = target.getVectorFromEdge2EdgeWithAngle(beginPoint, angle, targetEdge); //actual = target.getVectorFromEdge2EdgeWithAngle(beginPoint, angle, targetEdge); Assert.IsTrue(list.Count == 0); }
/// <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()); } }
/// <inheritdoc /> public override bool AddEdge(ReplaceableVertexFactoryInterface <TEdgeData> vertexFactory, int destVertexIndex, TEdgeData edgeData, out ReplaceableVertexAdjacency <TEdgeData> final) { if (ContainsEdgeToIndex(destVertexIndex)) { final = this; return(false); } final = vertexFactory.GetInstance( this.Append(AdjacentEdge.Create(destVertexIndex, edgeData)), EdgesCount + 1); return(true); }
/// <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> /// 这是一个以某个角度划分获得所设圆上的点的方法 /// </summary> private static List <Point> GetcircumPointOfTheCircle(AdjacentEdge sameEdge, Point circleCenterPoint, double circleRadius, SpectVector unitCircleVectorU, SpectVector unitCircleVectorV, double circleRange, int numberOfCircumPoint) { double angleOfTwoCircumPoint = circleRange * Math.PI / (numberOfCircumPoint * 180);//取点的角度 List <Point> circumPoints = new List <Point>(); //第一个点取一个微小角度,避免与面重合 circumPoints.Add(GetPointInCircumference(circleCenterPoint, circleRadius, unitCircleVectorU, unitCircleVectorV, 0.01)); for (int i = 1; i < numberOfCircumPoint - 1; i++)//在圆上取点,并放到list中 { circumPoints.Add(GetPointInCircumference(circleCenterPoint, circleRadius, unitCircleVectorU, unitCircleVectorV, i * angleOfTwoCircumPoint)); } //最后一个点减少一个微小角度,避免与面重合 circumPoints.Add(GetPointInCircumference(circleCenterPoint, circleRadius, unitCircleVectorU, unitCircleVectorV, circleRange * Math.PI / 180 - 0.01)); return(circumPoints); }
public void getVectorFromEdge2EdgeWithAngleTest3() { AdjacentEdge target = new AdjacentEdge(new Point(0, 0, 1), new Point(0, 0, -1)); // TODO: 初始化为适当的值 Point beginPoint = new Point(0, 0, 0); // TODO: 初始化为适当的值 double angle = 135; // TODO: 初始化为适当的值 AdjacentEdge targetEdge = new AdjacentEdge(new Point(-1, 0, 1), new Point(-1, 0, -1)); // TODO: 初始化为适当的值 RayInfo expected = new RayInfo(new Point(-1, 0, 1), new SpectVector(-1, 0, 1)); // TODO: 初始化为适当的值 RayInfo actual; List <RayInfo> list = new List <RayInfo>(); list = target.getVectorFromEdge2EdgeWithAngle(beginPoint, angle, targetEdge); actual = list[0]; Assert.IsTrue(Math.Abs(expected.Origin.X - actual.Origin.X) < 0.000001 && Math.Abs(expected.Origin.Y - actual.Origin.Y) < 0.000001 && Math.Abs(expected.Origin.Z - actual.Origin.Z) < 0.000001 && Math.Abs(expected.RayVector.a - actual.RayVector.a) < 0.000001 && Math.Abs(expected.RayVector.b - actual.RayVector.b) < 0.000001 && Math.Abs(expected.RayVector.c - actual.RayVector.c) < 0.000001); }
/// <summary> ///得到绕射节点 /// </summary> private Node GetDiffractionChildNode(Node fatherNode, Point position, AdjacentEdge diffractionEdge) { Node diffractionNode = new Node(); diffractionNode.Position = position; diffractionNode.DiffractionEdge = diffractionEdge; diffractionNode.NodeStyle = NodeStyle.DiffractionNode; diffractionNode.LayNum = fatherNode.LayNum + 1; diffractionNode.DiffractionNum = fatherNode.DiffractionNum + 1; diffractionNode.IsReceiver = false; diffractionNode.UAN = fatherNode.UAN; diffractionNode.DistanceToFrontNode = diffractionNode.Position.GetDistance(fatherNode.Position); diffractionNode.RayTracingDistance = fatherNode.RayTracingDistance; diffractionNode.RayTracingDistance += diffractionNode.DistanceToFrontNode; diffractionNode.RayIn = new RayInfo(fatherNode.Position, diffractionNode.Position); return(diffractionNode); }
// Polymorphism (Group A) is implemented here. /// <summary> /// Sets a specified weight of the edge from this vertex to another vertex. /// </summary> /// <param name="v">The destination vertex.</param> /// <param name="weight">The weight of the edge.</param> public void SetEdge(Vertex v, double weight) { AdjacentEdge tempEdge = new AdjacentEdge { vertex = v, weight = weight }; AdjacentEdge edgeToDelete = new AdjacentEdge(); for (int i = 0; i < adjacentEdges.Count; i++) { if (adjacentEdges[i].vertex.Equals(v)) { edgeToDelete = adjacentEdges[i]; } } this.adjacentEdges.Remove(edgeToDelete); this.adjacentEdges.Add(tempEdge); }
/// <summary> ///根据绕射点范围和取点距离取多个绕射点 /// </summary> /// <param name="crossPoint">射线与圆柱体的交点</param> /// <param name="diffEdge">绕射棱</param> /// <returns>在绕射点范围内一定个数的点的list</returns> private List <Point> GetDiffractionNodePoistions(Point crossPoint, AdjacentEdge diffEdge) { Point rightPoint = new RayInfo(crossPoint, diffEdge.EndPoint).GetPointOnRayVector(diffEdge.DiffCylinderRadius); Point leftPoint = new RayInfo(crossPoint, diffEdge.StartPoint).GetPointOnRayVector(diffEdge.DiffCylinderRadius); List <Point> diffPoints = new List <Point> { crossPoint }; diffPoints.AddRange(this.GetSamplingPointsInRange(crossPoint, rightPoint, 5)); diffPoints.AddRange(this.GetSamplingPointsInRange(crossPoint, leftPoint, 5)); for (int i = diffPoints.Count - 1; i >= 0; i--) { if (!diffEdge.JudgeIfPointInLineRange(diffPoints[i]) || diffPoints[i].equal(diffEdge.StartPoint) || diffPoints[i].equal(diffEdge.EndPoint)) { diffPoints.RemoveAt(i); } } return(diffPoints); }
/// <summary> ///根据绕射棱两侧的绕射射线生成绕射追踪模型 /// </summary> /// <param name="fatherPoint">父节点</param> /// <param name="leftRays">左侧的绕射射线</param> /// <param name="rightRays">右侧的绕射射线</param> /// <returns>绕射追踪模型</returns> private List <IRayTracing> GetDiffractionRayFaces(Point diffractionPoint, AdjacentEdge diffractionEdge) { //绕射范围两个端点的位置 Point rightPoint = new RayInfo(diffractionPoint, diffractionEdge.EndPoint).GetPointOnRayVector(diffractionEdge.DiffCylinderRadius); Point leftPoint = new RayInfo(diffractionPoint, diffractionEdge.StartPoint).GetPointOnRayVector(diffractionEdge.DiffCylinderRadius); //将点转成节点 Node leftNode = this.GetDiffractionChildNode(this.fatherNode, leftPoint, diffractionEdge); Node rightNode = this.GetDiffractionChildNode(this.fatherNode, rightPoint, diffractionEdge); //求出左侧节点的绕射射线 List <RayInfo> leftRays = Rays.GetDiffractionRays(this.fatherNode.Position, leftPoint, diffractionEdge, 24); List <IRayTracing> rayFaces = new List <IRayTracing>(); //根据左侧绕射射线生成射线模型 for (int i = 0; i < leftRays.Count; i++) { Point fatherFacePoint = new SpaceFace(diffractionEdge.StartPoint, leftRays[i].RayVector.CrossMultiplied(diffractionEdge.LineVector)).GetSubPointInFace(this.fatherNode.Position); Point fatherMirrorPoint = new RayInfo(rightPoint, fatherFacePoint).GetPointOnRayVector(diffractionEdge.DiffCylinderRadius); RayInfo rightRay = new RayInfo(rightPoint, new SpectVector(fatherMirrorPoint, rightPoint)); rayFaces.Add(new FaceRay(leftNode, rightNode, leftRays[i], rightRay)); } return(rayFaces); }
/// <summary> /// Removes an edge between two vertices in the adjacency list. /// </summary> /// <param name="vStart">The starting vertex.</param> /// <param name="vFinish">The finishing vertex.</param> /// <param name="isDirected">bool status indicating whether the egde in both directions should be removed.</param> public override void RemoveEdge(int vStart, int vFinish, bool isDirected) { AdjacentEdge edgeToRemove = new AdjacentEdge(); foreach (AdjacentEdge edge in this.list[vStart]) { if (edge.vertex == vFinish) { edgeToRemove = edge; } } this.list[vStart].Remove(edgeToRemove); if (!isDirected) { foreach (AdjacentEdge edge in this.list[vFinish]) { if (edge.vertex == vStart) { edgeToRemove = edge; } } this.list[vFinish].Remove(edgeToRemove); } }
/// <summary> /// 求空间衰减的扩散因子Ad,文档公式2 /// </summary> private static double GetSpreadFactor(Point originPoint, AdjacentEdge sameEdge, Point diffrationPoint, Point viewPoint, double waveLength) { double distanceOfOriginAndSameLine = originPoint.GetDistanceToLine(sameEdge.StartPoint, sameEdge.LineVector);//辐射源到公共棱的距离 double s1 = originPoint.GetDistance(diffrationPoint); double s2 = diffrationPoint.GetDistance(viewPoint); double Ad; if (s2 == 0)//若观察点为绕射点 { Ad = 1; } else { if (distanceOfOriginAndSameLine > (10 * waveLength)) //源点要绕射点的距离大于10个波长 { Ad = 1 / (Math.Sqrt(s2)); //平面波和柱面波入射时的扩散因子 } else { Ad = Math.Sqrt(s1 / (s2 * (s1 + s2)));//球面波入射时的扩散因子 } } return(Ad); }
/// <summary> /// 求绕射的入射面 /// </summary> /// <param name="diffractionFace1">绕射棱的第一个面</param> /// <param name="diffractionFace2">绕射棱的第二个面</param> /// <param name="diffractionRayFace">入射射线与棱构成的面</param> /// <param name="sameEdge">棱</param> /// <returns>入射面</returns> private static Face GetTheFrontFace(Face diffractionFace1, Face diffractionFace2, Face rayFace, AdjacentEdge sameEdge) { double angleOfDiffraction1FaceAndRayFace = GetAngleOfTwoTers(diffractionFace1, rayFace, sameEdge); double angleOfDiffraction2FaceAndRayFace = GetAngleOfTwoTers(diffractionFace2, rayFace, sameEdge); if (angleOfDiffraction1FaceAndRayFace < angleOfDiffraction2FaceAndRayFace) { return(diffractionFace1); } return(diffractionFace2); }
/// <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> ///求启发式绕射系数,文档公式3,5 /// </summary> private static Plural GetDiffractionFactor(RayInfo ray, Face diffractionFace1, Face diffractionFace2, AdjacentEdge sameEdge, Point diffractionPoint, Point viewPoint, double waveLength, bool judgeVerticallyPolarizedWave) { Plural D = new Plural(); //求a1,a2 Face rayFace = new SpaceFace(sameEdge.StartPoint, sameEdge.EndPoint, ray.Origin); Face diffractionRayFace = new SpaceFace(sameEdge.StartPoint, sameEdge.EndPoint, viewPoint); Face frontFace = GetTheFrontFace(diffractionFace1, diffractionFace2, rayFace, sameEdge);//先与射线相交的三角面 Face laterFace = diffractionFace2; if (frontFace != diffractionFace1) { laterFace = diffractionFace1;//后相交的三角面 } double a1 = GetAngleOfTwoTers(frontFace, rayFace, sameEdge) * Math.PI / 180; double a2; if (ray.Origin.JudgeIsConcaveOrConvexToViewPoint(frontFace, diffractionRayFace))//若两个三角面的形状是凸的 { double angleWithFront = GetAngleOfTwoTers(frontFace, diffractionRayFace, sameEdge); double angleWithLater = GetAngleOfTwoTers(laterFace, diffractionRayFace, sameEdge); if (angleWithFront < angleWithLater) { a2 = angleWithFront * Math.PI / 180; } else { a2 = (360 - angleWithFront) * Math.PI / 180; } } else//若两个三角面的形状是凹的 { a2 = GetAngleOfTwoTers(frontFace, diffractionRayFace, sameEdge) * Math.PI / 180; } //求n double angleOfTwoTers = GetAngleOfTwoTers(diffractionFace1, diffractionFace2, sameEdge); double n = 2 - (angleOfTwoTers / 180);//n=2-a/pi,其中a为两个三角面的夹角 //求ri double[] r = new double[4]; r[0] = (Math.PI - (a2 - a1)) / (2 * n); r[1] = (Math.PI + (a2 - a1)) / (2 * n); r[2] = (Math.PI - (a2 + a1)) / (2 * n); r[3] = (Math.PI + (a2 + a1)) / (2 * n); //求k double k = 2 * Math.PI / waveLength;//波矢量 //求L double L = GetDistanceParameter(ray.Origin, diffractionPoint, sameEdge, viewPoint, waveLength); //求Di Plural[] Di = new Plural[4]; Plural minusepi4 = new Plural(-Math.Sqrt(2) / 2, Math.Sqrt(2) / 2); for (int i = 0; i < 4; i++) { Di[i] = Plural.PluralMultiplyDouble(minusepi4 * GetTransitionFunction(2 * k * L * Math.Pow(n, 2) * Math.Pow(Math.Sin(r[i]), 2)), 1 / (Math.Tan(r[i]) * (2 * n * Math.Sqrt(2 * k * Math.PI)))); } //求反射系数R RayInfo diffractionRay = new RayInfo(diffractionPoint, viewPoint); Plural Ro = GetReflectionCoefficient(ray, frontFace, a1, waveLength, judgeVerticallyPolarizedWave); Plural Rn = GetReflectionCoefficient(diffractionRay, laterFace, n * Math.PI - a2, waveLength, judgeVerticallyPolarizedWave); D = Di[0] + Di[1] * Ro * Rn + Di[2] * Ro + Di[3] * Rn; return(D); }
/// <summary> /// 利用反向算法得到含有两次不相邻绕射的路径中的各个点详细位置信息 /// </summary> /// <param name="path">传入要计算的路径</param> /// <param name="indexOfEdge1">第一次绕射节点所在下标位置信息</param> /// <param name="indexOfEdge2">第二次绕射节点所在下标位置信息</param> /// <returns>按路径经过顺序存储的各个点的坐标</returns> private List <Point> GetPointsOfContainTwoNoAdjacentDiffractPath(Path path, int indexOfEdge1, int indexOfEdge2) { List <Point> pointList = new List <Point>(path.node.Count - 2); Stack <Triangle> reflectTrianglesBeforeDiffract = new Stack <Triangle>(), reflectTrianglesForMirrorBeforeDiffract = new Stack <Triangle>(), reflectTrianglesAfterDiffract = new Stack <Triangle>(), reflectTrianglesForMirrorAfterDiffract = new Stack <Triangle>(), reflectTrianglesBetweenDiffract = new Stack <Triangle>(); Stack <Point> mirrorPointsBeforeDiffract = new Stack <Point>(), mirrorPointsAfterDiffract = new Stack <Point>(), mirrorPointsBetweenDiffract = new Stack <Point>(); Stack <AdjacentEdge> mirrorDiffractEdge = new Stack <AdjacentEdge>(); //预处理绕射棱前后的三角面和点 this.DealTrianglesAndPointsBeforeAndAfterDiffractEdge(path, indexOfEdge1, indexOfEdge2, reflectTrianglesBeforeDiffract, reflectTrianglesAfterDiffract, mirrorPointsBeforeDiffract, mirrorPointsAfterDiffract); //求绕射两棱前后的镜像点 this.PushTrianglesAndMirrorPoints(reflectTrianglesBeforeDiffract, reflectTrianglesForMirrorBeforeDiffract, mirrorPointsBeforeDiffract); this.PushTrianglesAndMirrorPoints(reflectTrianglesAfterDiffract, reflectTrianglesForMirrorAfterDiffract, mirrorPointsAfterDiffract); mirrorPointsBetweenDiffract.Push(mirrorPointsBeforeDiffract.Peek()); mirrorDiffractEdge.Push(path.node[indexOfEdge1].DiffractionEdge); AdjacentEdge updatedDiffractEdge2 = path.node[indexOfEdge2].DiffractionEdge; AdjacentEdge tempDiffractEdge2 = this.GetNewDiffractEdge(path.node[indexOfEdge2 - 1].ReflectionFace, path.node[indexOfEdge2].DiffractionEdge, mirrorPointsAfterDiffract.Peek());//利用绕射棱前一三角面更新绕射棱信息 updatedDiffractEdge2.StartPoint = tempDiffractEdge2.StartPoint; updatedDiffractEdge2.EndPoint = tempDiffractEdge2.EndPoint; //作点和第一绕射棱关于两绕射棱之间的面的镜像 for (int i = indexOfEdge1 + 1; i < indexOfEdge2; i++) { reflectTrianglesBetweenDiffract.Push(path.node[i].ReflectionFace); mirrorPointsBetweenDiffract.Push(mirrorPointsBetweenDiffract.Peek().GetMirrorPoint(reflectTrianglesBetweenDiffract.Peek())); mirrorDiffractEdge.Push(new AdjacentEdge(mirrorDiffractEdge.Peek().StartPoint.GetMirrorPoint(reflectTrianglesBetweenDiffract.Peek()), mirrorDiffractEdge.Peek().EndPoint.GetMirrorPoint(reflectTrianglesBetweenDiffract.Peek()))); } List <Point> diffractPoints = this.GetTwoDiffractionPoints(mirrorDiffractEdge.Pop(), updatedDiffractEdge2, mirrorPointsBetweenDiffract.Pop(), mirrorPointsAfterDiffract.Peek()); pointList[indexOfEdge2 - 1] = diffractPoints[1]; //第二绕射棱上绕射点坐标 pointList[indexOfEdge2 - 2] = this.GetReflectPoint(diffractPoints[0], diffractPoints[1], reflectTrianglesBetweenDiffract.Pop()); if (pointList[indexOfEdge2 - 2] == null) //判断绕射棱前一三角面的反射点是否存在 { return(new List <Point>()); } if (reflectTrianglesBetweenDiffract.Count != 0)//两绕射棱间是否有未处理三角面 { pointList[indexOfEdge2 - 3] = this.GetReflectPoint(mirrorDiffractEdge.Pop().GetDiffractionPoint(mirrorPointsBetweenDiffract.Pop(), pointList[indexOfEdge2 - 2]), pointList[indexOfEdge2 - 2], reflectTrianglesBetweenDiffract.Pop()); if (pointList[indexOfEdge2 - 3] == null) { return(new List <Point>()); } } pointList[indexOfEdge1 - 1] = path.node[indexOfEdge1]. DiffractionEdge.GetDiffractionPoint(mirrorPointsBeforeDiffract.Peek(), pointList[indexOfEdge1]); if (reflectTrianglesBeforeDiffract.Count != 0)//第一条棱前是否有反射点 { pointList[indexOfEdge1 - 2] = this.GetReflectPoint( mirrorPointsBeforeDiffract.Pop(), pointList[indexOfEdge1 - 1], reflectTrianglesBeforeDiffract.Pop()); if (pointList[indexOfEdge1 - 2] == null) { return(new List <Point>()); } } if (reflectTrianglesAfterDiffract.Count != 0)//第二条棱后是否有反射点 { pointList[indexOfEdge2] = this.GetReflectPoint(pointList[indexOfEdge2 - 1], mirrorPointsAfterDiffract.Pop(), reflectTrianglesAfterDiffract.Pop()); if (pointList[indexOfEdge2] == null) { return(new List <Point>()); } } return(pointList); }
/// <summary> /// 计算两次绕射的绕射点 /// </summary> /// <param name="edge1">第一条绕射棱</param> /// <param name="edge2">第二条绕射棱</param> /// <param name="beginPoint">第一条绕射棱前的点</param> /// <param name="endPoint">第二条绕射棱后的点</param> /// <returns>用List的形式返回两个点的坐标</returns> private List <Point> GetTwoDiffractionPoints(AdjacentEdge edge1, AdjacentEdge edge2, Point beginPoint, Point endPoint) { Point p1 = edge1.GetDiffractionPoint(beginPoint, edge2.StartPoint); Point p2 = edge1.GetDiffractionPoint(beginPoint, edge2.EndPoint); Point p21 = edge2.StartPoint; Point p22 = edge2.EndPoint; AdjacentEdge tempLine = new AdjacentEdge(new Point(-10000 * edge2.LineVector.a + endPoint.X, -10000 * edge2.LineVector.b + endPoint.Y, -10000 * edge2.LineVector.c + endPoint.Z), new Point(10000 * edge2.LineVector.a + endPoint.X, 10000 * edge2.LineVector.b + endPoint.Y, 10000 * edge2.LineVector.c + endPoint.Z), edge2.LineVector); double angle1 = SpectVector.VectorPhase(new SpectVector(p1, edge2.StartPoint), edge2.LineVector); double angle2 = SpectVector.VectorPhase(new SpectVector(p2, edge2.EndPoint), edge2.LineVector); SpectVector sp1 = edge2.getVectorFromEdge2EdgeWithAngle(p1, angle1, tempLine).RayVector; SpectVector sp2 = edge2.getVectorFromEdge2EdgeWithAngle(p2, angle2, tempLine).RayVector; RayInfo ray1 = new RayInfo(p1, sp1); RayInfo ray2 = new RayInfo(p2, sp2); Point dropFoot1 = ray1.getDropFoot(endPoint); Point dropFoot2 = ray2.getDropFoot(endPoint); double distance1 = endPoint.GetDistance(dropFoot1); double distance2 = endPoint.GetDistance(dropFoot2); List <Point> diffractPoints = new List <Point>(); int i = 20; while (i-- > 0) { if (distance1 < 0.00001) { diffractPoints.Add(p1); diffractPoints.Add(p21); break; } if (distance2 < 0.00001) { diffractPoints.Add(p2); diffractPoints.Add(p22); break; } Point tempPoint = new Point((p1.X + p2.X) / 2, (p1.Y + p2.Y) / 2, (p1.Z + p2.Z) / 2); double tempAngle1 = SpectVector.VectorPhase(new SpectVector(beginPoint, tempPoint), edge1.LineVector); RayInfo tempRay1 = edge1.getVectorFromEdge2EdgeWithAngle(tempPoint, tempAngle1, edge2); double tempAngle2 = SpectVector.VectorPhase(tempRay1.RayVector, edge2.LineVector); RayInfo tempRay2 = edge2.getVectorFromEdge2EdgeWithAngle(tempRay1.Origin, tempAngle2, tempLine); Point tempDropFoot = new RayInfo(tempRay1.Origin, tempRay2.RayVector).getDropFoot(endPoint); double tempDistance = tempDropFoot.GetDistance(endPoint); SpectVector tempSP1 = new SpectVector(dropFoot1, edge2.StartPoint); SpectVector tempSP2 = new SpectVector(dropFoot2, edge2.StartPoint); SpectVector tempSP3 = new SpectVector(tempDropFoot, edge2.StartPoint); SpectVector tempSP4 = new SpectVector(endPoint, edge2.StartPoint); double endAngle12 = SpectVector.VectorPhase(tempSP1, tempSP2); double endAngle13 = SpectVector.VectorPhase(tempSP1, tempSP3); double endAngle23 = SpectVector.VectorPhase(tempSP2, tempSP3); double endAngle14 = SpectVector.VectorPhase(tempSP1, tempSP4); if (endAngle14 > endAngle13) { p1 = tempPoint; angle1 = tempAngle2; p21 = tempRay1.Origin; dropFoot1 = tempDropFoot; distance1 = tempDistance; } else if (endAngle14 < endAngle13) { p2 = tempPoint; angle2 = tempAngle2; p22 = tempRay1.Origin; dropFoot2 = tempDropFoot; distance2 = tempDistance; } else { if (distance1 < 0.1) { diffractPoints.Add(p1); diffractPoints.Add(p21); break; } if (distance2 < 0.1) { diffractPoints.Add(p2); diffractPoints.Add(p22); break; } throw new Exception("二次绕射反向问题"); } } return(diffractPoints); }
/// <inheritdoc /> public VertexAdjacency <TEdgeData> GetInstance(IEnumerable <AdjacentEdge <TEdgeData> > edgesTo, int edgesCount) { return(_wrapped.GetInstance(edgesTo.Select(e => AdjacentEdge.Create(_translator.GetDestIndex(e.Destination), e.Data)), edgesCount)); }