Example #1
0
            /// <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);
                }
            }
Example #5
0
            /// <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);
            }
Example #6
0
            /// <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()));
            }
Example #7
0
            /// <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;
                }
Example #10
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;
                }
Example #16
0
            /// <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();
                            }
                        }
                    }
                }
            }