/// <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 <IRayTracing> GetReflectionModel(Node reflectionNode) { if (reflectionNode.ReflectionFace == null) { LogFileManager.ObjLog.error("求反射射线时没有得到反射面"); return(new List <IRayTracing>()); } else { List <IRayTracing> reflectionModel = new List <IRayTracing>(); RayInfo reflectionRay = this.inRay.GetReflectionRay(reflectionNode.ReflectionFace, reflectionNode.Position); reflectionModel.Add(new LineRay(reflectionRay, reflectionNode)); return(reflectionModel); } }
/// <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 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; }
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); }
public RayInfo GetClosestPoint(Transform trans, Vector3 pos, Vector3 dir) { RayInfo curray = new RayInfo(); RaycastHit hit2; int oldLayer = trans.gameObject.layer; // Change this trans.gameObject.layer = 14; if (Physics.Raycast(pos - dir, dir, out hit2, dir.magnitude * 2, CurrentSpotLayer)) { curray.point = hit2.point; curray.normal = hit2.normal; if (!Physics.Linecast(HandTrans.position + transform.rotation * new Vector3(0, 0.05f, -0.05f), curray.point + new Vector3(0, 0.5f, 0), out hit2, CheckLayersReachable)) { if (!Physics.Linecast(curray.point - Quaternion.Euler(new Vector3(0, 90, 0)) * curray.normal * 0.35f + 0.1f * curray.normal, curray.point + Quaternion.Euler(new Vector3(0, 90, 0)) * curray.normal * 0.35f + 0.1f * curray.normal, out hit2, CheckLayersForObstacle)) { if (!Physics.Linecast(curray.point + Quaternion.Euler(new Vector3(0, 90, 0)) * curray.normal * 0.35f + 0.1f * curray.normal, curray.point - Quaternion.Euler(new Vector3(0, 90, 0)) * curray.normal * 0.35f + 0.1f * curray.normal, out hit2, CheckLayersForObstacle)) { curray.CanGoToPoint = true; } else { curray.CanGoToPoint = false; } } else { curray.CanGoToPoint = false; } } else { curray.CanGoToPoint = false; } trans.gameObject.layer = oldLayer; return(curray); } else { trans.gameObject.layer = oldLayer; return(curray); } }
/// <summary> ///得到DiffractionPoint节点,并加入child节点的子节点List中 /// </summary> private void GetDiffractionNode(Node fatherNode, Node cylinderCrossNode, Terrain ter, City cityBuilding, ReceiveBall rxBall, double rayBeamAngle, List <FrequencyBand> txFrequencyBand) { Point diffractionPoint = new RayInfo(cylinderCrossNode.DiffractionEdge.StartPoint, cylinderCrossNode.DiffractionEdge.LineVector).GetFootPointWithSkewLine(this.inRay); if (!cylinderCrossNode.DiffractionEdge.JudgeIfPointInLineRange(diffractionPoint))//若绕射点不在棱内 { return; } else { List <Point> diffPostions = this.GetDiffractionNodePoistions(diffractionPoint, cylinderCrossNode.DiffractionEdge); for (int i = 0; i < diffPostions.Count; i++) { Node diffractionNode = new Node(); diffractionNode.Position = diffPostions[i]; diffractionNode.DiffractionEdge = cylinderCrossNode.DiffractionEdge; diffractionNode.DisranceToEdge = diffractionPoint.GetDistanceToLine(cylinderCrossNode.DiffractionEdge.StartPoint, cylinderCrossNode.DiffractionEdge.LineVector); diffractionNode.NodeStyle = NodeStyle.DiffractionNode; diffractionNode.LayNum = fatherNode.LayNum + 1; diffractionNode.DiffractionNum = fatherNode.DiffractionNum + 1; diffractionNode.IsReceiver = false; diffractionNode.UAN = rxBall.UAN; diffractionNode.DistanceToFrontNode = diffractionNode.Position.GetDistance(fatherNode.Position); diffractionNode.RayTracingDistance = fatherNode.RayTracingDistance; diffractionNode.RayTracingDistance += diffractionNode.DistanceToFrontNode; diffractionNode.RayIn = new RayInfo(fatherNode.Position, diffractionNode.Position); //当新节点的层数加绕射次数不小于4或者绕射次数大于2,说明该路径已经过三次反射(或两次反射一次绕射)或者两次绕射,舍弃并追踪下一条射线 //将该节点设为end if ((diffractionNode.DiffractionNum >= 2) || ((diffractionNode.LayNum + diffractionNode.DiffractionNum) >= 4)) { diffractionNode.IsEnd = true; } //否则,递归调用该函数继续追踪射线 else { diffractionNode.IsEnd = false; fatherNode.ChildNodes.Add(diffractionNode); List <RayInfo> diffractionRays = Rays.GetDiffractionRays(fatherNode.Position, diffractionNode.Position, diffractionNode.DiffractionEdge, 36);//采用新的方法获得绕射射线 for (int j = 0; j < diffractionRays.Count; j++) { PunctiformPath newPath = new PunctiformPath(diffractionRays[j], ter); newPath.SetPunctiformRayPathNodes(diffractionNode, ter, rxBall, cityBuilding, rayBeamAngle, txFrequencyBand); } } } } }
/// <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); } }
// Update is called once per frame void LateUpdate() { float startingAngle = transform.eulerAngles.y - viewAngle / 2; float angleIncrement = viewAngle / meshPartitionsCount; List <RayInfo> rays = new List <RayInfo>(); Collider prevCollider = null; for (int i = 0; i < meshPartitionsCount + 1; ++i) { Vector3 rayDirection = AngleToDir(startingAngle + i * angleIncrement); float rayLenght = viewDistance; RaycastHit hit; if (Physics.Raycast(transform.position, rayDirection, out hit, viewDistance, objectsLayerMask)) { rayLenght = hit.distance; } RayInfo ray = new RayInfo(rayDirection, startingAngle + i * angleIncrement, rayLenght, hit.collider); bool hitOneObstacle = prevCollider == null && hit.collider != null || prevCollider != null && hit.collider == null; bool hitTwoObstacles = prevCollider != hit.collider && prevCollider != null && hit.collider != null; if (i > 0 && meshEdgeResolution > 0 && (hitOneObstacle || hitTwoObstacles)) { KeyValuePair <RayInfo, RayInfo> twoRays = FindCloseEdgeRays(rays[i - 1], ray); rays.Add(twoRays.Key); rays.Add(twoRays.Value); } rays.Add(ray); prevCollider = hit.collider; } if (debugRay) { foreach (RayInfo ri in rays) { Debug.DrawRay(transform.position, ri.rayDirection * ri.rayLenght, Color.red); } } GenerateMesh(rays); //meshTransform.localRotation = transform.localRotation; }
/// <summary> ///获取绕射模型 /// </summary> private List <IRayTracing> GetDiffractionModel(Node diffractionNode) { Point diffractionPoint = new RayInfo( diffractionNode.DiffractionEdge.StartPoint, diffractionNode.DiffractionEdge.LineVector ).GetFootPointWithSkewLine(this.inRay); if (!diffractionNode.DiffractionEdge.JudgeIfPointInLineRange(diffractionPoint))//若绕射点不在棱内 { return(new List <IRayTracing>()); } else { List <IRayTracing> rayFaces = this.GetDiffractionRayFaces(diffractionPoint, diffractionNode.DiffractionEdge); return(rayFaces); } }
/// <summary> ///全向静态发射射线,对每个三角形进行追踪 /// </summary> /// <param name="units">处理单元</param> /// <param name="pathInfo">路径</param> /// <param name="currentNode">节点</param> /// <param name="ter">地形</param> /// <param name="reArea">态势区域</param> /// <param name="cityBuilding">建筑物</param> /// <param name="N">初始细分点个数</param> /// <param name="TxFrequencyBand">发射机频段信息</param> /// <returns></returns> private void HandleEachSurface(List <RayTracingModel> units, List <Path> pathInfo, Node tx, ReceiveArea reArea, Terrain ter, City cityBuilding, int N, List <FrequencyBand> txFrequencyBand) { double PA = 4 / (Math.Sqrt(10 + 2 * Math.Sqrt(5))); double AW = (PA / 2) / Math.Sin(36 * Math.PI / 180); for (int num = 0; num < units.Count; num++) { List <Point> vertex = this.GetSubDivisionPoints(units[num], N); for (int i = 0; i < vertex.Count; i++) { RayInfo param = new RayInfo(tx.Position, new SpectVector(vertex[i].X, vertex[i].Y, vertex[i].Z)); List <Path> path = this.GetSingleRayPaths(tx, ter, reArea, cityBuilding, param, txFrequencyBand); if (path.Count != 0) { pathInfo.AddRange(path); } } } }
/// <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--; }
RayInfo GetClosestPoint(Transform _tranform, Vector3 _direction, Vector3 _position) { RayInfo _currentRayInfo = new RayInfo(); RaycastHit _hit; int _oldLayer = _tranform.gameObject.layer; _tranform.gameObject.layer = 14;// change this shit if (Physics.Raycast(_position - _direction, _direction, out _hit, _direction.magnitude * 2, currentSpotLayer)) { _currentRayInfo.Point = _hit.point; _currentRayInfo.Normal = _hit.normal; if (!Physics.Linecast(handTransform.position + transform.rotation * new Vector3(0, .05f, .05f), _currentRayInfo.Point + new Vector3(0, .5f, 0), out _hit, checkLayerReachable)) { if (!Physics.Linecast(_currentRayInfo.Point - Quaternion.Euler(new Vector3(0, 90, 0)) * _currentRayInfo.Normal * .35f + .1f * _currentRayInfo.Normal, _currentRayInfo.Point + Quaternion.Euler(new Vector3(0, 90, 0)) * _currentRayInfo.Normal * .35f + .1f * _currentRayInfo.Normal, out _hit, checkLayerObstacle)) { if (!Physics.Linecast(_currentRayInfo.Point + Quaternion.Euler(new Vector3(0, 90, 0)) * _currentRayInfo.Normal * .35f + .1f * _currentRayInfo.Normal, _currentRayInfo.Point - Quaternion.Euler(new Vector3(0, 90, 0)) * _currentRayInfo.Normal * .35f + .1f * _currentRayInfo.Normal, out _hit, checkLayerObstacle)) { _currentRayInfo.CanGoToPoint = true; } else { SetGoToPointFalse(); } } else { SetGoToPointFalse(); } } else { SetGoToPointFalse(); } _tranform.gameObject.layer = _oldLayer; return(_currentRayInfo); } else { _tranform.gameObject.layer = _oldLayer; return(_currentRayInfo); } }
/// <summary> /// 查找墙边点 改变状态 /// </summary> /// <param name="h">所使用检测到的射线</param> /// <param name="sort">当前的状态</param> public void FindSpot(RaycastHit h, CheckingSort sort) { //若是该攀爬点跟世界的角度过大(过于倾斜),则不能抓 if (Vector3.Angle(h.normal, Vector3.up) < MaxAngle) { if (sort == CheckingSort.nomal) { nextClimbPoint = GetClosetPoint(h.transform, h.point + new Vector3(0, -0.01f, 0), transform.forward / 2.5f); } else if (sort == CheckingSort.turning) { nextClimbPoint = GetClosetPoint(h.transform, h.point + new Vector3(0, -0.01f, 0), transform.forward / 2.5f - transform.right * Input.GetAxis("Horizontal")); } else if (sort == CheckingSort.falling) { nextClimbPoint = GetClosetPoint(h.transform, h.point + new Vector3(0, -0.01f, 0), -transform.forward / 2.5f); } Debug.Log("nextClimbPoint111111111 = " + nextClimbPoint.point); } }
/// <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="h">所使用检测到的射线</param> /// <param name="sort">当前的状态</param> #region public void FindSpot(RaycastHit h, CheckingSort sort) { //若是该攀爬点跟世界的角度过大(过于倾斜),则不能抓 if (Vector3.Angle(h.normal, Vector3.up) < MaxAngle) { RayInfo ray = new RayInfo(); if (sort == CheckingSort.nomal) { ray = GetClosetPoint(h.transform, h.point + new Vector3(0, -0.01f, 0), transform.forward / 2.5f); } else if (sort == CheckingSort.turning) { ray = GetClosetPoint(h.transform, h.point + new Vector3(0, -0.01f, 0), transform.forward / 2.5f - transform.right * Input.GetAxis("Horizontal")); } else if (sort == CheckingSort.falling) { ray = GetClosetPoint(h.transform, h.point + new Vector3(0, -0.01f, 0), -transform.forward / 2.5f); } TargetPoint = ray.point; TargetNormal = ray.nomal; //如果该点能攀爬 if (ray.CanGoToPoint) { //若不是攀爬状态,并且不是爬动状态 if (currentSort != Climbingsort.Climbing && currentSort != Climbingsort.ClimbingTowardsPoint) { //爬向最近的spot.爬动时人物控制取消,刚体取消,不在地上 Debug.Log("FindSpot::找到要爬的点了 TargetPoint = " + TargetPoint); rigid.isKinematic = true; TPUC.enabled = false; TPC.m_IsGrounded = false; } currentSort = Climbingsort.ClimbingTowardsPoint; BeginDistance = Vector3.Distance(transform.position, (TargetPoint - transform.rotation * HandTrans.localPosition)); } } }
/// <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); } } }
public void ReflectEfieldTest11() { EField e = new EField(new Plural(0, 0), new Plural(1, 0), new Plural(1, 0)); // TODO: 初始化为适当的值 RayInfo rayIn = new RayInfo(new Point(0, 0, 0), new Point(1, 0, 0)); // TODO: 初始化为适当的值 Face face = new SpaceFace(new Point(6, -2, 3), new Point(6, -2, -3), new Point(6 + 4 / Math.Sqrt(3), 2, 0)); RayInfo rayOut = new RayInfo(new Point(0, 0, 0), new Point(-1, Math.Sqrt(3), 0)); // TODO: 初始化为适当的值 SpectVector l = face.GetNormalVector(); // TODO: 初始化为适当的值 double Conduct = 10000000; // TODO: 初始化为适当的值 double Epara = 0; // TODO: 初始化为适当的值 double s1 = 1; // TODO: 初始化为适当的值 double s2 = 1; // TODO: 初始化为适当的值 double f = 1000; // TODO: 初始化为适当的值 EField expected = new EField(new Plural(0.216525636623664, 0.374928007347336), new Plural(0.125011134591127, 0.216464785968714), new Plural(0.250016703089389, 0.432950353731651)); // TODO: 初始化为适当的值 EField actual = new EField(); actual = ReflectEfieldCal.ReflectEfield(e, rayIn, rayOut, l, Conduct, Epara, s1, s2, f); Assert.IsTrue(Math.Abs(actual.X.Re - expected.X.Re) < 0.0000001 && Math.Abs(actual.X.Im - expected.X.Im) < 0.0000001 && Math.Abs(actual.Y.Re - expected.Y.Re) < 0.0000001 && Math.Abs(actual.Y.Im - expected.Y.Im) < 0.0000001 && Math.Abs(actual.Z.Re - expected.Z.Re) < 0.0000001 && Math.Abs(actual.Z.Im - expected.Z.Im) < 0.0000001); //Assert.Inconclusive("验证此测试方法的正确性。"); }
public void ReflectEfieldTest9() { EField e = new EField(new Plural(0, 0), new Plural(1, 0), new Plural(1, 0)); // TODO: 初始化为适当的值 RayInfo rayIn = new RayInfo(new Point(0, 0, 0), new Point(1, 0, 0)); // TODO: 初始化为适当的值 Face face = new SpaceFace(new Point(6, -2, 3), new Point(6, -2, -3), new Point(6 + 4 * Math.Sqrt(3), 2, 0)); RayInfo rayOut = new RayInfo(new Point(0, 0, 0), new Point(1, Math.Sqrt(3), 0)); // TODO: 初始化为适当的值 SpectVector l = face.GetNormalVector(); // TODO: 初始化为适当的值 double Conduct = 0; // TODO: 初始化为适当的值 double Epara = 80.4; // TODO: 初始化为适当的值 double s1 = 1; // TODO: 初始化为适当的值 double s2 = 1; // TODO: 初始化为适当的值 double f = 1000; // TODO: 初始化为适当的值 EField expected = new EField(new Plural(0.137839140789951, 0.238744395119831), new Plural(-0.0795814650399449, -0.137839140789949), new Plural(0.223473914142364, 0.387068173460853)); // TODO: 初始化为适当的值 EField actual = new EField(); actual = ReflectEfieldCal.ReflectEfield(e, rayIn, rayOut, l, Conduct, Epara, s1, s2, f); Assert.IsTrue(Math.Abs(actual.X.Re - expected.X.Re) < 0.0000001 && Math.Abs(actual.X.Im - expected.X.Im) < 0.0000001 && Math.Abs(actual.Y.Re - expected.Y.Re) < 0.0000001 && Math.Abs(actual.Y.Im - expected.Y.Im) < 0.0000001 && Math.Abs(actual.Z.Re - expected.Z.Re) < 0.0000001 && Math.Abs(actual.Z.Im - expected.Z.Im) < 0.0000001); //Assert.Inconclusive("验证此测试方法的正确性。"); }
public void ReflectEfieldTest12() { EField e = new EField(new Plural(0, 0), new Plural(1, 0), new Plural(1, 0)); // TODO: 初始化为适当的值 RayInfo rayIn = new RayInfo(new Point(0, 0, 0), new Point(1, 0, 0)); // TODO: 初始化为适当的值 Face face = new SpaceFace(new Point(6, -2, 3), new Point(6, -2, -3), new Point(10, 2, 0)); RayInfo rayOut = new RayInfo(new Point(0, 0, 0), new Point(0, 1, 0)); // TODO: 初始化为适当的值 SpectVector l = face.GetNormalVector(); // TODO: 初始化为适当的值 double Conduct = 10000000; // TODO: 初始化为适当的值 double Epara = 0; // TODO: 初始化为适当的值 double s1 = 1; // TODO: 初始化为适当的值 double s2 = 1; // TODO: 初始化为适当的值 double f = 1000; // TODO: 初始化为适当的值 EField expected = new EField(new Plural(0.2500272723013, 0.432910889925977), new Plural(0, 0), new Plural(0.25001363855995, 0.432961794520133)); // TODO: 初始化为适当的值 EField actual = new EField(); actual = ReflectEfieldCal.ReflectEfield(e, rayIn, rayOut, l, Conduct, Epara, s1, s2, f); Assert.IsTrue(Math.Abs(actual.X.Re - expected.X.Re) < 0.0000001 && Math.Abs(actual.X.Im - expected.X.Im) < 0.0000001 && Math.Abs(actual.Y.Re - expected.Y.Re) < 0.0000001 && Math.Abs(actual.Y.Im - expected.Y.Im) < 0.0000001 && Math.Abs(actual.Z.Re - expected.Z.Re) < 0.0000001 && Math.Abs(actual.Z.Im - expected.Z.Im) < 0.0000001); //Assert.Inconclusive("验证此测试方法的正确性。"); }
/// <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); }
public void ReflectEfieldTest14() { EField e = new EField(new Plural(0, 0), new Plural(1, 0), new Plural(1, 0)); // TODO: 初始化为适当的值 RayInfo rayIn = new RayInfo(new Point(0, 0, 0), new Point(1, 0, 0)); // TODO: 初始化为适当的值 Face face = new SpaceFace(new Point(6, -2, 3), new Point(6, -2, -3), new Point(10, 2, 0)); RayInfo rayOut = new RayInfo(new Point(0, 0, 0), new Point(0, 1, 0)); // TODO: 初始化为适当的值 SpectVector l = face.GetNormalVector(); // TODO: 初始化为适当的值 double Conduct = 0; // TODO: 初始化为适当的值 double Epara = 1 / 80.4; // TODO: 初始化为适当的值 double s1 = 1; // TODO: 初始化为适当的值 double s2 = 1; // TODO: 初始化为适当的值 double f = 1000; // TODO: 初始化为适当的值 EField expected = new EField(new Plural(-0.26082694568263, -0.426578602845795), new Plural(0, 0), new Plural(0.429829743600304, -0.25543373214299)); // TODO: 初始化为适当的值 EField actual = new EField(); actual = ReflectEfieldCal.ReflectEfield(e, rayIn, rayOut, l, Conduct, Epara, s1, s2, f); Assert.IsTrue(Math.Abs(actual.X.Re - expected.X.Re) < 0.0000001 && Math.Abs(actual.X.Im - expected.X.Im) < 0.0000001 && Math.Abs(actual.Y.Re - expected.Y.Re) < 0.0000001 && Math.Abs(actual.Y.Im - expected.Y.Im) < 0.0000001 && Math.Abs(actual.Z.Re - expected.Z.Re) < 0.0000001 && Math.Abs(actual.Z.Im - expected.Z.Im) < 0.0000001); //Assert.Inconclusive("验证此测试方法的正确性。"); }
public void ReflectEfieldTest13() { EField e = new EField(new Plural(0, 0), new Plural(1, 0), new Plural(1, 0)); // TODO: 初始化为适当的值 RayInfo rayIn = new RayInfo(new Point(0, 0, 0), new Point(1, 0, 0)); // TODO: 初始化为适当的值 Face face = new SpaceFace(new Point(6, -2, 3), new Point(6, -2, -3), new Point(6 + 4 / Math.Sqrt(3), 2, 0)); RayInfo rayOut = new RayInfo(new Point(0, 0, 0), new Point(-1, Math.Sqrt(3), 0)); // TODO: 初始化为适当的值 SpectVector l = face.GetNormalVector(); // TODO: 初始化为适当的值 double Conduct = 0; // TODO: 初始化为适当的值 double Epara = 1 / 80.4; // TODO: 初始化为适当的值 double s1 = 1; // TODO: 初始化为适当的值 double s2 = 1; // TODO: 初始化为适当的值 double f = 1000; // TODO: 初始化为适当的值 EField expected = new EField(new Plural(-0.232861639196329, -0.365069112622252), new Plural(-0.134442730073938, -0.210772750445275), new Plural(0.240433653861357, -0.43839669032828)); // TODO: 初始化为适当的值 EField actual = new EField(); actual = ReflectEfieldCal.ReflectEfield(e, rayIn, rayOut, l, Conduct, Epara, s1, s2, f); Assert.IsTrue(Math.Abs(actual.X.Re - expected.X.Re) < 0.0000001 && Math.Abs(actual.X.Im - expected.X.Im) < 0.0000001 && Math.Abs(actual.Y.Re - expected.Y.Re) < 0.0000001 && Math.Abs(actual.Y.Im - expected.Y.Im) < 0.0000001 && Math.Abs(actual.Z.Re - expected.Z.Re) < 0.0000001 && Math.Abs(actual.Z.Im - expected.Z.Im) < 0.0000001); //Assert.Inconclusive("验证此测试方法的正确性。"); }
public void ReflectEfieldTest15() { EField e = new EField(new Plural(0, 0), new Plural(1, 0), new Plural(1, 0)); // TODO: 初始化为适当的值 RayInfo rayIn = new RayInfo(new Point(0, 0, 0), new Point(1, 0, 0)); // TODO: 初始化为适当的值 Face face = new SpaceFace(new Point(6, -2, 3), new Point(6, -2, -3), new Point(6 + 4 * Math.Sqrt(3), 2, 0)); RayInfo rayOut = new RayInfo(new Point(0, 0, 0), new Point(1, Math.Sqrt(3), 0)); // TODO: 初始化为适当的值 SpectVector l = face.GetNormalVector(); // TODO: 初始化为适当的值 double Conduct = 0; // TODO: 初始化为适当的值 double Epara = 1 / 80.4; // TODO: 初始化为适当的值 double s1 = 1; // TODO: 初始化为适当的值 double s2 = 1; // TODO: 初始化为适当的值 double f = 1000; // TODO: 初始化为适当的值 EField expected = new EField(new Plural(-0.221914313088277, -0.37182527838564), new Plural(0.128122288398547, 0.214673424567456), new Plural(0.49998683666538, -0.00362810713003811)); // TODO: 初始化为适当的值 EField actual = new EField(); actual = ReflectEfieldCal.ReflectEfield(e, rayIn, rayOut, l, Conduct, Epara, s1, s2, f); Assert.IsTrue(Math.Abs(actual.X.Re - expected.X.Re) < 0.0000001 && Math.Abs(actual.X.Im - expected.X.Im) < 0.0000001 && Math.Abs(actual.Y.Re - expected.Y.Re) < 0.0000001 && Math.Abs(actual.Y.Im - expected.Y.Im) < 0.0000001 && Math.Abs(actual.Z.Re - expected.Z.Re) < 0.0000001 && Math.Abs(actual.Z.Im - expected.Z.Im) < 0.0000001); //Assert.Inconclusive("验证此测试方法的正确性。"); }
public void ReflectEfieldTest8() { EField e = new EField(new Plural(0, 0), new Plural(1, 0), new Plural(1, 0)); // TODO: 初始化为适当的值 RayInfo rayIn = new RayInfo(new Point(0, 0, 0), new Point(1, 0, 0)); // TODO: 初始化为适当的值 Face face = new SpaceFace(new Point(6, -2, 3), new Point(6, -2, -3), new Point(10, 2, 0)); RayInfo rayOut = new RayInfo(new Point(0, 0, 0), new Point(0, 1, 0)); // TODO: 初始化为适当的值 SpectVector l = face.GetNormalVector(); // TODO: 初始化为适当的值 double Conduct = 0; // TODO: 初始化为适当的值 double Epara = 80.4; // TODO: 初始化为适当的值 double s1 = 1; // TODO: 初始化为适当的值 double s2 = 1; // TODO: 初始化为适当的值 double f = 1000; // TODO: 初始化为适当的值 EField expected = new EField(new Plural(0.182066642851485, 0.315348675782264), new Plural(0, 0), new Plural(0.213346339815971, 0.36952670017011)); // TODO: 初始化为适当的值 EField actual = new EField(); actual = ReflectEfieldCal.ReflectEfield(e, rayIn, rayOut, l, Conduct, Epara, s1, s2, f); Assert.IsTrue(Math.Abs(actual.X.Re - expected.X.Re) < 0.0000001 && Math.Abs(actual.X.Im - expected.X.Im) < 0.0000001 && Math.Abs(actual.Y.Re - expected.Y.Re) < 0.0000001 && Math.Abs(actual.Y.Im - expected.Y.Im) < 0.0000001 && Math.Abs(actual.Z.Re - expected.Z.Re) < 0.0000001 && Math.Abs(actual.Z.Im - expected.Z.Im) < 0.0000001); //Assert.Inconclusive("验证此测试方法的正确性。"); }
/// <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); }
public void ReflectEfieldTest1() { EField e = new EField(new Plural(0, 0), new Plural(1, 0), new Plural(1, 0)); // TODO: 初始化为适当的值 RayInfo rayIn = new RayInfo(new Point(0, 0, 0), new Point(1, 0, 0)); // TODO: 初始化为适当的值 Face face = new SpaceFace(new Point(6, -2, -3), new Point(6, -2, 3), new Point(6, 2, 0)); RayInfo rayOut = new RayInfo(new Point(0, 0, 0), new Point(-1, 0, 0)); // TODO: 初始化为适当的值 SpectVector l = face.GetNormalVector(); // TODO: 初始化为适当的值 double Conduct = 0; // TODO: 初始化为适当的值 double Epara = 4.1; // TODO: 初始化为适当的值 double s1 = 1; // TODO: 初始化为适当的值 double s2 = 1; // TODO: 初始化为适当的值 double f = 1000; // TODO: 初始化为适当的值 EField expected = new EField(new Plural(0, 0), new Plural(-0.0847023107852173, -0.146708705798483), new Plural(-0.0847023107852173, -0.146708705798483));; // TODO: 初始化为适当的值 EField actual = new EField(); actual = ReflectEfieldCal.ReflectEfield(e, rayIn, rayOut, l, Conduct, Epara, s1, s2, f); Assert.IsTrue(Math.Abs(actual.X.Re - expected.X.Re) < 0.0000001 && Math.Abs(actual.X.Im - expected.X.Im) < 0.0000001 && Math.Abs(actual.Y.Re - expected.Y.Re) < 0.0000001 && Math.Abs(actual.Y.Im - expected.Y.Im) < 0.0000001 && Math.Abs(actual.Z.Re - expected.Z.Re) < 0.0000001 && Math.Abs(actual.Z.Im - expected.Z.Im) < 0.0000001); //Assert.Inconclusive("验证此测试方法的正确性。"); }
public void ReflectEfieldTest2() { EField e = new EField(new Plural(0, 0), new Plural(1, 0), new Plural(1, 0)); // TODO: 初始化为适当的值 RayInfo rayIn = new RayInfo(new Point(0, 0, 0), new Point(1, 0, 0)); // TODO: 初始化为适当的值 Face face = new SpaceFace(new Point(6, -2, 3), new Point(6, -2, -3), new Point(6 + 4 / Math.Sqrt(3), 2, 0)); RayInfo rayOut = new RayInfo(new Point(0, 0, 0), new Point(-1, Math.Sqrt(3), 0)); // TODO: 初始化为适当的值 SpectVector l = face.GetNormalVector(); // TODO: 初始化为适当的值 double Conduct = 0; // TODO: 初始化为适当的值 double Epara = 4.1; // TODO: 初始化为适当的值 double s1 = 1; // TODO: 初始化为适当的值 double s2 = 1; // TODO: 初始化为适当的值 double f = 1000; // TODO: 初始化为适当的值 EField expected = new EField(new Plural(0.0623877164578374, 0.108058694673174), new Plural(0.0360195648910585, 0.0623877164578365), new Plural(0.0968928150328006, 0.167823278525182)); // TODO: 初始化为适当的值 EField actual = new EField(); actual = ReflectEfieldCal.ReflectEfield(e, rayIn, rayOut, l, Conduct, Epara, s1, s2, f); Assert.IsTrue(Math.Abs(actual.X.Re - expected.X.Re) < 0.0000001 && Math.Abs(actual.X.Im - expected.X.Im) < 0.0000001 && Math.Abs(actual.Y.Re - expected.Y.Re) < 0.0000001 && Math.Abs(actual.Y.Im - expected.Y.Im) < 0.0000001 && Math.Abs(actual.Z.Re - expected.Z.Re) < 0.0000001 && Math.Abs(actual.Z.Im - expected.Z.Im) < 0.0000001); //Assert.Inconclusive("验证此测试方法的正确性。"); }
/// <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); }
public void ReflectEfieldTest7() { EField e = new EField(new Plural(0, 0), new Plural(1, 0), new Plural(1, 0)); // TODO: 初始化为适当的值 RayInfo rayIn = new RayInfo(new Point(0, 0, 0), new Point(1, 0, 0)); // TODO: 初始化为适当的值 Face face = new SpaceFace(new Point(6, -2, 3), new Point(6, -2, -3), new Point(6 + 4 / Math.Sqrt(3), 2, 0)); RayInfo rayOut = new RayInfo(new Point(0, 0, 0), new Point(-1, Math.Sqrt(3), 0)); // TODO: 初始化为适当的值 SpectVector l = face.GetNormalVector(); // TODO: 初始化为适当的值 double Conduct = 0; // TODO: 初始化为适当的值 double Epara = 80.4; // TODO: 初始化为适当的值 double s1 = 1; // TODO: 初始化为适当的值 double s2 = 1; // TODO: 初始化为适当的值 double f = 1000; // TODO: 初始化为适当的值 EField expected = new EField(new Plural(0.167173715239667, 0.289553368485151), new Plural(0.0965177894950518, 0.167173715239665), new Plural(0.205899086049201, 0.356627678269207)); // TODO: 初始化为适当的值 EField actual = new EField(); actual = ReflectEfieldCal.ReflectEfield(e, rayIn, rayOut, l, Conduct, Epara, s1, s2, f); Assert.IsTrue(Math.Abs(actual.X.Re - expected.X.Re) < 0.0000001 && Math.Abs(actual.X.Im - expected.X.Im) < 0.0000001 && Math.Abs(actual.Y.Re - expected.Y.Re) < 0.0000001 && Math.Abs(actual.Y.Im - expected.Y.Im) < 0.0000001 && Math.Abs(actual.Z.Re - expected.Z.Re) < 0.0000001 && Math.Abs(actual.Z.Im - expected.Z.Im) < 0.0000001); //Assert.Inconclusive("验证此测试方法的正确性。"); }
private bool IntersectBVH(ref RayInfo ray, ref RayHit sp) { if (bvhTree.Length == 0) return false; int triangleIndex = -1; float u = 0f, v = 0f; bool hit = false; Vector invDir = ray.InvDirection; //new Vector(1f / ray.Dir.x, 1f / ray.Dir.y, 1f / ray.Dir.z); var dirIsNeg = new[] { invDir.x < 0, invDir.y < 0, invDir.z < 0 }; int todoOffset = 0, nodeNum = 0; int[] todo = new int[TraversalStackSize]; var dist = float.MaxValue; while (true) { var node = bvhTree[nodeNum]; float t1 = 0f; if (BBox.IntersectBox(ref node.Bound, ref ray)) { //if (node.bbox.Intersect(vray, out t0, out t2)) { if (node.PrimitiveCount > 0) { for (var i = 0; i < node.PrimitiveCount; ++i) { if (triangles[node.PrimOffset + i].Intersect(sceneVertices, ref ray, ref t1, ref u, ref v)) { if (dist > t1) { triangleIndex = node.PrimOffset + i; dist = t1; sp.Index = (uint)(triangleIndex); sp.Distance = dist; sp.U = u; sp.V = v; hit = true; } } } if (todoOffset == 0) break; nodeNum = todo[--todoOffset]; } else { if (dirIsNeg[node.Axis]) { todo[todoOffset++] = nodeNum + 1; nodeNum = node.SecondChildOffset; } else { todo[todoOffset++] = node.SecondChildOffset; nodeNum = nodeNum + 1; } } } else { if (todoOffset == 0) break; nodeNum = todo[--todoOffset]; } } if (hit) { return true; } sp.Index = RayBuffer.NotHit; return false; }
public bool IntersectLBVH(ref RayInfo ray, ref RayHit sp) { int currentNode = 0; float u = 0f, v = 0f, t1 = float.MaxValue, dist = float.MaxValue; bool hit = false; int stopNode = gpuBvhTree[0].SkipOffset; sp.Index = RayBuffer.NotHit; while (currentNode < stopNode) { if (BBox.IntersectBox(ref gpuBvhTree[currentNode].Bound, ref ray)) { if (gpuBvhTree[currentNode].PrimOffset != 0) { if (triangles[gpuBvhTree[currentNode].PrimOffset].Intersect(sceneVertices, ref ray, ref t1, ref u, ref v)) { var triangleIndex = gpuBvhTree[currentNode].PrimOffset; dist = t1; sp.Index = (uint)(triangleIndex); sp.Distance = dist; sp.U = u; sp.V = v; hit = true; } } currentNode++; } else { currentNode = gpuBvhTree[currentNode].SkipOffset; } } return hit; }
protected void FillPosArray(Vector3 position, Vector3 direction, float maxDistance,RayInfo rayInfo) { RaycastHit hit = new RaycastHit(); if (Physics.Raycast(position,direction,out hit,maxDistance,layers.value | reflectionSettings.reflectLayers.value)) { if (SendMessageToHitObjects) { ArcReactorHitInfo arcHit = new ArcReactorHitInfo(); arcHit.launcher = this; arcHit.rayInfo = rayInfo; arcHit.raycastHit = hit; hit.transform.gameObject.SendMessage("ArcReactorHit",arcHit,SendMessageOptions.DontRequireReceiver); } posArray[posArrayLen] = hit.point; posArrayLen++; if (SendMessageToTouchedObjects) { RaycastHit[] hits; hits = Physics.RaycastAll(position, direction, Vector3.Distance(position,hit.point), touchLayers); foreach (RaycastHit touchHit in hits) { ArcReactorHitInfo arcHit = new ArcReactorHitInfo(); arcHit.launcher = this; arcHit.rayInfo = rayInfo; arcHit.raycastHit = touchHit; touchHit.transform.gameObject.SendMessage("ArcReactorTouch",arcHit,SendMessageOptions.DontRequireReceiver); } } if ((reflectionSettings.reflections == ReflectSettings.reflect_by_layer || CheckReflectObject(hit.transform)) && (reflectionSettings.reflectLayers.value & 1 << hit.transform.gameObject.layer) > 0) { if (reflectionSettings.sendMessageToReflectors) { ArcReactorHitInfo arcHit = new ArcReactorHitInfo(); arcHit.launcher = this; arcHit.rayInfo = rayInfo; arcHit.raycastHit = hit; hit.transform.gameObject.SendMessage("ArcReactorReflection",arcHit,SendMessageOptions.DontRequireReceiver); } FillPosArray(hit.point + hit.normal * reflectionSettings.thickness,Vector3.Reflect(direction, hit.normal), maxDistance - Vector3.Distance(position,hit.point),rayInfo ); } } else { if (SendMessageToTouchedObjects) { RaycastHit[] hits; hits = Physics.RaycastAll(position, direction, maxDistance, touchLayers); foreach (RaycastHit touchHit in hits) { ArcReactorHitInfo arcHit = new ArcReactorHitInfo(); arcHit.launcher = this; arcHit.rayInfo = rayInfo; arcHit.raycastHit = touchHit; touchHit.transform.gameObject.SendMessage("ArcReactorTouch",arcHit,SendMessageOptions.DontRequireReceiver); } } posArray[posArrayLen] = position + direction.normalized * maxDistance; posArrayLen++; } }
public void LaunchRay() { if (launchMethod == LaunchMethod.forward_raycast && startBehaviour == RayTransformBehaivour.follow_raycast) { Debug.LogError("Launch method 'forward_raycast' and start behaviour 'follow_raycast' are incompatible. Change one of the settings."); return; } if (arcPrefab == null) { Debug.LogError("No arc prefab set."); return; } Transform start = transform; Transform end; //GameObject startObj; //GameObject endObj; GameObject tmpobj = new GameObject("rayEndPoint"); RaycastHit hit = new RaycastHit(); //End position will be raycasted in any case end = tmpobj.transform; if (Physics.Raycast(transform.position,transform.forward,out hit,Distance,layers.value)) { end.position = hit.point; //endObj = hit.transform.gameObject; } else end.position = transform.position + transform.forward * Distance; if (endBehaviour == RayTransformBehaivour.stick && hit.transform != null) { end.parent = hit.transform; } else { end.parent = globalSpaceTransform; } //Start position will depend on launch method switch (launchMethod) { case LaunchMethod.double_raycast: tmpobj = new GameObject("rayStartPoint"); start = tmpobj.transform; if (Physics.Raycast(transform.position,-transform.forward,out hit,Distance,layers.value)) { start.position = hit.point; //startObj = hit.transform.gameObject; } else start.position = transform.position - transform.forward * Distance; if (startBehaviour == RayTransformBehaivour.stick && hit.transform != null) { start.parent = hit.transform; } break; case LaunchMethod.forward_raycast: tmpobj = new GameObject("rayStartPoint"); start = tmpobj.transform; start.position = transform.position; if (startBehaviour == RayTransformBehaivour.stick) { start.parent = transform; start.rotation = transform.rotation; if (helperPrefab != null) { tmpobj = (GameObject)Instantiate(helperPrefab); tmpobj.transform.parent = start; tmpobj.transform.position = start.transform.position; tmpobj.transform.rotation = start.transform.rotation; } } else { start.parent = globalSpaceTransform; } break; } RayInfo rinfo = new RayInfo(); tmpobj = (GameObject)Instantiate(arcPrefab); tmpobj.transform.parent = globalSpaceTransform; rinfo.arc = tmpobj.GetComponent<ArcReactor_Arc>(); //bool[] destrFlags = new bool[0]; switch (rayInertiaSettings.type) { case InertiaMethod.none: rinfo.shape = new Transform[2]; rinfo.shape[0] = start; rinfo.shape[1] = end; rinfo.arc.shapeTransforms = rinfo.shape; //destrFlags = new bool[2]; break; case InertiaMethod.linespeed: int transformCount = 0; if (rayInertiaSettings.localDetalization) { transformCount = Mathf.CeilToInt(rayInertiaSettings.detalization) + 2; } else { transformCount = Mathf.CeilToInt(Vector3.Distance(start.position,end.position)/rayInertiaSettings.detalization) + 2; } rinfo.shape = new Transform[transformCount]; //destrFlags = new bool[transformCount]; rinfo.shape[0] = start; rinfo.shape[transformCount-1] = end; for (int i = 1; i < transformCount-1; i++) { tmpobj = new GameObject("rayInertiaPoint"); tmpobj.transform.position = Vector3.Lerp(start.position,end.position,(float)i/(transformCount-1)); tmpobj.transform.parent = globalSpaceTransform; rinfo.shape[i] = tmpobj.transform; } break; } rinfo.arc.shapeTransforms = rinfo.shape; /*for(int i = 0; i <= destrFlags.Length-1; i++) destrFlags[i] = true; rinfo.arc.transformsDestructionFlags = destrFlags;*/ rays.Add(rinfo); }
public static bool IntersectBox(ref BBox box, ref RayInfo ray) { float t0 = ray.Min; float t1 = ray.Max; var rayInvDir = ray.InvDirection; //1f /ray.Dir; float invDirX = rayInvDir.x; if (!process_box_coord(ref t0, ref t1, box.Min.x - ray.Org.x, box.Max.x - ray.Org.x, invDirX)) return false; float invDirY = rayInvDir.y; if (!process_box_coord(ref t0, ref t1, box.Min.y - ray.Org.y, box.Max.y - ray.Org.y, invDirY)) return false; float invDirZ = rayInvDir.z; if (!process_box_coord(ref t0, ref t1, box.Min.z - ray.Org.z, box.Max.z - ray.Org.z, invDirZ)) return false; return true; }
private bool IntersectNode(Node node, ref RayInfo ray) { if (node == null) { return false; } float t0, t1 = 0f, u = 0f, v = 0f; if (IntersectBox(node.Bound, ref ray)) { //ray.MinT = t0; // ray.MaxT = t1; if (node.nPrims > 0) { for (var np = node.StartOffset; np < (node.StartOffset + node.nPrims); np++) { if (triangles[np].Intersect(sceneVertices, ref ray, ref t1, ref u, ref v)) { return true; } } } return IntersectNode(node.Left, ref ray) || IntersectNode(node.Right, ref ray); } return false; }
public bool Intersect(ref RayInfo ray, out RayHit intersection) { intersection = new RayHit(); return IntersectLBVH(ref ray, ref intersection); //return IntersectBVH(ref ray, ref intersection); //return IntersectNode(RootNode, ray, out intersection); }
public bool Intersect(ref RayInfo ray) { return ShadowIntersectBVH(ref ray); //return IntersectNode(RootNode, ray); }
private bool ShadowIntersectBVH(ref RayInfo ray) { if (nodes.Count == 0) return false; bool hit = false; Vector invDir = ray.InvDirection; //new Vector(1f / ray.Dir.x, 1f / ray.Dir.y, 1f / ray.Dir.z); var dirIsNeg = new[] { invDir.x < 0, invDir.y < 0, invDir.z < 0 }; int todoOffset = 0, nodeNum = 0; int[] todo = new int[TraversalStackSize]; while (true) { var node = bvhTree[nodeNum]; float t1 = 0f, u = 0f, v = 0f; if (BBox.IntersectBox(ref node.Bound, ref ray)) { if (node.PrimitiveCount > 0) { for (var i = 0; i < node.PrimitiveCount; ++i) { if (!triangles[node.PrimOffset + i].Intersect(sceneVertices, ref ray, ref t1, ref u, ref v)) continue; hit = true; break; } if (todoOffset == 0) break; nodeNum = todo[--todoOffset]; } else { if (dirIsNeg[node.Axis]) { todo[todoOffset++] = nodeNum + 1; nodeNum = node.SecondChildOffset; } else { todo[todoOffset++] = node.SecondChildOffset; nodeNum = nodeNum + 1; } } } else { if (todoOffset == 0) break; nodeNum = todo[--todoOffset]; } } return hit; }