/// <summary> /// Provides a ray from the source. (Stochastic only) /// </summary> /// <param name="index"></param> /// <param name="thread"></param> /// <param name="random"></param> /// <returns></returns> public override BroadRay Directions(int index, int thread, ref Random random) { X_Event X = new X_Event(); double[] RayPower = new double[8]; Hare.Geometry.Point Pt = T.Polys[base.rayct % T.Polygon_Count].GetRandomPoint(random.NextDouble(), random.NextDouble(), 0); Hare.Geometry.Vector P = new Vector(Pt.x, Pt.y, Pt.z); P.Normalize(); for (int oct = 0; oct < 8; oct++) { if (base.SPL[oct] == 0) { RayPower[oct] = 0; } else { Balloon.Shoot(new Ray(new Hare.Geometry.Point(0, 0, 0), P, thread, random.Next()), oct, out X); RayPower[oct] = 1E-12 * Math.Pow(10, .1 * X.t); } } base.rayct++; return(new BroadRay(H_Center, P, random.Next(), thread, RayPower, 0, Source_ID())); }
public override double[] DirPower(int threadid, int random, Vector Direction, double position, ref Curve Curves, ref double[] DomainPower) { X_Event X = new X_Event(); double[] RayPower = new double[8]; Interval t = Curves.Domain; Point3d P = Curves.PointAt((position / t.Length) + t.Min); Vector3d f = Curves.TangentAt(position); Vector fore = new Hare.Geometry.Vector(f.X, f.Y, f.Z); double cosphi = Hare.Geometry.Hare_math.Dot(Direction, fore); double sinphi = Math.Sqrt(1 - cosphi * cosphi); double tanphi = sinphi / cosphi; double F_r = sinphi * sinphi * Math.Pow((tanphi * tanphi + 1) / (tanphi * tanphi + (1 + tanphi * Math.Tan(delta))), 1.5); for (int oct = 0; oct < 8; oct++) { if (DomainPower[oct] == 0) { RayPower[oct] = 0; } else { RayPower[oct] = DomainPower[oct] * reciprocal_velocity * dLinf * F_r; } } return(RayPower); }
/// <summary> /// Checks a ray for an intersection with a given polygon. /// </summary> /// <param name="Poly_ID">The index of the polygon to be checked.</param> /// <param name="R">The ray to be intersected with the polygon.</param> /// <param name="X">An event describing the intersection of the ray with the polygon.</param> /// <returns>true if ray intersects, false if not.</returns> public bool intersect(int Poly_ID, Ray R, out X_Event X) { double u, v, t; Point P; Polys[Poly_ID].Intersect(R, this.Polygon_Vertices(Poly_ID), out P, out u, out v, out t, out Poly_ID); X = new X_Event(P, u, v, t, Poly_ID); return(true); }
public override bool shoot(Ray R, int top_id, out X_Event XPT) { double u, v, t; int SurfID; Hare.Geometry.Point Xpt; if (shoot(R, out u, out v, out SurfID, out Xpt, out t)) { XPT = new X_Event(Xpt, u, v, t, SurfID); return(true); } else { XPT = new X_Event(); return(false); } }
/// <summary> /// Deterministic Source Power /// </summary> /// <param name="thread"></param> /// <param name="random"></param> /// <param name="DIR"></param> /// <returns></returns> public override double[] DirPower(int thread, int random, Vector DIR) { X_Event X = new X_Event(); double[] RayPower = new double[8]; for (int oct = 0; oct < 8; oct++) { if (base.SPL[oct] == 0) { RayPower[oct] = 0; } else { Balloon.Shoot(new Ray(new Hare.Geometry.Point(0, 0, 0), DIR, thread, random), oct, out X); RayPower[oct] = 1E-12 * Math.Pow(10, .1 * X.t); } } return(RayPower); }
/// <summary> /// Provides a ray from the source. (Stochastic only) /// </summary> /// <param name="index"></param> /// <param name="thread"></param> /// <param name="random"></param> /// <returns></returns> public override BroadRay Directions(int index, int thread, ref Random random) { X_Event X = new X_Event(); double[] RayPower = new double[8]; Hare.Geometry.Point Pt = T.Polys[base.rayct % T.Polygon_Count].GetRandomPoint(random.NextDouble(), random.NextDouble(), 0); Hare.Geometry.Vector P = new Vector(Pt.x, Pt.y, Pt.z); P.Normalize(); for (int oct = 0; oct < 8; oct++) { if (base.SPL[oct] == 0) { RayPower[oct] = 0; } else { Balloon.Shoot(new Ray(new Hare.Geometry.Point(0, 0, 0), P, thread, random.Next()), oct, out X); RayPower[oct] = 1E-12 * Math.Pow(10, .1 * X.t); } } double[] phtemp = new double[8]; if (ph == Phase_Regime.Random) { for (int o = 0; o < 8; o++) { phtemp[o] = random.Next() * 2 * Math.PI; } } else { for (int o = 0; o < 8; o++) { phtemp[o] = 0 - Delay * Utilities.Numerics.angularFrequency[o]; } } base.rayct++; return(new BroadRay(H_Center, P, random.Next(), thread, RayPower, phase, delay, Source_ID())); }
/// <summary> /// Fire a ray into the model. Ray must start inside the bounding box of the Topology. /// </summary> /// <param name="R"> The ray to be entered. Make certain the Ray has a unique Ray_ID variable. </param> /// <param name="top_index"> Indicates the topology the ray is to intersect. </param> /// <param name="Ret_Event"> The nearest resulting intersection information, if any. </param> /// <returns> Indicates whether or not an intersection was found. </returns> public override bool Shoot(Ray R, int top_index, out X_Event Ret_Event)//, On3dPoint EndPt, int Octave_in) { int X, Y, Z; //Identify which voxel the Origin point is located in... X = (int)Math.Floor((R.origin.x - OBox.Min.x) / VoxelDims.x); Y = (int)Math.Floor((R.origin.y - OBox.Min.y) / VoxelDims.y); Z = (int)Math.Floor((R.origin.z - OBox.Min.z) / VoxelDims.z); double tDeltaX, tDeltaY, tDeltaZ; double tMaxX = 0, tMaxY = 0, tMaxZ = 0; int stepX, stepY, stepZ, OutX, OutY, OutZ; double t_start = 0; if (X < 0 || X >= VoxelCtX || Y < 0 || Y >= VoxelCtY || Z < 0 || Z >= VoxelCtZ) //return false; { if (!OBox.Intersect(R, ref t_start, ref R.origin)) { Ret_Event = new X_Event(); return(false); } X = (int)Math.Floor((R.origin.x - OBox.Min.x + R.direction.x * 0.001) / VoxelDims.x); Y = (int)Math.Floor((R.origin.y - OBox.Min.y + R.direction.y * 0.001) / VoxelDims.y); Z = (int)Math.Floor((R.origin.z - OBox.Min.z + R.direction.z * 0.001) / VoxelDims.z); X = Math.Max(0, X); Y = Math.Max(0, Y); Z = Math.Max(0, Z); } if (R.direction.x < 0) { OutX = -1; stepX = -1; tMaxX = (Voxels[X, Y, Z].Min.x - R.origin.x) / R.direction.x; tDeltaX = VoxelDims.x / R.direction.x * stepX; } else { OutX = VoxelCtX; stepX = 1; tMaxX = (Voxels[X, Y, Z].Max.x - R.origin.x) / R.direction.x; tDeltaX = VoxelDims.x / R.direction.x * stepX; } if (R.direction.y < 0) { OutY = -1; stepY = -1; tMaxY = (Voxels[X, Y, Z].Min.y - R.origin.y) / R.direction.y; tDeltaY = VoxelDims.y / R.direction.y * stepY; } else { OutY = VoxelCtY; stepY = 1; tMaxY = (Voxels[X, Y, Z].Max.y - R.origin.y) / R.direction.y; tDeltaY = VoxelDims.y / R.direction.y * stepY; } if (R.direction.z < 0) { OutZ = -1; stepZ = -1; tMaxZ = (Voxels[X, Y, Z].Min.z - R.origin.z) / R.direction.z; tDeltaZ = VoxelDims.z / R.direction.z * stepZ; } else { OutZ = VoxelCtZ; stepZ = 1; tMaxZ = (Voxels[X, Y, Z].Max.z - R.origin.z) / R.direction.z; tDeltaZ = VoxelDims.z / R.direction.z * stepZ; } List <Point> X_LIST = new List <Point>(); List <double> ulist = new List <double>(); List <double> vlist = new List <double>(); List <double> tlist = new List <double>(); List <int> pidlist = new List <int>(); while (true) { //Check all polygons in the current voxel... foreach (int i in Voxel_Inv[X, Y, Z, top_index]) { if (Poly_Ray_ID[R.ThreadID, top_index][i] != R.Ray_ID) { Poly_Ray_ID[R.ThreadID, top_index][i] = R.Ray_ID; Point Pt; double u = 0, v = 0, t = 0; if (Model[top_index].intersect(i, R, out Pt, out u, out v, out t) && t > 0.0000000001) { X_LIST.Add(Pt); ulist.Add(u); vlist.Add(v); tlist.Add(t); pidlist.Add(i); } } } for (int c = 0; c < X_LIST.Count; c++) { if (this.Voxels[X, Y, Z].IsPointInBox(X_LIST[c])) { int choice = c; //Ret_Event = new X_Event(X_LIST[c], ulist[c], vlist[c], tlist[c], pidlist[c]; for (int s = c + 1; s < X_LIST.Count; s++) { if (tlist[s] < tlist[choice]) { choice = s; //Ret_Event = X_LIST[s]; } } Ret_Event = new X_Event(X_LIST[choice], ulist[choice], vlist[choice], tlist[choice] + t_start, pidlist[choice]); return(true); } } //Find the Next Voxel... ///////////////////////////////////////////////// if (tMaxX < tMaxY) { if (tMaxX < tMaxZ) { X += stepX; if (X < 0 || X >= VoxelCtX) { Ret_Event = new X_Event(); return(false); /* outside grid */ } tMaxX = tMaxX + tDeltaX; } else { Z += stepZ; if (Z < 0 || Z >= VoxelCtZ) { Ret_Event = new X_Event(); return(false); /* outside grid */ } tMaxZ = tMaxZ + tDeltaZ; } } else { if (tMaxY < tMaxZ) { Y += stepY; if (Y < 0 || Y >= VoxelCtY) { Ret_Event = new X_Event(); return(false); /* outside grid */ } tMaxY = tMaxY + tDeltaY; } else { Z += stepZ; if (Z < 0 || Z >= VoxelCtZ) { Ret_Event = new X_Event(); return(false); /* outside grid */ } tMaxZ = tMaxZ + tDeltaZ; } } } }
public bool Intersect_13Pt(Point Center, double frequency, out List<Bound_Node.Boundary> Bout, out List<double> alpha, ref Random Rnd) { Bout = new List<Bound_Node.Boundary>(); alpha = new List<double>(); Center += new Point((Rnd.NextDouble() - .5) * 1E-6, (Rnd.NextDouble() - .5) * 1E-6, (Rnd.NextDouble() - .5) * 1E-6); X_Event XPt = new X_Event(); double dx2 = 2 * dx + double.Epsilon; XPt = new X_Event(); if (Rm.shoot(new Ray(Center, -1 * Dir[1], 0, Rnd.Next()), 0, out XPt) && XPt.t < dx2) { //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(new Rhino.Geometry.Line(Utilities.PachTools.HPttoRPt(Center), Utilities.PachTools.HPttoRPt(Center - Dir[1] * 2 * dx))); Bout.Add(Bound_Node.Boundary.AYPos); alpha.Add(Rm.AbsorptionValue[XPt.Poly_id].Reflection_Narrow(frequency).Magnitude); } XPt = new X_Event(); if (Rm.shoot(new Ray(Center, Dir[1], 0, Rnd.Next()), 0, out XPt) && XPt.t < dx2) { //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(new Rhino.Geometry.Line(Utilities.PachTools.HPttoRPt(Center), Utilities.PachTools.HPttoRPt(Center + Dir[1] * 2 * dx))); Bout.Add(Bound_Node.Boundary.AYNeg); alpha.Add(Rm.AbsorptionValue[XPt.Poly_id].Reflection_Narrow(frequency).Magnitude); } XPt = new X_Event(); if (Rm.shoot(new Ray(Center, -1 * Dir[2], 0, Rnd.Next()), 0, out XPt) && XPt.t < dx2) { //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(new Rhino.Geometry.Line(Utilities.PachTools.HPttoRPt(Center), Utilities.PachTools.HPttoRPt(Center - Dir[2] * 2 * dx))); Bout.Add(Bound_Node.Boundary.AZPos); alpha.Add(Rm.AbsorptionValue[XPt.Poly_id].Reflection_Narrow(frequency).Magnitude); } XPt = new X_Event(); if (Rm.shoot(new Ray(Center, Dir[2], 0, Rnd.Next()), 0, out XPt) && XPt.t < dx2) { //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(new Rhino.Geometry.Line(Utilities.PachTools.HPttoRPt(Center), Utilities.PachTools.HPttoRPt(Center + Dir[2] * 2 * dx))); Bout.Add(Bound_Node.Boundary.AZNeg); alpha.Add(Rm.AbsorptionValue[XPt.Poly_id].Reflection_Narrow(frequency).Magnitude); } XPt = new X_Event(); if (Rm.shoot(new Ray(Center, Dir[9], 0, Rnd.Next()), 0, out XPt) && XPt.t < dx2) { //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(new Rhino.Geometry.Line(Utilities.PachTools.HPttoRPt(Center), Utilities.PachTools.HPttoRPt(Center + Dir[9] * 2 * dx))); Bout.Add(Bound_Node.Boundary.DXNegYNegZPos); alpha.Add(Rm.AbsorptionValue[XPt.Poly_id].Reflection_Narrow(frequency).Magnitude); } XPt = new X_Event(); if (Rm.shoot(new Ray(Center, Dir[9] * -1, 0, Rnd.Next()), 0, out XPt) && XPt.t < dx2) { //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(new Rhino.Geometry.Line(Utilities.PachTools.HPttoRPt(Center), Utilities.PachTools.HPttoRPt(Center - Dir[9] * 2 * dx))); Bout.Add(Bound_Node.Boundary.DXPosYPosZNeg); alpha.Add(Rm.AbsorptionValue[XPt.Poly_id].Reflection_Narrow(frequency).Magnitude); } XPt = new X_Event(); if (Rm.shoot(new Ray(Center, Dir[10], 0, Rnd.Next()), 0, out XPt) && XPt.t < dx2) { //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(new Rhino.Geometry.Line(Utilities.PachTools.HPttoRPt(Center), Utilities.PachTools.HPttoRPt(Center + Dir[10] * 2 * dx))); Bout.Add(Bound_Node.Boundary.DXPosYNegZPos); alpha.Add(Rm.AbsorptionValue[XPt.Poly_id].Reflection_Narrow(frequency).Magnitude); } XPt = new X_Event(); if (Rm.shoot(new Ray(Center, Dir[10] * -1, 0, Rnd.Next()), 0, out XPt) && XPt.t < dx2) { //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(new Rhino.Geometry.Line(Utilities.PachTools.HPttoRPt(Center), Utilities.PachTools.HPttoRPt(Center - Dir[10] * 2 * dx))); Bout.Add(Bound_Node.Boundary.DXNegYPosZNeg); alpha.Add(Rm.AbsorptionValue[XPt.Poly_id].Reflection_Narrow(frequency).Magnitude); } XPt = new X_Event(); if (Rm.shoot(new Ray(Center, Dir[11], 0, Rnd.Next()), 0, out XPt) && XPt.t < dx2) { //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(new Rhino.Geometry.Line(Utilities.PachTools.HPttoRPt(Center), Utilities.PachTools.HPttoRPt(Center + Dir[11] * 2 * dx))); Bout.Add(Bound_Node.Boundary.DXPosYPosZPos); alpha.Add(Rm.AbsorptionValue[XPt.Poly_id].Reflection_Narrow(frequency).Magnitude); } XPt = new X_Event(); if (Rm.shoot(new Ray(Center, Dir[11] * -1, 0, Rnd.Next()), 0, out XPt) && XPt.t < dx2) { //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(new Rhino.Geometry.Line(Utilities.PachTools.HPttoRPt(Center), Utilities.PachTools.HPttoRPt(Center - Dir[11] * 2 * dx))); Bout.Add(Bound_Node.Boundary.DXNegYNegZNeg); alpha.Add(Rm.AbsorptionValue[XPt.Poly_id].Reflection_Narrow(frequency).Magnitude); } XPt = new X_Event(); if (Rm.shoot(new Ray(Center, Dir[12], 0, Rnd.Next()), 0, out XPt) && XPt.t < dx2) { //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(new Rhino.Geometry.Line(Utilities.PachTools.HPttoRPt(Center), Utilities.PachTools.HPttoRPt(Center + Dir[12] * 2 * dx))); Bout.Add(Bound_Node.Boundary.DXNegYPosZPos); alpha.Add(Rm.AbsorptionValue[XPt.Poly_id].Reflection_Narrow(frequency).Magnitude); } XPt = new X_Event(); if (Rm.shoot(new Ray(Center, Dir[12] * -1, 0, Rnd.Next()), 0, out XPt) && XPt.t < dx2) { //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(new Rhino.Geometry.Line(Utilities.PachTools.HPttoRPt(Center), Utilities.PachTools.HPttoRPt(Center - Dir[12] * 2 * dx))); Bout.Add(Bound_Node.Boundary.DXPosYNegZNeg); alpha.Add(Rm.AbsorptionValue[XPt.Poly_id].Reflection_Narrow(frequency).Magnitude); } return Bout.Count > 0; }
public bool Intersect_26Pt(Point Center, out List<Bound_Node_IWB.Boundary> Bout, out List<double[]> alpha, ref Random Rnd) { Bout = new List<Bound_Node.Boundary>(); alpha = new List<double[]>(); Center += new Point((Rnd.NextDouble() - .5) * 1E-6, (Rnd.NextDouble() - .5) * 1E-6, (Rnd.NextDouble() - .5) * 1E-6); X_Event XPt = new X_Event(); //new Vector(-1,0,0), if (Rm.shoot(new Ray(Center, Dir[0], 0, Rnd.Next()), 0, out XPt) && XPt.t < dx) { //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(new Rhino.Geometry.Line(Utilities.PachTools.HPttoRPt(Center), Utilities.PachTools.HPttoRPt(Center + Dir[0] * dx))); Bout.Add(Bound_Node.Boundary.AXNeg); //TODO: Intelligently Assign Absorption alpha.Add(Rm.AbsorptionValue[XPt.Poly_id].Coefficient_A_Broad()); } XPt = new X_Event(); if (Rm.shoot(new Ray(Center, Dir[0] * -1, 0, Rnd.Next()), 0, out XPt) && XPt.t < dx) { //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(new Rhino.Geometry.Line(Utilities.PachTools.HPttoRPt(Center), Utilities.PachTools.HPttoRPt(Center - Dir[0] * dx))); Bout.Add(Bound_Node.Boundary.AXPos); //TODO: Intelligently Assign Absorption alpha.Add(Rm.AbsorptionValue[XPt.Poly_id].Coefficient_A_Broad()); } //new Vector(0,-1,0), XPt = new X_Event(); if (Rm.shoot(new Ray(Center, Dir[1], 0, Rnd.Next()), 0, out XPt) && XPt.t < dx) { //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(new Rhino.Geometry.Line(Utilities.PachTools.HPttoRPt(Center), Utilities.PachTools.HPttoRPt(Center + Dir[1] * dx))); Bout.Add(Bound_Node.Boundary.AYNeg); alpha.Add(Rm.AbsorptionValue[XPt.Poly_id].Coefficient_A_Broad()); } XPt = new X_Event(); if (Rm.shoot(new Ray(Center, Dir[1] * -1, 0, Rnd.Next()), 0, out XPt) && XPt.t < dx) { //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(new Rhino.Geometry.Line(Utilities.PachTools.HPttoRPt(Center), Utilities.PachTools.HPttoRPt(Center - Dir[1] * dx))); Bout.Add(Bound_Node.Boundary.AYPos); alpha.Add(Rm.AbsorptionValue[XPt.Poly_id].Coefficient_A_Broad()); } //new Vector(0,0,-1), XPt = new X_Event(); if (Rm.shoot(new Ray(Center, Dir[2], 0, Rnd.Next()), 0, out XPt) && XPt.t < dx) { //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(new Rhino.Geometry.Line(Utilities.PachTools.HPttoRPt(Center), Utilities.PachTools.HPttoRPt(Center + Dir[2] * dx))); Bout.Add(Bound_Node.Boundary.AZNeg); alpha.Add(Rm.AbsorptionValue[XPt.Poly_id].Coefficient_A_Broad()); } XPt = new X_Event(); if (Rm.shoot(new Ray(Center, Dir[2] * -1, 0, Rnd.Next()), 0, out XPt) && XPt.t < dx) { //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(new Rhino.Geometry.Line(Utilities.PachTools.HPttoRPt(Center), Utilities.PachTools.HPttoRPt(Center - Dir[2] * dx))); Bout.Add(Bound_Node.Boundary.AZPos); alpha.Add(Rm.AbsorptionValue[XPt.Poly_id].Coefficient_A_Broad()); } //new Vector(-1/rt2,-1/rt2,0), XPt = new X_Event(); if (Rm.shoot(new Ray(Center, Dir[3], 0, Rnd.Next()), 0, out XPt) && XPt.t < dxrt2) { //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(new Rhino.Geometry.Line(Utilities.PachTools.HPttoRPt(Center), Utilities.PachTools.HPttoRPt(Center + Dir[3] * dx))); Bout.Add(Bound_Node.Boundary.SDXNegYNeg); alpha.Add(Rm.AbsorptionValue[XPt.Poly_id].Coefficient_A_Broad()); } XPt = new X_Event(); if (Rm.shoot(new Ray(Center, Dir[3] * -1, 0, Rnd.Next()), 0, out XPt) && XPt.t < dxrt2) { //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(new Rhino.Geometry.Line(Utilities.PachTools.HPttoRPt(Center), Utilities.PachTools.HPttoRPt(Center - Dir[3] * dx))); Bout.Add(Bound_Node.Boundary.SDXPosYPos); alpha.Add(Rm.AbsorptionValue[XPt.Poly_id].Coefficient_A_Broad()); } //new Vector(1/rt2, -1/rt2,0), XPt = new X_Event(); if (Rm.shoot(new Ray(Center, Dir[4], 0, Rnd.Next()), 0, out XPt) && XPt.t < dxrt2) { //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(new Rhino.Geometry.Line(Utilities.PachTools.HPttoRPt(Center), Utilities.PachTools.HPttoRPt(Center + Dir[4] * dx))); Bout.Add(Bound_Node.Boundary.SDXPosYNeg); alpha.Add(Rm.AbsorptionValue[XPt.Poly_id].Coefficient_A_Broad()); } XPt = new X_Event(); if (Rm.shoot(new Ray(Center, Dir[4] * -1, 0, Rnd.Next()), 0, out XPt) && XPt.t < dxrt2) { //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(new Rhino.Geometry.Line(Utilities.PachTools.HPttoRPt(Center), Utilities.PachTools.HPttoRPt(Center - Dir[4] * dx))); Bout.Add(Bound_Node.Boundary.SDXNegYPos); alpha.Add(Rm.AbsorptionValue[XPt.Poly_id].Coefficient_A_Broad()); } //new Vector(-1/rt2, 0, 1/rt2), XPt = new X_Event(); if (Rm.shoot(new Ray(Center, Dir[5], 0, Rnd.Next()), 0, out XPt) && XPt.t < dxrt2) { //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(new Rhino.Geometry.Line(Utilities.PachTools.HPttoRPt(Center), Utilities.PachTools.HPttoRPt(Center + Dir[5] * dx))); Bout.Add(Bound_Node.Boundary.SDXNegZPos); alpha.Add(Rm.AbsorptionValue[XPt.Poly_id].Coefficient_A_Broad()); } XPt = new X_Event(); if (Rm.shoot(new Ray(Center, Dir[5] * -1, 0, Rnd.Next()), 0, out XPt) && XPt.t < dxrt2) { //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(new Rhino.Geometry.Line(Utilities.PachTools.HPttoRPt(Center), Utilities.PachTools.HPttoRPt(Center - Dir[5] * dx))); Bout.Add(Bound_Node.Boundary.SDXPosZNeg); alpha.Add(Rm.AbsorptionValue[XPt.Poly_id].Coefficient_A_Broad()); } //new Vector(0, -1/rt2, 1/rt2), XPt = new X_Event(); if (Rm.shoot(new Ray(Center, Dir[6], 0, Rnd.Next()), 0, out XPt) && XPt.t < dxrt2) { //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(new Rhino.Geometry.Line(Utilities.PachTools.HPttoRPt(Center), Utilities.PachTools.HPttoRPt(Center + Dir[6] * dx))); Bout.Add(Bound_Node.Boundary.SDYNegZPos); alpha.Add(Rm.AbsorptionValue[XPt.Poly_id].Coefficient_A_Broad()); } XPt = new X_Event(); if (Rm.shoot(new Ray(Center, Dir[6] * -1, 0, Rnd.Next()), 0, out XPt) && XPt.t < dxrt2) { //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(new Rhino.Geometry.Line(Utilities.PachTools.HPttoRPt(Center), Utilities.PachTools.HPttoRPt(Center - Dir[6] * dx))); Bout.Add(Bound_Node.Boundary.SDYPosZNeg); alpha.Add(Rm.AbsorptionValue[XPt.Poly_id].Coefficient_A_Broad()); } //new Vector(1/rt2, 0, 1/rt2), XPt = new X_Event(); if (Rm.shoot(new Ray(Center, Dir[7], 0, Rnd.Next()), 0, out XPt) && XPt.t < dxrt2) { //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(new Rhino.Geometry.Line(Utilities.PachTools.HPttoRPt(Center), Utilities.PachTools.HPttoRPt(Center + Dir[7] * dx))); Bout.Add(Bound_Node.Boundary.SDXPosZPos); alpha.Add(Rm.AbsorptionValue[XPt.Poly_id].Coefficient_A_Broad()); } XPt = new X_Event(); if (Rm.shoot(new Ray(Center, Dir[7] * -1, 0, Rnd.Next()), 0, out XPt) && XPt.t < dxrt2) { //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(new Rhino.Geometry.Line(Utilities.PachTools.HPttoRPt(Center), Utilities.PachTools.HPttoRPt(Center - Dir[7] * dx))); Bout.Add(Bound_Node.Boundary.SDXNegZNeg); alpha.Add(Rm.AbsorptionValue[XPt.Poly_id].Coefficient_A_Broad()); } //new Vector(0, 1/rt2, 1/rt2), XPt = new X_Event(); if (Rm.shoot(new Ray(Center, Dir[8], 0, Rnd.Next()), 0, out XPt) && XPt.t < dxrt2) { //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(new Rhino.Geometry.Line(Utilities.PachTools.HPttoRPt(Center), Utilities.PachTools.HPttoRPt(Center + Dir[8] * dx))); Bout.Add(Bound_Node.Boundary.SDYPosZPos); alpha.Add(Rm.AbsorptionValue[XPt.Poly_id].Coefficient_A_Broad()); } XPt = new X_Event(); if (Rm.shoot(new Ray(Center, Dir[8] * -1, 0, Rnd.Next()), 0, out XPt) && XPt.t < dxrt2) { //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(new Rhino.Geometry.Line(Utilities.PachTools.HPttoRPt(Center), Utilities.PachTools.HPttoRPt(Center - Dir[8] * dx))); Bout.Add(Bound_Node.Boundary.SDYNegZNeg); alpha.Add(Rm.AbsorptionValue[XPt.Poly_id].Coefficient_A_Broad()); } //new Vector(-1/rt3,-1/rt3,1/rt3), XPt = new X_Event(); if (Rm.shoot(new Ray(Center, Dir[9], 0, Rnd.Next()), 0, out XPt) && XPt.t < dxrt2) { //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(new Rhino.Geometry.Line(Utilities.PachTools.HPttoRPt(Center), Utilities.PachTools.HPttoRPt(Center + Dir[9] * dx))); Bout.Add(Bound_Node.Boundary.DXNegYNegZPos); alpha.Add(Rm.AbsorptionValue[XPt.Poly_id].Coefficient_A_Broad()); } XPt = new X_Event(); if (Rm.shoot(new Ray(Center, Dir[9] * -1, 0, Rnd.Next()), 0, out XPt) && XPt.t < dxrt2) { Bout.Add(Bound_Node.Boundary.DXPosYPosZNeg); //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(new Rhino.Geometry.Line(Utilities.PachTools.HPttoRPt(Center), Utilities.PachTools.HPttoRPt(Center - Dir[9] * dx))); alpha.Add(Rm.AbsorptionValue[XPt.Poly_id].Coefficient_A_Broad()); } //new Vector(1/rt3,-1/rt3,1/rt3), XPt = new X_Event(); if (Rm.shoot(new Ray(Center, Dir[10], 0, Rnd.Next()), 0, out XPt) && XPt.t < dxrt2) { //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(new Rhino.Geometry.Line(Utilities.PachTools.HPttoRPt(Center), Utilities.PachTools.HPttoRPt(Center + Dir[10] * dx))); Bout.Add(Bound_Node.Boundary.DXPosYNegZPos); alpha.Add(Rm.AbsorptionValue[XPt.Poly_id].Coefficient_A_Broad()); } XPt = new X_Event(); if (Rm.shoot(new Ray(Center, Dir[10] * -1, 0, Rnd.Next()), 0, out XPt) && XPt.t < dxrt2) { //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(new Rhino.Geometry.Line(Utilities.PachTools.HPttoRPt(Center), Utilities.PachTools.HPttoRPt(Center - Dir[10] * dx))); Bout.Add(Bound_Node.Boundary.DXNegYPosZNeg); alpha.Add(Rm.AbsorptionValue[XPt.Poly_id].Coefficient_A_Broad()); } //new Vector(1/rt3,1/rt3,1/rt3), XPt = new X_Event(); if (Rm.shoot(new Ray(Center + new Point(0, 1E-6, -1E-6), Dir[11], 0, Rnd.Next()), 0, out XPt) && XPt.t < dxrt2) { //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(new Rhino.Geometry.Line(Utilities.PachTools.HPttoRPt(Center), Utilities.PachTools.HPttoRPt(Center + Dir[11] * dx))); Bout.Add(Bound_Node.Boundary.DXPosYPosZPos); alpha.Add(Rm.AbsorptionValue[XPt.Poly_id].Coefficient_A_Broad()); } XPt = new X_Event(); if (Rm.shoot(new Ray(Center, Dir[11] * -1, 0, Rnd.Next()), 0, out XPt) && XPt.t < dxrt2) { //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(new Rhino.Geometry.Line(Utilities.PachTools.HPttoRPt(Center), Utilities.PachTools.HPttoRPt(Center - Dir[11] * dx))); Bout.Add(Bound_Node.Boundary.DXNegYNegZNeg); alpha.Add(Rm.AbsorptionValue[XPt.Poly_id].Coefficient_A_Broad()); } //new Vector(-1/rt3,1/rt3,1/rt3) XPt = new X_Event(); if (Rm.shoot(new Ray(Center, Dir[12], 0, Rnd.Next()), 0, out XPt) && XPt.t < dxrt2) { //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(new Rhino.Geometry.Line(Utilities.PachTools.HPttoRPt(Center), Utilities.PachTools.HPttoRPt(Center + Dir[12] * dx))); Bout.Add(Bound_Node.Boundary.DXNegYPosZPos); alpha.Add(Rm.AbsorptionValue[XPt.Poly_id].Coefficient_A_Broad()); } XPt = new X_Event(); if (Rm.shoot(new Ray(Center, Dir[12] * -1, 0, Rnd.Next()), 0, out XPt) && XPt.t < dxrt2) { //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(new Rhino.Geometry.Line(Utilities.PachTools.HPttoRPt(Center), Utilities.PachTools.HPttoRPt(Center - Dir[12] * dx))); Bout.Add(Bound_Node.Boundary.DXPosYNegZNeg); alpha.Add(Rm.AbsorptionValue[XPt.Poly_id].Coefficient_A_Broad()); } return Bout.Count > 0; }
public abstract bool Shoot(Ray R, int top_index, out X_Event Ret_event);
/// <summary> /// cast a ray within the model. /// </summary> /// <param name="R">A ray, complete with origin point and direction...</param> /// <param name="u">optional surface coordinate</param> /// <param name="v">optional surface coordinate</param> /// <param name="Poly_ID">the polygon of intersection</param> /// <param name="X_PT">the point of intersection</param> /// <param name="t">the distance traveled by the ray</param> /// <param name="code">returns code indicating where the ray has been (for polyrefractive)</param> /// <returns>true if successful, false if no hit</returns> public abstract bool shoot(Ray R, int topo, out X_Event Xpt);
public override bool shoot(Ray R, int topo, out X_Event Xpt) { Xpt = new X_Event(new Hare.Geometry.Point(), -1, -1, -1, -1); return(false); }
/// <summary> /// Deterministic Source Power /// </summary> /// <param name="thread"></param> /// <param name="random"></param> /// <param name="DIR"></param> /// <returns></returns> public override double[] DirPower(int thread, int random, Vector DIR) { X_Event X = new X_Event(); double[] RayPower = new double[8]; for (int oct = 0; oct < 8; oct++) { if (base.SPL[oct] == 0) { RayPower[oct] = 0; } else { Balloon.Shoot(new Ray(new Hare.Geometry.Point(0,0,0), DIR, thread, random), oct, out X); RayPower[oct] = 1E-12 * Math.Pow(10, .1 * X.t); } } return RayPower; }
/// <summary> /// Provides a ray from the source. (Stochastic only) /// </summary> /// <param name="index"></param> /// <param name="thread"></param> /// <param name="random"></param> /// <returns></returns> public override BroadRay Directions(int index, int thread, ref Random random) { X_Event X = new X_Event(); double[] RayPower = new double[8]; Hare.Geometry.Point Pt = T.Polys[base.rayct%T.Polygon_Count].GetRandomPoint(random.NextDouble(), random.NextDouble(), 0); Hare.Geometry.Vector P = new Vector(Pt.x, Pt.y, Pt.z); P.Normalize(); for (int oct = 0; oct < 8; oct++) { if (base.SPL[oct] == 0) { RayPower[oct] = 0; } else { Balloon.Shoot(new Ray(new Hare.Geometry.Point(0,0,0), P, thread, random.Next()), oct, out X); RayPower[oct] = 1E-12 * Math.Pow(10, .1 * X.t); } } double[] phtemp = new double[8]; if (ph == Phase_Regime.Random) for (int o = 0; o < 8; o++) phtemp[o] = random.Next() * 2 * Math.PI; else for (int o = 0; o < 8; o++) phtemp[o] = 0 - Delay * Utilities.Numerics.angularFrequency[o]; base.rayct++; return new BroadRay(H_Center, P, random.Next(), thread, RayPower, phase, delay, Source_ID()); }
public override double[] DirPower(int threadid, int random, Vector Direction, double position, ref Curve Curves, ref double[] DomainPower) { X_Event X = new X_Event(); double[] RayPower = new double[8]; Interval t = Curves.Domain; Point3d P = Curves.PointAt((position/t.Length) + t.Min); Vector3d f = Curves.TangentAt(position); Vector fore = new Hare.Geometry.Vector(f.X, f.Y, f.Z); double cosphi = Hare.Geometry.Hare_math.Dot(Direction, fore); double sinphi = Math.Sqrt(1 - cosphi * cosphi); double tanphi = sinphi / cosphi; double F_r = sinphi * sinphi * Math.Pow((tanphi * tanphi + 1) / (tanphi * tanphi + (1 + tanphi * Math.Tan(delta))), 1.5); for (int oct = 0; oct < 8; oct++) { if (DomainPower[oct] == 0) { RayPower[oct] = 0; } else { RayPower[oct] = DomainPower[oct] * reciprocal_velocity * dLinf * F_r; } } return RayPower; }
/// <summary> /// Fire a ray into the model. /// </summary> /// <param name="R"> The ray to be entered. Make certain the Ray has a unique Ray_ID variable. </param> /// <param name="top_index"> Indicates the topology the ray is to intersect. </param> /// <param name="Ret_Event"> The nearest resulting intersection information, if any. </param> /// <returns> Indicates whether or not an intersection was found. </returns> public override bool Shoot(Ray R, int top_index, out X_Event Ret_Event)//, On3dPoint EndPt, int Octave_in) { int X, Y, Z; //////////////////////// double VPrev = 0; //////////////////////// //Identify whether the Origin is inside the voxel grid... //Identify which voxel the Origin point is located in... X = (int)Math.Floor((R.origin.x - OBox.Min_PT.x) / VoxelDims.x); Y = (int)Math.Floor((R.origin.y - OBox.Min_PT.y) / VoxelDims.y); Z = (int)Math.Floor((R.origin.z - OBox.Min_PT.z) / VoxelDims.z); double tDeltaX, tDeltaY, tDeltaZ; double tMaxX = 0, tMaxY = 0, tMaxZ = 0; int stepX, stepY, stepZ, OutX, OutY, OutZ; double t_start = 0; if (X < 0 || X >= VoxelCtX || Y < 0 || Y >= VoxelCtY || Z < 0 || Z >= VoxelCtZ) //return false; { if (!OBox.Intersect(R, ref t_start, ref R.origin)) { Ret_Event = new X_Event(); return(false); } X = (int)Math.Floor((R.origin.x - OBox.Min_PT.x + R.direction.x) / VoxelDims.x); Y = (int)Math.Floor((R.origin.y - OBox.Min_PT.y + R.direction.y) / VoxelDims.y); Z = (int)Math.Floor((R.origin.z - OBox.Min_PT.z + R.direction.z) / VoxelDims.z); } if (R.direction.x < 0) { OutX = -1; stepX = -1; tMaxX = (float)((Voxels[X, Y, Z].Min_PT.x - R.origin.x) / R.direction.x); tDeltaX = (float)(VoxelDims.x / R.direction.x * stepX); } else { OutX = VoxelCtX; stepX = 1; tMaxX = (float)((Voxels[X, Y, Z].Max_PT.x - R.origin.x) / R.direction.x); tDeltaX = (float)(VoxelDims.x / R.direction.x * stepX); } if (R.direction.y < 0) { OutY = -1; stepY = -1; tMaxY = (float)((Voxels[X, Y, Z].Min_PT.y - R.origin.y) / R.direction.y); tDeltaY = (float)(VoxelDims.y / R.direction.y * stepY); } else { OutY = VoxelCtY; stepY = 1; tMaxY = (float)((Voxels[X, Y, Z].Max_PT.y - R.origin.y) / R.direction.y); tDeltaY = (float)(VoxelDims.y / R.direction.y * stepY); } if (R.direction.z < 0) { OutZ = -1; stepZ = -1; tMaxZ = (float)((Voxels[X, Y, Z].Min_PT.z - R.origin.z) / R.direction.z); tDeltaZ = (float)(VoxelDims.z / R.direction.z * stepZ); } else { OutZ = VoxelCtZ; stepZ = 1; tMaxZ = (float)((Voxels[X, Y, Z].Max_PT.z - R.origin.z) / R.direction.z); tDeltaZ = (float)(VoxelDims.z / R.direction.z * stepZ); } List <double> t_list = new List <double>(); List <int> Codes = new List <int>(); List <Point> Path_pts = new List <Point>(); List <int> voxelCodes = new List <int>(); List <Point> X_LIST = new List <Point>(); List <double> ulist = new List <double>(); List <double> vlist = new List <double>(); List <double> tlist = new List <double>(); List <int> pidlist = new List <int>(); while (true) { //Check all polygons in the current voxel... foreach (int i in Voxel_Inv[X, Y, Z, top_index]) { if (Poly_Ray_ID[R.ThreadID, top_index][i] != R.Ray_ID) { Poly_Ray_ID[R.ThreadID, top_index][i] = R.Ray_ID; Point Pt; double u = 0, v = 0, t = 0; if (Model[top_index].intersect(i, R, out Pt, out u, out v, out t) && t > 0.0000000001) { X_LIST.Add(Pt); } ulist.Add(u); vlist.Add(v); tlist.Add(t); pidlist.Add(i); } } for (int c = 0; c < X_LIST.Count; c++) { if (this.Voxels[X, Y, Z].IsPointInBox(X_LIST[c])) { int choice = c; //Ret_Event = X_LIST[c]; for (int s = c; s < X_LIST.Count; s++) { if (tlist[s] < tlist[choice]) { choice = s; //Ret_Event = X_LIST[s]; } } Path_pts.Add(X_LIST[choice]); t_list.Add(tlist[choice]); Ret_Event = new X_Event_NH(Path_pts, ulist[choice], vlist[choice], t_list, pidlist[choice], Codes); //Ret_Event.t += t_start; return(true); } } ///////////////////////////////////////// VPrev = Velocities[X, Y, Z]; ///////////////////////////////////////// //Find the Next Voxel... ///////////////////////////////////////////////// if (tMaxX < tMaxY) { if (tMaxX < tMaxZ) { X += stepX; if (X < 0 || X >= VoxelCtX) { Ret_Event = new X_Event(); return(false); /* outside grid */ } tMaxX += tDeltaX; if (VPrev != Velocities[X, Y, Z]) { R.direction = XRefraction(R.direction, VPrev, Velocities[X, Y, Z]); if (R.direction.x < 0) { stepX = -1; } else { stepX = 1; } if (R.direction.y < 0) { stepY = -1; } else { stepY = 1; } if (R.direction.z < 0) { stepZ = -1; } else { stepZ = 1; } tDeltaX = (float)(VoxelDims.x / R.direction.x * stepX); tDeltaY = (float)(VoxelDims.y / R.direction.y * stepY); tDeltaZ = (float)(VoxelDims.z / R.direction.z * stepZ); t_list.Add(tDeltaX); Codes.Add(VoxelCode(X, Y, Z)); R.origin += R.direction * tDeltaX; Path_pts.Add(R.origin); X_LIST.Clear(); } } else { Z += stepZ; if (Z < 0 || Z >= VoxelCtZ) { Ret_Event = new X_Event(); return(false); /* outside grid */ } tMaxZ += tDeltaZ; if (VPrev != Velocities[X, Y, Z]) { R.direction = ZRefraction(R.direction, VPrev, Velocities[X, Y, Z]); if (R.direction.x < 0) { stepX = -1; } else { stepX = 1; } if (R.direction.y < 0) { stepY = -1; } else { stepY = 1; } if (R.direction.z < 0) { stepZ = -1; } else { stepZ = 1; } tDeltaX = (float)(VoxelDims.x / R.direction.x * stepX); tDeltaY = (float)(VoxelDims.y / R.direction.y * stepY); tDeltaZ = (float)(VoxelDims.z / R.direction.z * stepZ); t_list.Add(tDeltaZ); R.origin += R.direction * tDeltaZ; Path_pts.Add(R.origin); X_LIST.Clear(); } } } else { if (tMaxY < tMaxZ) { Y += stepY; if (Y < 0 || Y >= VoxelCtY) { Ret_Event = new X_Event(); return(false); /* outside grid */ } tMaxY += tDeltaY; if (VPrev != Velocities[X, Y, Z]) { R.direction = YRefraction(R.direction, VPrev, Velocities[X, Y, Z]); if (R.direction.x < 0) { stepX = -1; } else { stepX = 1; } if (R.direction.y < 0) { stepY = -1; } else { stepY = 1; } if (R.direction.z < 0) { stepZ = -1; } else { stepZ = 1; } tDeltaX = (float)(VoxelDims.x / R.direction.x * stepX); tDeltaY = (float)(VoxelDims.y / R.direction.y * stepY); tDeltaZ = (float)(VoxelDims.z / R.direction.z * stepZ); t_list.Add(tDeltaY); R.origin += R.direction * tDeltaY; Path_pts.Add(R.origin); X_LIST.Clear(); } } else { Z += stepZ; if (Z < 0 || Z >= VoxelCtZ) { Ret_Event = new X_Event(); return(false); /* outside grid */ } tMaxZ += tDeltaZ; if (VPrev != Velocities[X, Y, Z]) { R.direction = ZRefraction(R.direction, VPrev, Velocities[X, Y, Z]); if (R.direction.x < 0) { stepX = -1; } else { stepX = 1; } if (R.direction.y < 0) { stepY = -1; } else { stepY = 1; } if (R.direction.z < 0) { stepZ = -1; } else { stepZ = 1; } tDeltaX = (float)(VoxelDims.x / R.direction.x * stepX); tDeltaY = (float)(VoxelDims.y / R.direction.y * stepY); tDeltaZ = (float)(VoxelDims.z / R.direction.z * stepZ); t_list.Add(tDeltaZ); R.origin += R.direction * tDeltaZ; Path_pts.Add(R.origin); X_LIST.Clear(); } } } } }
/// <summary> /// Fire a ray into the model. /// </summary> /// <param name="R"> The ray to be entered. Make certain the Ray has a unique Ray_ID variable. </param> /// <param name="top_index"> Indicates the topology the ray is to intersect. </param> /// <param name="Ret_Event"> The nearest resulting intersection information, if any. </param> /// <returns> Indicates whether or not an intersection was found. </returns> public override bool Shoot(Ray R, int top_index, out X_Event Ret_Event)//, On3dPoint EndPt, int Octave_in) { int X, Y, Z; //////////////////////// double VPrev = 0; //////////////////////// //Identify whether the Origin is inside the voxel grid... //Identify which voxel the Origin point is located in... X = (int)Math.Floor((R.origin.x - OBox.Min_PT.x) / VoxelDims.x); Y = (int)Math.Floor((R.origin.y - OBox.Min_PT.y) / VoxelDims.y); Z = (int)Math.Floor((R.origin.z - OBox.Min_PT.z) / VoxelDims.z); double tDeltaX, tDeltaY, tDeltaZ; double tMaxX = 0, tMaxY = 0, tMaxZ = 0; int stepX, stepY, stepZ, OutX, OutY, OutZ; double t_start = 0; if (X < 0 || X >= VoxelCtX || Y < 0 || Y >= VoxelCtY || Z < 0 || Z >= VoxelCtZ) //return false; { if (!OBox.Intersect(R, ref t_start, ref R.origin)) { Ret_Event = new X_Event(); return false; } X = (int)Math.Floor((R.origin.x - OBox.Min_PT.x + R.direction.x) / VoxelDims.x); Y = (int)Math.Floor((R.origin.y - OBox.Min_PT.y + R.direction.y) / VoxelDims.y); Z = (int)Math.Floor((R.origin.z - OBox.Min_PT.z + R.direction.z) / VoxelDims.z); } if (R.direction.x < 0) { OutX = -1; stepX = -1; tMaxX = (float)((Voxels[X, Y, Z].Min_PT.x - R.origin.x) / R.direction.x); tDeltaX = (float)(VoxelDims.x / R.direction.x * stepX); } else { OutX = VoxelCtX; stepX = 1; tMaxX = (float)((Voxels[X, Y, Z].Max_PT.x - R.origin.x) / R.direction.x); tDeltaX = (float)(VoxelDims.x / R.direction.x * stepX); } if (R.direction.y < 0) { OutY = -1; stepY = -1; tMaxY = (float)((Voxels[X, Y, Z].Min_PT.y - R.origin.y) / R.direction.y); tDeltaY = (float)(VoxelDims.y / R.direction.y * stepY); } else { OutY = VoxelCtY; stepY = 1; tMaxY = (float)((Voxels[X, Y, Z].Max_PT.y - R.origin.y) / R.direction.y); tDeltaY = (float)(VoxelDims.y / R.direction.y * stepY); } if (R.direction.z < 0) { OutZ = -1; stepZ = -1; tMaxZ = (float)((Voxels[X, Y, Z].Min_PT.z - R.origin.z) / R.direction.z); tDeltaZ = (float)(VoxelDims.z / R.direction.z * stepZ); } else { OutZ = VoxelCtZ; stepZ = 1; tMaxZ = (float)((Voxels[X, Y, Z].Max_PT.z - R.origin.z) / R.direction.z); tDeltaZ = (float)(VoxelDims.z / R.direction.z * stepZ); } List<double> t_list = new List<double>(); List<int> Codes = new List<int>(); List<Point> Path_pts = new List<Point>(); List<int> voxelCodes = new List<int>(); List<Point> X_LIST = new List<Point>(); List<double> ulist = new List<double>(); List<double> vlist = new List<double>(); List<double> tlist = new List<double>(); List<int> pidlist = new List<int>(); while (true) { //Check all polygons in the current voxel... foreach (int i in Voxel_Inv[X, Y, Z, top_index]) { if (Poly_Ray_ID[R.ThreadID, top_index][i] != R.Ray_ID) { Poly_Ray_ID[R.ThreadID, top_index][i] = R.Ray_ID; Point Pt; double u=0, v=0, t=0; if (Model[top_index].intersect(i, R, out Pt, out u, out v, out t) && t > 0.0000000001) X_LIST.Add(Pt); ulist.Add(u); vlist.Add(v); tlist.Add(t); pidlist.Add(i); } } for (int c = 0; c < X_LIST.Count; c++) { if (this.Voxels[X, Y, Z].IsPointInBox(X_LIST[c])) { int choice = c; //Ret_Event = X_LIST[c]; for (int s = c; s < X_LIST.Count; s++) { if (tlist[s] < tlist[choice]) { choice = s; //Ret_Event = X_LIST[s]; } } Path_pts.Add(X_LIST[choice]); t_list.Add(tlist[choice]); Ret_Event = new X_Event_NH(Path_pts, ulist[choice], vlist[choice], t_list, pidlist[choice], Codes); //Ret_Event.t += t_start; return true; } } ///////////////////////////////////////// VPrev = Velocities[X, Y, Z]; ///////////////////////////////////////// //Find the Next Voxel... ///////////////////////////////////////////////// if (tMaxX < tMaxY) { if (tMaxX < tMaxZ) { X += stepX; if (X < 0 || X >= VoxelCtX) { Ret_Event = new X_Event(); return false; /* outside grid */ } tMaxX += tDeltaX; if (VPrev != Velocities[X, Y, Z]) { R.direction = XRefraction(R.direction, VPrev, Velocities[X, Y, Z]); if (R.direction.x < 0) { stepX = -1; } else { stepX = 1; } if (R.direction.y < 0) { stepY = -1; } else { stepY = 1; } if (R.direction.z < 0) { stepZ = -1; } else { stepZ = 1; } tDeltaX = (float)(VoxelDims.x / R.direction.x * stepX); tDeltaY = (float)(VoxelDims.y / R.direction.y * stepY); tDeltaZ = (float)(VoxelDims.z / R.direction.z * stepZ); t_list.Add(tDeltaX); Codes.Add(VoxelCode(X,Y,Z)); R.origin += R.direction * tDeltaX; Path_pts.Add(R.origin); X_LIST.Clear(); } } else { Z += stepZ; if (Z < 0 || Z >= VoxelCtZ) { Ret_Event = new X_Event(); return false; /* outside grid */ } tMaxZ += tDeltaZ; if (VPrev != Velocities[X, Y, Z]) { R.direction = ZRefraction(R.direction, VPrev, Velocities[X, Y, Z]); if (R.direction.x < 0) { stepX = -1; } else { stepX = 1; } if (R.direction.y < 0) { stepY = -1; } else { stepY = 1; } if (R.direction.z < 0) { stepZ = -1; } else { stepZ = 1; } tDeltaX = (float)(VoxelDims.x / R.direction.x * stepX); tDeltaY = (float)(VoxelDims.y / R.direction.y * stepY); tDeltaZ = (float)(VoxelDims.z / R.direction.z * stepZ); t_list.Add(tDeltaZ); R.origin += R.direction * tDeltaZ; Path_pts.Add(R.origin); X_LIST.Clear(); } } } else { if (tMaxY < tMaxZ) { Y += stepY; if (Y < 0 || Y >= VoxelCtY) { Ret_Event = new X_Event(); return false; /* outside grid */ } tMaxY += tDeltaY; if (VPrev != Velocities[X, Y, Z]) { R.direction = YRefraction(R.direction, VPrev, Velocities[X, Y, Z]); if (R.direction.x < 0) { stepX = -1; } else { stepX = 1; } if (R.direction.y < 0) { stepY = -1; } else { stepY = 1; } if (R.direction.z < 0) { stepZ = -1; } else { stepZ = 1; } tDeltaX = (float)(VoxelDims.x / R.direction.x * stepX); tDeltaY = (float)(VoxelDims.y / R.direction.y * stepY); tDeltaZ = (float)(VoxelDims.z / R.direction.z * stepZ); t_list.Add(tDeltaY); R.origin += R.direction * tDeltaY; Path_pts.Add(R.origin); X_LIST.Clear(); } } else { Z += stepZ; if (Z < 0 || Z >= VoxelCtZ) { Ret_Event = new X_Event(); return false; /* outside grid */ } tMaxZ += tDeltaZ; if (VPrev != Velocities[X, Y, Z]) { R.direction = ZRefraction(R.direction, VPrev, Velocities[X, Y, Z]); if (R.direction.x < 0) { stepX = -1; } else { stepX = 1; } if (R.direction.y < 0) { stepY = -1; } else { stepY = 1; } if (R.direction.z < 0) { stepZ = -1; } else { stepZ = 1; } tDeltaX = (float)(VoxelDims.x / R.direction.x * stepX); tDeltaY = (float)(VoxelDims.y / R.direction.y * stepY); tDeltaZ = (float)(VoxelDims.z / R.direction.z * stepZ); t_list.Add(tDeltaZ); R.origin += R.direction * tDeltaZ; Path_pts.Add(R.origin); X_LIST.Clear(); } } } } }