public override Hare.Geometry.Point ClosestPt(Hare.Geometry.Point P, ref double Dist)
            {
                Point3d PR = new Point3d();

                PR = ClosestPt(new Point3d(P.x, P.y, P.z), ref Dist);
                return(new Hare.Geometry.Point(PR.X, PR.Y, PR.Z));
            }
            /// <summary>
            /// Most explicit constructor.
            /// </summary>
            /// <param name="power_In_db">Sound Power of the source</param>
            /// <param name="Source">Origin of the source</param>
            /// <param name="TotalRays_in">Number of rays </param>
            /// <param name="Broadband_Time"></param>
            /// <param name="ID">The identifier of the source</param>
            public Source(double[] power_In_db, Point3d Source, Phase_Regime p, int ID)
            {
                ph = p;
                S_ID = ID;
                H_Center = new Hare.Geometry.Point(Source.X, Source.Y, Source.Z);
                Center = Source;                

                SPL[0] = power_In_db[0];
                SPL[1] = power_In_db[1];
                SPL[2] = power_In_db[2];
                SPL[3] = power_In_db[3];
                SPL[4] = power_In_db[4];
                SPL[5] = power_In_db[5];
                SPL[6] = power_In_db[6];
                SPL[7] = power_In_db[7];

                phase = new double[8];

                SourcePower[0] = 1E-12 * Math.Pow(10, .1 * SPL[0]);
                SourcePower[1] = 1E-12 * Math.Pow(10, .1 * SPL[1]);
                SourcePower[2] = 1E-12 * Math.Pow(10, .1 * SPL[2]);
                SourcePower[3] = 1E-12 * Math.Pow(10, .1 * SPL[3]);
                SourcePower[4] = 1E-12 * Math.Pow(10, .1 * SPL[4]);
                SourcePower[5] = 1E-12 * Math.Pow(10, .1 * SPL[5]);
                SourcePower[6] = 1E-12 * Math.Pow(10, .1 * SPL[6]);
                SourcePower[7] = 1E-12 * Math.Pow(10, .1 * SPL[7]);
            }
예제 #3
0
            private void triangle(Vector P0, Vector P1, Vector P2, int Ord, int max, ref Hare.Geometry.Point[][] P)
            {
                if (Ord < max)
                {
                    Vector P3 = (P0 + P1) / 2;
                    P3.Normalize();

                    Vector P4 = (P1 + P2) / 2;
                    P4.Normalize();

                    Vector P5 = (P2 + P0) / 2;
                    P5.Normalize();

                    this.triangle(P0, P3, P5, Ord + 1, max, ref P);
                    this.triangle(P1, P4, P3, Ord + 1, max, ref P);
                    this.triangle(P2, P5, P4, Ord + 1, max, ref P);
                    this.triangle(P3, P4, P5, Ord + 1, max, ref P);
                }
                else
                {
                    P[Fnum] = new Hare.Geometry.Point[3] {
                        P0, P1, P2
                    };
                    Fnum++;
                }
            }
예제 #4
0
            /// <summary>
            /// Most explicit constructor.
            /// </summary>
            /// <param name="power_In_db">Sound Power of the source</param>
            /// <param name="Source">Origin of the source</param>
            /// <param name="TotalRays_in">Number of rays </param>
            /// <param name="Broadband_Time"></param>
            /// <param name="ID">The identifier of the source</param>
            public Source(double[] power_In_db, Point Source, Phase_Regime p, int ID)
            {
                ph       = p;
                S_ID     = ID;
                H_Center = new Hare.Geometry.Point(Source.x, Source.y, Source.z);
                Center   = Source;

                SPL[0] = power_In_db[0];
                SPL[1] = power_In_db[1];
                SPL[2] = power_In_db[2];
                SPL[3] = power_In_db[3];
                SPL[4] = power_In_db[4];
                SPL[5] = power_In_db[5];
                SPL[6] = power_In_db[6];
                SPL[7] = power_In_db[7];

                phase = new double[8];

                SourcePower[0] = 1E-12 * Math.Pow(10, .1 * SPL[0]);
                SourcePower[1] = 1E-12 * Math.Pow(10, .1 * SPL[1]);
                SourcePower[2] = 1E-12 * Math.Pow(10, .1 * SPL[2]);
                SourcePower[3] = 1E-12 * Math.Pow(10, .1 * SPL[3]);
                SourcePower[4] = 1E-12 * Math.Pow(10, .1 * SPL[4]);
                SourcePower[5] = 1E-12 * Math.Pow(10, .1 * SPL[5]);
                SourcePower[6] = 1E-12 * Math.Pow(10, .1 * SPL[6]);
                SourcePower[7] = 1E-12 * Math.Pow(10, .1 * SPL[7]);
            }
            public override void EdgeFrame_Tangents(Hare.Geometry.Point Origin, Vector Normal, int[] PlaneIDs, ref List <double> dist2, List <Vector> Dir, List <int> EdgeIDs)
            {
                double d = Hare_math.Dot(Normal, Origin);

                //for (int i = 0; i < PlaneCount; i++)
                foreach (int i in EdgeIDs)
                {
                    Hare.Geometry.Point[] Pts = new Hare.Geometry.Point[2];
                    double d_min = double.MaxValue;
                    double d_max = double.MinValue;
                    foreach (int j in Topo[0].Plane_Members[i])
                    {
                        //Do the polygon/plane intersection for each member 'j' of i.
                        Hare.Geometry.Point[] vtx  = Topo[0].Polygon_Vertices(j);
                        Hare.Geometry.Point[] temp = new Hare.Geometry.Point[1];
                        uint tmpcount = 0;

                        for (int k = 0, h = 1; k < vtx.Length; k++, h++)
                        {
                            Vector ab = vtx[h % vtx.Length] - vtx[k];
                            double t  = (d - Hare_math.Dot(Normal, vtx[k])) / Hare_math.Dot(Normal, ab);

                            // If t in [0..1] compute and return intersection point
                            if (t >= 0.0f && t <= 1.0f)
                            {
                                temp[tmpcount] = vtx[k] + t * ab;
                                tmpcount++;
                            }
                            if (h == 0 && tmpcount == 0)
                            {
                                break;
                            }
                            if (tmpcount > 1)
                            {
                                break;
                            }
                        }
                        foreach (Hare.Geometry.Point p in temp)
                        {
                            Hare.Geometry.Point v = Origin - p;
                            double tmp            = v.x * v.x + v.y * v.y + v.z * v.z;
                            if (tmp > d_max)
                            {
                                Pts[1] = p;
                                d_max  = tmp;
                            }
                            if (tmp < d_min)
                            {
                                Pts[0] = p;
                                d_min  = tmp;
                            }
                        }
                    }
                    dist2.Add(d_min);
                    EdgeIDs.Add(i);
                    Vector direction = (Pts[1] - Pts[0]);
                    direction.Normalize();
                    Dir.Add(direction);
                }
            }
예제 #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);
                    }
                }

                base.rayct++;

                return(new BroadRay(H_Center, P, random.Next(), thread, RayPower, 0, Source_ID()));
            }
            /// <summary>
            /// used by the image source method to mirror sources over a face.
            /// </summary>
            /// <param name="Point">the point to mirror</param>
            /// <param name="Top_Id">the id of the topology to reference (for multi-resolution)</param>
            /// <param name="q">the index of the surface to use</param>
            /// <returns>the mirrored point</returns>
            public Hare.Geometry.Point Image(Hare.Geometry.Point Point, int Top_Id, int q)
            {
                //Mirror the point along the plane of the polygon...
                double Dist = Topo[0].DistToPlane(Point, q);

                Hare.Geometry.Point PX = Point - 2 * Topo[Top_Id].Normal(q) * Dist;
                return(PX);
            }
예제 #8
0
            public double Sound_Speed(Hare.Geometry.Point pt)
            {
                int X = (int)Math.Floor((pt.x - OBox.Min_PT.x) / VoxelDims.x);
                int Y = (int)Math.Floor((pt.y - OBox.Min_PT.y) / VoxelDims.y);
                int Z = (int)Math.Floor((pt.z - OBox.Min_PT.z) / VoxelDims.z);

                return(Velocities[X, Y, Z]);
            }
예제 #9
0
            public override BroadRay Directions(int index, int thread, ref Random random, int[] Octaves)
            {
                Hare.Geometry.Point  Pt = T.Polys[rayct % T.Polygon_Count].GetRandomPoint(random.NextDouble(), random.NextDouble(), 0);
                Hare.Geometry.Vector P  = new Vector(Pt.x, Pt.y, Pt.z);
                P.Normalize();
                rayct++;

                return(new BroadRay(H_Center, P, random.Next(), thread, SourcePower, phase, delay, Source_ID(), Octaves)); //Provides divided Power[stochastic]
            }
 public override bool shoot(Ray R, out double u, out double v, out int Poly_ID, out Hare.Geometry.Point X_PT, out double t)
 {
     u       = -1;
     v       = -1;
     Poly_ID = -1;
     X_PT    = new Hare.Geometry.Point();
     t       = -1;
     return(false);
 }
            public override bool shoot(Ray R, out double u, out double v, out int Srf_ID, out Hare.Geometry.Point X_PT, out double t)
            {
                S_Origin = Utilities.PachTools.HPttoRPt(R.origin);
                Srf_ID   = 0;

                while (true)
                {
                    Point3d[] P = Rhino.Geometry.Intersect.Intersection.RayShoot(new Ray3d(S_Origin, new Vector3d(R.direction.x, R.direction.y, R.direction.z)), BrepList, 1);

                    if (P == null)
                    {
                        X_PT = default(Hare.Geometry.Point); u = 0; v = 0; t = 0; return(false);
                    }

                    Voxels.PointIsInVoxel(P[0], ref XVoxel, ref YVoxel, ref ZVoxel);
                    try
                    {
                        SurfaceIndex = Voxels.VoxelList(XVoxel, YVoxel, ZVoxel);
                    }
                    catch (Exception)
                    {
                        //Rare floating point error on some computers... abandon the ray and start the next...
                        //Explanation: This would never happen on my IBM T43P laptop, but happened
                        //consistently millions of function calls into the calculation on my
                        //ASUS K8N-DL based desktop computer. I believe it has something to do with some quirk of that system.
                        //This try...catch statement is here in case this ever manifests on any user's computer.
                        //It is rare enough that this should not affect the accuracy of the calculation.
                        t    = 0.0f;
                        X_PT = default(Hare.Geometry.Point);
                        u    = 0;
                        v    = 0;
                        return(false);
                    }

                    Point3d        CP;
                    Vector3d       N;
                    ComponentIndex CI;
                    double         MD = 0.0001;

                    foreach (int index in SurfaceIndex)
                    {
                        if (BrepList[index].ClosestPoint(P[0], out CP, out CI, out u, out v, MD, out N) && (CI.ComponentIndexType == ComponentIndexType.BrepFace))
                        {
                            if ((Math.Abs(P[0].X - CP.X) < 0.0001) && (Math.Abs(P[0].Y - CP.Y) < 0.0001) && (Math.Abs(P[0].Z - CP.Z) < 0.0001))
                            {
                                Srf_ID = index;
                                X_PT   = new Hare.Geometry.Point(P[0].X, P[0].Y, P[0].Z);
                                t      = (double)(S_Origin.DistanceTo(P[0]));
                                return(true);
                            }
                        }
                    }
                    S_Origin = new Point3d(P[0]);
                }
            }
예제 #12
0
            public bool Cyl_Coord(Hare.Geometry.Point S, Hare.Geometry.Point R, ref double rs, ref double thetas, ref double zs, ref double rr, ref double thetar, ref double zr, out int Obtuse_Side)//, out double[] tm, out double[] tl)
            {
                //diffx = Tangent;
                //diffy = Normal;
                //diffz = Z_Norm;
                Vector S_D = S - Z_mid;
                Vector R_D = R - Z_mid;

                Vector S_Norm = new Vector(S_D.x, S_D.y, S_D.z) / S_D.Length(); // S - Z_mid;
                Vector R_Norm = new Vector(R_D.x, R_D.y, R_D.z) / R_D.Length(); //R - Z_mid;

                double S0 = Hare_math.Dot(S_Norm, Tangent[0]);
                double S1 = Hare_math.Dot(S_Norm, Tangent[1]);

                uint SDIR = 0;

                if (S0 > S1)
                {
                    if (S1 > 0)
                    {
                        SDIR = 1;
                    }
                }

                Obtuse_Side = (Hare_math.Dot(S_Norm, Normal[SDIR]) < 0 ? 1 : 0);

                zs = Hare_math.Dot(S_D, Z_Norm); //S_Coord.z;
                zr = Hare_math.Dot(R_D, Z_Norm); //R_Coord.z;

                Hare.Geometry.Point S_p = S - (Z_mid + zs * Z_Norm);
                Hare.Geometry.Point R_p = R - (Z_mid + zr * Z_Norm);

                rs     = Math.Sqrt(S_p.x * S_p.x + S_p.y * S_p.y + S_p.z * S_p.z); //Math.Sqrt(S_Coord.x * S_Coord.x + S_Coord.y * S_Coord.y + S_Coord.z * S_Coord.z);
                rr     = Math.Sqrt(R_p.x * R_p.x + R_p.y * R_p.y + R_p.z * R_p.z); //Math.Sqrt(R_Coord.x * R_Coord.x + R_Coord.y * R_Coord.y + R_Coord.z * R_Coord.z);
                thetas = Math.Acos(Hare_math.Dot(Tangent[SDIR], S_Norm));          //Math.Atan2(S_Coord.y, S_Coord.x);

                //double sdt = Hare_math.Dot(Tangent[SDIR], S_Norm);
                double rdt = Hare_math.Dot(Normal[SDIR] * (Obtuse_Side == 1 ? 1 : -1), R_Norm);

                if (rdt > 0)
                {
                    thetar = Utilities.Numerics.PiX2 - Math.Acos(Hare_math.Dot(Tangent[SDIR], R_Norm));//Math.Atan2(R_Coord.y, R_Coord.x);
                }
                else
                {
                    thetar = Math.Acos(Hare_math.Dot(Tangent[SDIR], R_Norm));
                }

                //if (thetas < 0) thetas += Utilities.Numerics.PiX2;
                //if (thetar < 0) thetar += Utilities.Numerics.PiX2;
                return(true);
            }
예제 #13
0
        /// <summary>
        /// Returns the list of Apexes for this source/receiver combination.
        /// </summary>
        /// <param name="src">source point</param>
        /// <param name="rec">receiver point</param>
        /// <returns></returns>
        public List <int> Find_Apex(Hare.Geometry.Point src, Hare.Geometry.Point rec)
        {
            List <int> Apex = new List <int>();

            for (int i = 0; i < Sources.Count; i++)
            {
                Vector T_Comp = Hare.Geometry.Hare_math.Cross(Sources[i].Z_mid - src, Sources[i].Z_mid - rec);
                if ((Sources[i].Z_Norm.x * T_Comp.x + Sources[i].Z_Norm.y * T_Comp.y + Sources[i].Z_Norm.z * T_Comp.z) > .95)
                {
                    Apex.Add(i);
                }
            }
            return(Apex);
        }
예제 #14
0
            //public double Apex_Solve(Hare.Geometry.Point src, Hare.Geometry.Point rec, ref double m, ref double l)
            //{
            //    double rr = 0, rs = 0, zr = 0, zs = 0, thetar = 0, thetas = 0;
            //    int obtuse;
            //    if (!Cyl_Coord(src, rec, ref rs, ref thetas, ref zs, ref rr, ref thetar, ref zr, out obtuse, out )) return 0;
            //    m = Math.Sqrt(rs * rs + zs * zs);
            //    l = Math.Sqrt(rr * rr + zr * zr);
            //    double rho = Rho(rr, rs);
            //    double R0 = m + l;//R_o(zr, zs, rr, rs);
            //    double[] phi = Phi(thetas, thetar);
            //    double sinpsi = this.sinpsi(rs, rr, R0);
            //    double B1 = B_1(R0, rho, phi, obtuse);
            //    double sqrt_B1_inv = 1 / Math.Sqrt(B1);
            //    if (rho == 1 || zs == zr)
            //    {
            //        //symmetrical case
            //        if ((zr - zr) / R0 == sincos45)
            //        {
            //            double B4 = B_4(phi, obtuse);
            //            return -v_2pi[obtuse] * (B4 * sqrt_B1_inv) * Math.Atan(Z_Range * sqrt_B1_inv);
            //        }
            //        else
            //        {
            //            double B3 = B_3(R0, rho, sinpsi);
            //            double sqrt_B3_inv = 1 / Math.Sqrt(B3);
            //            double B0 = B_0(R0, rho, phi, rr, rs, sinpsi, obtuse);
            //            return -v_2pi[obtuse] * (B0 / (B3 - B1)) * (sqrt_B1_inv * Math.Atan(Z_Range * sqrt_B1_inv) - sqrt_B3_inv * Math.Atan(Z_Range * sqrt_B3_inv));
            //        }
            //    }
            //    //asymmetrical case
            //    double rt1 = 1 + rho;
            //    double cospsi = this.cospsi(zs, zr, R0);
            //    if (sinpsi * sinpsi == 2 * rho / (rt1 * rt1))
            //    {
            //        double B5 = B_5(R0, rho, phi, cospsi, obtuse);
            //        double B6 = B_6(R0, rho, cospsi);
            //        double B6sqr = B6 * B6;
            //        double ZRB6 = Z_Range + B6;
            //        return v_2pi[obtuse] * (B5 * B5 / (B1 + B6sqr)) * (.5 * Math.Log(Math.Abs(B6sqr * (Z_dot + B1) / (B1 * (ZRB6 * ZRB6))), Math.E) - B6 * sqrt_B1_inv * Math.Atan(Z_Range * sqrt_B1_inv));
            //    }
            //    else
            //    {
            //        double B0 = B_0(R0, rho, phi, rs, rr, sinpsi, obtuse);
            //        double B2 = B_2(R0, rho, sinpsi, cospsi);
            //        double B3 = B_3(R0, rho, sinpsi);
            //        double B2_2 = B2 * B2;
            //        double B1_B3 = B1 - B3;
            //        double F = this.F(B2, B3);
            //        return v_2pi[obtuse] * (B0 * B2 / (B1 * B2_2 + B1_B3 * B1_B3)) * (0.5 * Math.Log(Math.Abs((B3 * (Z_dot + B1)) / B1 * (Z_dot + B2 * Z_Range + B3)), Math.E) + ((2 * B1_B3 - B2_2) * sqrt_B1_inv / B2) * Math.Atan(Z_Range * sqrt_B1_inv) + ((-2 * B1_B3 - B2_2) / (2 * B2)) * F);
            //    }
            //}

            public double Flex_Solve(Hare.Geometry.Point src, Hare.Geometry.Point rec, ref double m, ref double l, ref double[] dM, ref double[] dL)
            {
                double zr = 0, zs = 0, thetar = 0, thetas = 0;
                int    obtuse;
                double rr = 0, rs = 0;

                if (!Cyl_Coord(src, rec, ref rs, ref thetas, ref zs, ref rr, ref thetar, ref zr, out obtuse))
                {
                    return(0);
                }
                double Za = Z_apex(zs, zr, rs, rr);

                ////get the range of times that this sample occupies./////////////////////////////////
                //double z0 = Math.Abs(zs);
                //double zl = (z0 - Z_Range_2;
                //double zu = z0 + Z_Range_2;
                //tm = new double[2] { Math.Sqrt(rs * rs + zl * zl), Math.Sqrt(rs * rs + zu * zu) };
                //z0 = Math.Abs(zr);
                //zl = z0 - Z_Range_2;
                //zu = z0 + Z_Range_2;
                //tl = new double[2] { Math.Sqrt(rr * rr + zl * zl), Math.Sqrt(rr * rr + zu * zu) };
                //////////////////////////////////////////////////////////////////////////////////////

                //////////////////////////////////
                //double zm = Za - zs, zl = Za - zr;
                double zm = Math.Abs(zs);
                double zl = Math.Abs(zr);
                double zml = zm - Z_Range_2;
                double zmu = zm + Z_Range_2;
                double zll = zl - Z_Range_2;
                double zlu = zl + Z_Range_2;
                double rs_2 = rs * rs, rr_2 = rr * rr;

                dM = new double[] { Math.Sqrt(zml * zml + rs_2), Math.Sqrt(zmu * zmu + rs_2) };
                dL = new double[] { Math.Sqrt(zll * zll + rr_2), Math.Sqrt(zlu * zlu + rr_2) };
                //////////////////////////////////
                if (Math.Abs(Za) < Z_Range_2)
                {
                    double B = Apex_Solve(Za, zs, zr, rs, rr, thetas, thetar, obtuse, out m, out l);
                    dM[0] = m;
                    dL[0] = l;
                    if (double.IsNaN(B))
                    {
                        Rhino.RhinoApp.WriteLine("EdgeCalc gave NAN");
                    }
                    return(B);
                }
                return(Gen_Solve(Za, zs, zr, rs, rr, thetas, thetar, obtuse, ref m, ref l));
            }
예제 #15
0
            public EdgeSource(int[] attr_in, Hare.Geometry.Point PtZ0, Hare.Geometry.Point _PtZ, Vector[] _Tangents)
            {
                attr    = attr_in;
                Tangent = _Tangents;
                Z_Norm  = _PtZ - PtZ0;

                Z_Range   = Z_Norm.Length();
                Z_dot     = Z_Range * Z_Range;//Hare_math.Dot(Z_Norm, Z_Norm);
                Z_Norm   /= Z_Range;
                Z_Range_2 = Z_Range / 2;
                Z_mid     = (PtZ0 + _PtZ) / 2;
                Vector Bisector = (Tangent[0] + Tangent[1]) / 2;

                Bisector.Normalize();
                double BisectAngle = Math.Acos(Hare_math.Dot(Tangent[0], Bisector));

                if (BisectAngle == 0)
                {
                    BisectAngle = 1E-12;
                }
                v = new double[2] {
                    Math.PI / (2 * BisectAngle), Math.PI / (Utilities.Numerics.PiX2 - 2 * BisectAngle)
                };
                v_4pi = new double[2] {
                    v[0] / (4 * Math.PI), v[1] / (4 * Math.PI)
                };
                v_2pi = new double[2] {
                    v[0] / (2 * Math.PI), v[1] / (2 * Math.PI)
                };
                Normal[0] = Hare_math.Cross(_Tangents[0], Z_Norm);
                Normal[1] = Hare_math.Cross(_Tangents[1], Z_Norm * -1);

                if (Hare_math.Dot(Normal[0], Bisector) > 0)
                {
                    Normal[0] *= -1;
                    Normal[1] *= -1;
                }

                ////////////////////////////
                //VisCheck//
                Rhino.Geometry.Point3d pt = new Rhino.Geometry.Point3d(Z_mid.x, Z_mid.y, Z_mid.z);
                Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(pt, pt + new Rhino.Geometry.Point3d(Normal[0].x, Normal[0].y, Normal[0].z));
                Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(pt, pt + new Rhino.Geometry.Point3d(Normal[1].x, Normal[1].y, Normal[1].z));
                //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(pt, pt + new Rhino.Geometry.Point3d(Tangent[0].x, Tangent[0].y, Tangent[0].z));
                //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(pt, pt + new Rhino.Geometry.Point3d(Tangent[1].x, Tangent[1].y, Tangent[1].z));
                //////Rhino.RhinoDoc.ActiveDoc.Objects.AddPoint(new Rhino.Geometry.Point3d(Z_mid.x, Z_mid.y, Z_mid.z));
            }
예제 #16
0
            public Hare.Geometry.Point ClosestPoint(Hare.Geometry.Point p, out int sel)
            {
                double min = double.PositiveInfinity;

                sel = -1;
                for (int i = 0; i < Samples.Length; i++)
                {
                    Hare.Geometry.Vector v = p - Samples[i];
                    double lsq             = Hare_math.Dot(v, v);
                    if (lsq < min)
                    {
                        min = lsq;
                        sel = i;
                    }
                }
                return(Samples[sel]);
            }
 public void Update_Position(Hare.Geometry.Point Center)
 {
     for (int i = 0; i < m_HareMesh[4].Vertex_Count; i++)
     {
         Point Po = m_HareMesh[4][i];
         Point P  = new Point(Po.x, Po.y, Po.z) / 90; //new Point((float)(Po.x + Center.x - CurrentPos.x), (float)(Po.y + Center.y - CurrentPos.y), (float)(Po.z + Center.z - CurrentPos.z));
         m_DisplayMesh.Set_Vertex(i, P);
     }
     Update_Aim();
     for (int i = 0; i < m_HareMesh[4].Vertex_Count; i++)
     {
         Point Po = m_DisplayMesh[i];
         Point P  = new Point((float)(Po.x + Center.x), (float)(Po.y + Center.y), (float)(Po.z + Center.z)); //new Point((float)(Po.x + Center.x - CurrentPos.x), (float)(Po.y + Center.y - CurrentPos.y), (float)(Po.z + Center.z - CurrentPos.z));
         m_DisplayMesh.Set_Vertex(i, P);
     }
     CurrentPos = Center;
 }
            public override Hare.Geometry.Point ClosestPt(Hare.Geometry.Point P, ref double Dist)
            {
                double Max = double.MaxValue;

                Hare.Geometry.Point RP = new Hare.Geometry.Point();
                Hare.Geometry.Point TP;
                for (int i = 0; i < Topo[0].Polygon_Count; i++)
                {
                    TP   = Topo[0].Closest_Point(P, i);
                    Dist = TP.x * TP.x + TP.y * TP.y + TP.z * TP.z;
                    if (Dist < Max)
                    {
                        RP  = TP;
                        Max = Dist;
                    }
                }
                Dist = Math.Sqrt(Max);
                return(RP);
            }
예제 #19
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()));
            }
 public override bool shoot(Hare.Geometry.Ray R, out double u, out double v, out int Poly_ID, out Hare.Geometry.Point X_PT, out double t)
 {
     Hare.Geometry.X_Event X = new Hare.Geometry.X_Event();
     if (SP.Shoot(R, 0, out X))
     {
         Poly_ID = X.Poly_id;
         X_PT    = X.X_Point;
         t       = X.t;
         u       = 0;
         v       = 0;
         return(true);
     }
     Poly_ID = 0;
     X_PT    = new Hare.Geometry.Point();
     //Rhino.RhinoDoc.ActiveDoc.Objects.Add(new Rhino.Geometry.LineCurve(Utilities.PachTools.HPttoRPt(R.origin), Utilities.PachTools.HPttoRPt(R.origin + R.direction)));
     t = 0;
     u = 0;
     v = 0;
     return(false);
 }
예제 #21
0
            public EdgeSource(int[] attr_in, Hare.Geometry.Point Z_mid_in, double Delta_Z, Vector[] _Tangents)
            {
                attr      = attr_in;
                Tangent   = _Tangents;
                Z_Norm    = Hare.Geometry.Hare_math.Cross(_Tangents[0], _Tangents[1]);
                Z_Range   = Delta_Z;
                Z_dot     = Z_Range * Z_Range;//Hare_math.Dot(Z_Norm, Z_Norm);
                Z_Range_2 = Z_Range / 2;
                Z_Norm.Normalize();
                Z_mid = Z_mid_in;
                Vector Bisector = (Tangent[0] + Tangent[1]) / 2;

                Bisector.Normalize();
                double BisectAngle = Math.Acos(Hare_math.Dot(Tangent[0], Bisector));

                if (BisectAngle == 0)
                {
                    BisectAngle = 1E-12;
                }
                v = new double[2] {
                    Math.PI / (2 * BisectAngle), Math.PI / (Utilities.Numerics.PiX2 - 2 * BisectAngle)
                };
                v_4pi = new double[2] {
                    v[0] / (4 * Math.PI), v[1] / (4 * Math.PI)
                };
                v_2pi = new double[2] {
                    v[0] / (2 * Math.PI), v[1] / (2 * Math.PI)
                };
                //BisectAngle = Math.Cos(BisectAngle);
                Normal[0] = Hare_math.Cross(_Tangents[0], Z_Norm);
                Normal[1] = Hare_math.Cross(_Tangents[1], Z_Norm * -1);

                if (Hare_math.Dot(Normal[0], Bisector) > 0)
                {
                    Normal[0] *= -1;
                    Normal[1] *= -1;
                }
            }
예제 #22
0
                public override double[] DirPower(Vector direction, ref Hare.Geometry.Point[] samples, int i, ref double[] domainpower)
                {
                    double[] raypower = new double[8];

                    Hare.Geometry.Point  P = samples[i];
                    Hare.Geometry.Vector fore;
                    if (i == 0)
                    {
                        fore = P - samples[1];
                    }
                    else if (i == samples.Length - 1)
                    {
                        fore = P - samples[i - 1];
                    }
                    else
                    {
                        fore = ((P - samples[i - 1]) + (samples[i + 1] - P)) / 2;
                    }

                    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);
                }
            public EdgeSource(int[] attr_in, Hare.Geometry.Point PtZ0, Hare.Geometry.Point _PtZ, Vector[] _Tangents)
            {
                attr = attr_in;
                Tangent = _Tangents;
                Z_Norm = _PtZ - PtZ0;

                Z_Range = Z_Norm.Length();
                Z_dot = Z_Range * Z_Range;//Hare_math.Dot(Z_Norm, Z_Norm);
                Z_Norm/= Z_Range;
                Z_Range_2 = Z_Range / 2;
                Z_mid = (PtZ0 + _PtZ) / 2;
                Vector Bisector = (Tangent[0] + Tangent[1])/2;
                Bisector.Normalize();
                double BisectAngle = Math.Acos(Hare_math.Dot(Tangent[0], Bisector));
                if (BisectAngle == 0) BisectAngle = 1E-12;
                v = new double[2] { Math.PI / (2 * BisectAngle), Math.PI / (Utilities.Numerics.PiX2 - 2 * BisectAngle) };
                v_4pi = new double[2] { v[0] / (4 * Math.PI), v[1] / (4 * Math.PI) };
                v_2pi = new double[2] { v[0] / (2 * Math.PI), v[1] / (2 * Math.PI) };
                Normal[0] = Hare_math.Cross(_Tangents[0], Z_Norm);
                Normal[1] = Hare_math.Cross(_Tangents[1], Z_Norm*-1);

                if(Hare_math.Dot(Normal[0], Bisector) > 0)
                {
                    Normal[0] *= -1;
                    Normal[1] *= -1;
                }
                
                ////////////////////////////
                //VisCheck//
                Rhino.Geometry.Point3d pt = new Rhino.Geometry.Point3d(Z_mid.x, Z_mid.y, Z_mid.z);
                Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(pt, pt + new Rhino.Geometry.Point3d(Normal[0].x, Normal[0].y, Normal[0].z));
                Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(pt, pt + new Rhino.Geometry.Point3d(Normal[1].x, Normal[1].y, Normal[1].z));
                //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(pt, pt + new Rhino.Geometry.Point3d(Tangent[0].x, Tangent[0].y, Tangent[0].z));
                //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(pt, pt + new Rhino.Geometry.Point3d(Tangent[1].x, Tangent[1].y, Tangent[1].z));
                //////Rhino.RhinoDoc.ActiveDoc.Objects.AddPoint(new Rhino.Geometry.Point3d(Z_mid.x, Z_mid.y, Z_mid.z));
            }
예제 #24
0
            /// <summary>
            /// Constructor assigns a default sound power level of 120 dB per octave.
            /// </summary>
            /// <param name="Source">Origin of the source</param>
            /// <param name="TotalRays_in">Number of rays </param>
            /// <param name="Broadband_Time"></param>
            /// <param name="ID">The identifier of the source</param>
            public Source(Point Source, int ID)
            {
                S_ID     = ID;
                H_Center = new Hare.Geometry.Point(Source.x, Source.y, Source.z);
                Center   = Source;

                SPL[0] = 120;
                SPL[1] = 120;
                SPL[2] = 120;
                SPL[3] = 120;
                SPL[4] = 120;
                SPL[5] = 120;
                SPL[6] = 120;
                SPL[7] = 120;

                SourcePower[0] = 1E-12 * Math.Pow(10, .1 * SPL[0]);
                SourcePower[1] = 1E-12 * Math.Pow(10, .1 * SPL[1]);
                SourcePower[2] = 1E-12 * Math.Pow(10, .1 * SPL[2]);
                SourcePower[3] = 1E-12 * Math.Pow(10, .1 * SPL[3]);
                SourcePower[4] = 1E-12 * Math.Pow(10, .1 * SPL[4]);
                SourcePower[5] = 1E-12 * Math.Pow(10, .1 * SPL[5]);
                SourcePower[6] = 1E-12 * Math.Pow(10, .1 * SPL[6]);
                SourcePower[7] = 1E-12 * Math.Pow(10, .1 * SPL[7]);
            }
            /// <summary>
            /// creates a geodesic sphere.
            /// </summary>
            /// <param name="order"></param>
            public void GeoSphere(int order)
            {
                double sqr5 = System.Math.Sqrt(5.0);
                double phi = (1.0 + sqr5) * 0.5; // golden ratio
                double ratio = System.Math.Sqrt(10.0 + (2.0 * sqr5)) / (4.0 * phi);
                double a = (.25 / ratio) * 0.5;
                double b = (.25 / ratio) / (2.0 * phi);

                // Define the icosahedron's 12 vertices
                Vector P0 = new Vector(0, b, -a);
                Vector P1 = new Vector(b, a, 0);
                Vector P2 = new Vector(-b, a, 0);
                Vector P3 = new Vector(0, b, a);
                Vector P4 = new Vector(0, -b, a);
                Vector P5 = new Vector(-a, 0, b);
                Vector P6 = new Vector(0, -b, -a);
                Vector P7 = new Vector(a, 0, -b);
                Vector P8 = new Vector(a, 0, b);
                Vector P9 = new Vector(-a, 0, -b);
                Vector P10 = new Vector(b, -a, 0);
                Vector P11 = new Vector(-b, -a, 0);

                P0.Normalize();
                P1.Normalize();
                P2.Normalize();
                P3.Normalize();
                P4.Normalize();
                P5.Normalize();
                P6.Normalize();
                P7.Normalize();
                P8.Normalize();
                P9.Normalize();
                P10.Normalize();
                P11.Normalize();

                Hare.Geometry.Point[][] P = new Hare.Geometry.Point[20 * (int)Math.Pow(4, order)][];

                //Create the icosahedron's 20 triangular faces
                triangle(P0, P1, P2, 0, order, ref P);
                triangle(P3, P2, P1, 0, order, ref P);
                triangle(P3, P4, P5, 0, order, ref P);
                triangle(P3, P8, P4, 0, order, ref P);
                triangle(P0, P6, P7, 0, order, ref P);
                triangle(P0, P9, P6, 0, order, ref P);
                triangle(P4, P10, P11, 0, order, ref P);
                triangle(P6, P11, P10, 0, order, ref P);
                triangle(P2, P5, P9, 0, order, ref P);
                triangle(P11, P9, P5, 0, order, ref P);
                triangle(P1, P7, P8, 0, order, ref P);
                triangle(P10, P8, P7, 0, order, ref P);
                triangle(P3, P5, P2, 0, order, ref P);
                triangle(P3, P1, P8, 0, order, ref P);
                triangle(P0, P2, P9, 0, order, ref P);
                triangle(P0, P7, P1, 0, order, ref P);
                triangle(P6, P9, P11, 0, order, ref P);
                triangle(P6, P10, P7, 0, order, ref P);
                triangle(P4, P11, P5, 0, order, ref P);
                triangle(P4, P8, P10, 0, order, ref P);

                T = new Topology(P);
            }
        public Topology[] Balloons(double[] spl_values)
        {
            Topology[] Balloon = new Topology[8];

            int umax, vmax;
            switch (Type)
            {
                case 0:
                    umax = 19;
                    vmax = 36;
                    break;
                case 1:
                    umax = 37;
                    vmax = 72;
                    break;
                default:
                    throw new Exception("Balloon type not valid for this version of CLF.");
            }

            for (int oct = 1; oct < 9; oct++)
            {
                string[] values;
                if (code[oct - 1] != "")
                {
                    values = code[oct - 1].Split(';');
                }
                else
                {
                    values = new string[umax * vmax];
                    for (int i = 0; i < values.Length; i++)
                    {
                        values[i] = "0";
                    }
                }

                Vector[,] Magnitude = new Vector[umax, vmax];
                double Theta, Phi;
                int idx = 0;
                for (int v = 0; v < vmax; v++)
                {
                    for (int u = 0; u < umax; u++)
                    {
                        if (double.IsInfinity(spl_values[oct - 1]) || double.IsNaN(spl_values[oct - 1]))
                        {
                            Magnitude[u, v] = new Vector();
                        }
                        else
                        {
                            Theta = u * System.Math.PI / (umax - 1);
                            Phi = 2 * v * System.Math.PI / (vmax) + System.Math.PI / 2;
                            Magnitude[u, v] = new Vector(Math.Sin(Theta) * Math.Cos(Phi), Math.Cos(Theta), Math.Sin(Theta) * Math.Sin(Phi));
                            Magnitude[u, v].Normalize();
                            Magnitude[u, v] *= (double.Parse(values[idx]) + spl_values[oct - 1]);
                        }
                        idx++;
                    }
                }

                for (int u = 0; u < umax; u++)
                {
                    for (int v = 0; v < vmax; v++)
                    {
                        double roll = CurrentAxi * Math.PI / 180;
                        double yaw = CurrentAlt * Math.PI / 180;
                        double pitch = CurrentAzi * Math.PI / 180;

                        double x = Magnitude[u, v].x;
                        Magnitude[u, v].x = x * Math.Cos(roll) - Magnitude[u, v].z * Math.Sin(roll);
                        Magnitude[u, v].z = x * Math.Sin(roll) + Magnitude[u, v].z * Math.Cos(roll);
                        double y = Magnitude[u, v].y;
                        Magnitude[u, v].y = y * Math.Cos(yaw) - Magnitude[u, v].z * Math.Sin(yaw);
                        Magnitude[u, v].z = y * Math.Sin(yaw) + Magnitude[u, v].z * Math.Cos(yaw);
                        x = Magnitude[u, v].x;
                        Magnitude[u, v].x = x * Math.Cos(pitch) - Magnitude[u, v].y * Math.Sin(pitch);
                        Magnitude[u, v].y = x * Math.Sin(pitch) + Magnitude[u, v].y * Math.Cos(pitch);
                    }
                }

                List<Hare.Geometry.Point[]> list = new List<Hare.Geometry.Point[]>();
                //Create a mesh of the points...
                for (int u = 0; u < umax - 1; u++)
                {
                    for (int v = 0; v < vmax; v++)
                    {
                        Hare.Geometry.Point[] Poly = new Hare.Geometry.Point[3];
                        Poly[0] = Magnitude[u, v];
                        Poly[1] = Magnitude[u, (v + 1) % vmax];
                        Poly[2] = Magnitude[u + 1, v];
                        list.Add(Poly);
                        //Balloon[oct - 1].Add_Polygon(Poly);

                        Poly = new Hare.Geometry.Point[3];
                        Poly[0] = Magnitude[u, (v + 1) % vmax];
                        Poly[1] = Magnitude[u + 1, (v + 1) % vmax];
                        Poly[2] = Magnitude[u + 1, v];
                        list.Add(Poly);
                        //Balloon[oct - 1].Add_Polygon(Poly);
                    }
                }

                double Minx = double.MaxValue, Miny = double.MaxValue, Minz = double.MaxValue, Maxx = double.MinValue, Maxy = double.MinValue, Maxz = double.MinValue;
                foreach(Hare.Geometry.Point[] p in list)
                {
                    foreach(Hare.Geometry.Point p0 in p)
                    {
                        if (p0.x < Minx) Minx = p0.x;
                        if (p0.y < Miny) Miny = p0.y;
                        if (p0.z < Minz) Minz = p0.z;
                        if (p0.x > Maxx) Maxx = p0.x;
                        if (p0.y > Maxy) Maxy = p0.y;
                        if (p0.z > Maxz) Maxz = p0.z;
                    }
                }

                Balloon[oct - 1] = new Topology(new Hare.Geometry.Point(Minx, Miny, Minz), new Hare.Geometry.Point(Maxx, Maxy, Maxz));
                foreach (Hare.Geometry.Point[] p in list) Balloon[oct - 1].Add_Polygon(p);
            }
            Balloon[0].Finish_Topology();
            Balloon[1].Finish_Topology();
            Balloon[2].Finish_Topology();
            Balloon[3].Finish_Topology();
            Balloon[4].Finish_Topology();
            Balloon[5].Finish_Topology();
            Balloon[6].Finish_Topology();
            Balloon[7].Finish_Topology();
            return Balloon;
        }
예제 #27
0
            /// <summary>
            /// creates a geodesic sphere.
            /// </summary>
            /// <param name="order"></param>
            public void GeoSphere(int order)
            {
                double sqr5  = System.Math.Sqrt(5.0);
                double phi   = (1.0 + sqr5) * 0.5; // golden ratio
                double ratio = System.Math.Sqrt(10.0 + (2.0 * sqr5)) / (4.0 * phi);
                double a     = (.25 / ratio) * 0.5;
                double b     = (.25 / ratio) / (2.0 * phi);

                // Define the icosahedron's 12 vertices
                Vector P0  = new Vector(0, b, -a);
                Vector P1  = new Vector(b, a, 0);
                Vector P2  = new Vector(-b, a, 0);
                Vector P3  = new Vector(0, b, a);
                Vector P4  = new Vector(0, -b, a);
                Vector P5  = new Vector(-a, 0, b);
                Vector P6  = new Vector(0, -b, -a);
                Vector P7  = new Vector(a, 0, -b);
                Vector P8  = new Vector(a, 0, b);
                Vector P9  = new Vector(-a, 0, -b);
                Vector P10 = new Vector(b, -a, 0);
                Vector P11 = new Vector(-b, -a, 0);

                P0.Normalize();
                P1.Normalize();
                P2.Normalize();
                P3.Normalize();
                P4.Normalize();
                P5.Normalize();
                P6.Normalize();
                P7.Normalize();
                P8.Normalize();
                P9.Normalize();
                P10.Normalize();
                P11.Normalize();

                Hare.Geometry.Point[][] P = new Hare.Geometry.Point[20 * (int)Math.Pow(4, order)][];

                //Create the icosahedron's 20 triangular faces
                triangle(P0, P1, P2, 0, order, ref P);
                triangle(P3, P2, P1, 0, order, ref P);
                triangle(P3, P4, P5, 0, order, ref P);
                triangle(P3, P8, P4, 0, order, ref P);
                triangle(P0, P6, P7, 0, order, ref P);
                triangle(P0, P9, P6, 0, order, ref P);
                triangle(P4, P10, P11, 0, order, ref P);
                triangle(P6, P11, P10, 0, order, ref P);
                triangle(P2, P5, P9, 0, order, ref P);
                triangle(P11, P9, P5, 0, order, ref P);
                triangle(P1, P7, P8, 0, order, ref P);
                triangle(P10, P8, P7, 0, order, ref P);
                triangle(P3, P5, P2, 0, order, ref P);
                triangle(P3, P1, P8, 0, order, ref P);
                triangle(P0, P2, P9, 0, order, ref P);
                triangle(P0, P7, P1, 0, order, ref P);
                triangle(P6, P9, P11, 0, order, ref P);
                triangle(P6, P10, P7, 0, order, ref P);
                triangle(P4, P11, P5, 0, order, ref P);
                triangle(P4, P8, P10, 0, order, ref P);

                T = new Topology(P);
            }
            /// <summary>
            /// Constructor assigns a default sound power level of 120 dB per octave.
            /// </summary>
            /// <param name="Source">Origin of the source</param>
            /// <param name="TotalRays_in">Number of rays </param>
            /// <param name="Broadband_Time"></param>
            /// <param name="ID">The identifier of the source</param>
            public Source(Point3d Source, int ID)
            {
                S_ID = ID;
                H_Center = new Hare.Geometry.Point(Source.X, Source.Y, Source.Z);
                Center = Source;

                SPL[0] = 120;
                SPL[1] = 120;
                SPL[2] = 120;
                SPL[3] = 120;
                SPL[4] = 120;
                SPL[5] = 120;
                SPL[6] = 120;
                SPL[7] = 120;

                SourcePower[0] = 1E-12 * Math.Pow(10, .1 * SPL[0]);
                SourcePower[1] = 1E-12 * Math.Pow(10, .1 * SPL[1]);
                SourcePower[2] = 1E-12 * Math.Pow(10, .1 * SPL[2]);
                SourcePower[3] = 1E-12 * Math.Pow(10, .1 * SPL[3]);
                SourcePower[4] = 1E-12 * Math.Pow(10, .1 * SPL[4]);
                SourcePower[5] = 1E-12 * Math.Pow(10, .1 * SPL[5]);
                SourcePower[6] = 1E-12 * Math.Pow(10, .1 * SPL[6]);
                SourcePower[7] = 1E-12 * Math.Pow(10, .1 * SPL[7]);
            }
예제 #29
0
            /// <summary>
            /// Receiver bank constructor.
            /// </summary>
            /// <param name="Pt">array of receiver origin points</param>
            /// <param name="SrcPT">sound source point</param>
            /// <param name="Room">the acoustical scene</param>
            /// <param name="RCT">the number or rays emanating from the source</param>
            /// <param name="CSound">the speed of sound in m/s</param>
            /// <param name="SampleRate_in">the simulation histogram sampling frequency</param>
            /// <param name="COTime_in">the Cut Off Time in ms.</param>
            /// <param name="Type">the type of receivers contained in this receiver bank</param>
            public Receiver_Bank(IEnumerable<Point3d> Pt, Point3d SrcPT, Scene Sc, int SampleRate_in, double COTime_in, double delayinms, Type Type)
            {
                delay_ms = delayinms;
                SampleRate = SampleRate_in;
                SampleCT = (int)Math.Floor(COTime_in * SampleRate_in / 1000);
                this.CutOffTime = COTime_in;
                Rec_Type = Type;
                Point3d[] arrPts = Pt.ToArray<Point3d>();
                Rec_List = new Spherical_Receiver[arrPts.Length];
                Min = new Hare.Geometry.Point(double.PositiveInfinity, double.PositiveInfinity, double.PositiveInfinity);
                Max = new Hare.Geometry.Point(double.NegativeInfinity, double.NegativeInfinity, double.NegativeInfinity);

                for (int i = 0; i < arrPts.Length; i++)
                {
                    if (Type == Type.Stationary) Rec_List[i] = new Spherical_Receiver(new Point3d(arrPts[i]), new Point3d(SrcPT), Sc.Attenuation(Utilities.PachTools.RPttoHPt(arrPts[i])), Sc.Sound_speed(Utilities.PachTools.RPttoHPt(arrPts[i])), Sc.Rho(Utilities.PachTools.RPttoHPt(arrPts[i])), SampleRate_in, COTime_in);
                    if (Type == Type.Variable) Rec_List[i] = new Expanding_Receiver(new Point3d(arrPts[i]), new Point3d(SrcPT), RayCount, Sc.Attenuation(Utilities.PachTools.RPttoHPt(arrPts[i])), Sc.Sound_speed(Utilities.PachTools.RPttoHPt(arrPts[i])), Sc.Rho(Utilities.PachTools.RPttoHPt(arrPts[i])), SampleRate_in, COTime_in);

                    if (arrPts[i].X > Max.x) Max.x = arrPts[i].X;
                    if (arrPts[i].Y > Max.y) Max.y = arrPts[i].Y;
                    if (arrPts[i].Z > Max.z) Max.z = arrPts[i].Z;
                    if (arrPts[i].X < Min.x) Min.x = arrPts[i].X;
                    if (arrPts[i].Y < Min.y) Min.y = arrPts[i].Y;
                    if (arrPts[i].Z < Min.z) Min.z = arrPts[i].Z;
                }
            }
            //public override void Plane_Intersection(Point Origin, Vector Normal, int[] SrfIDs, ref List<double> dist2, List<Vector> Dir, List<int> IDs)
            //{
            //    foreach (int i in SrfIDs)
            //    {
            //        double u = 0, v = 0;
            //        SurfaceArray[i].GetClosestPoint(Utilities.PachTools.HPttoRPt(Origin), ref u, ref v);
            //        Vector3d N = new Vector3d();
            //        SurfaceArray[i].EvNormal(u, v, ref N);
            //        Vector tan = Hare_math.Cross(Normal, Utilities.PachTools.RPttoHPt((Point3d)N));
            //        Point P = Origin + tan * 0.01;
            //        ///There has got to be a better way...
            //    }
            //}

            public override void EdgeFrame_Tangents(Hare.Geometry.Point Origin, Vector Normal, int[] PlaneIDs, ref List <double> dist2, List <Vector> Dir, List <int> IDs)
            {
                throw new NotImplementedException();//TODO:
            }
예제 #31
0
        /// <summary>
        /// Constructor which takes a Binary Reader at the appropriate point, from which calculated data will be extracted.
        /// </summary>
        /// <param name="BR"></param>
        /// <param name="Rec_CT"></param>
        /// <param name="Direct"></param>
        /// <returns></returns>
        public static ImageSourceData Read_Data(ref System.IO.BinaryReader BR, int Rec_CT, Direct_Sound Direct, bool Edges, int Src_ID, string version)
        {
            ImageSourceData IS = new ImageSourceData();
            IS.ValidPaths = new List<Deterministic_Reflection>[Rec_CT];
            IS.Direct_Time = new double[Rec_CT];
            double v = double.Parse(version.Substring(0, 3));

            for (int q = 0; q < Rec_CT; q++)
            {
                IS.ValidPaths[q] = new List<Deterministic_Reflection>();
                //2. Write the receiver number:int
                BR.ReadInt32();
                //3. Write number of paths:int
                int PathCt = BR.ReadInt32();
                for (int i = 0; i < PathCt; i++)
                {
                    int ReflectionType = BR.ReadInt16();
                    if (ReflectionType == 0)
                    {
                        //Speculare Reflection
                        //4. Write the number of reflection path points
                        Hare.Geometry.Point[] PTS = new Hare.Geometry.Point[BR.ReadInt32()];

                        //5. Write the reflection path:double
                        for (int r = 0; r < PTS.Length; r++)
                        {
                            PTS[r] = new Hare.Geometry.Point(BR.ReadDouble(), BR.ReadDouble(), BR.ReadDouble());
                        }

                        //Previously, Pachyderm performed the deterministic part in intensity only...                    
                        //6a. Write the energy values
                        double[] Energy = new double[8];
                        Energy[0] = BR.ReadDouble();
                        Energy[1] = BR.ReadDouble();
                        Energy[2] = BR.ReadDouble();
                        Energy[3] = BR.ReadDouble();
                        Energy[4] = BR.ReadDouble();
                        Energy[5] = BR.ReadDouble();
                        Energy[6] = BR.ReadDouble();
                        Energy[7] = BR.ReadDouble();

                        bool Special_Filter = BR.ReadBoolean();
                        System.Numerics.Complex[] Filter = null;
                   
                        if (Special_Filter)
                        {
                            //6aa1. Write length of filter...
                            int Filter_Length = BR.ReadInt32();
                            Filter = new System.Numerics.Complex[Filter_Length];
                            //6aa2. Write filter...
                            for(int j = 0; j < Filter.Length; j++)
                            {
                                Filter[j] = new System.Numerics.Complex(BR.ReadDouble(), BR.ReadDouble());
                            }
                            //6aa3. Write octave band root mean square pressure...
                        }

                        double[] prms = new double[8];
                        for (int j = 0; j < prms.Length; j++) prms[j] = BR.ReadDouble();

                        //7. Write the arrival time:double
                        double Time = BR.ReadDouble();

                        //8. Write the Reflection Sequence:int
                        int[] Sequence = new int[PTS.Length - 2];
                        for (int r = 0; r < Sequence.Length; r++)
                        {
                            Sequence[r] = BR.ReadInt32();
                        }

                        IS.ValidPaths[q].Add(new Specular_Path(PTS, Energy, prms, Filter, Time, Sequence, Direct.Min_Time(q), Src_ID));
                    }
                    else if (ReflectionType == 1)
                    {
                        //TODO: Find a robust format for compound reflection paths...
                        ///Specular Path:
                        //BW.Write((short)1);
                        //Write the number of samples and the pressure signal down:
                        //Write the number of samples and the pressure signal down:

                        //6a.2. Write the number of samples in the pressure signal.(int)
                        //6b. Write the pressure values
                    }

                }
            }
            return IS;
        }
        public Speaker_Balloon(string[] Ballooncode_in, string SWL_in, int Type_in, Hare.Geometry.Point Center)//int sym_in,
        {
            code = Ballooncode_in;
            Type = Type_in;
            if (SWL_in != "" || SWL_in != null)
            {
                SWL = SWL_in;
            }
            else
            {
                SWL_in = "120; 120; 120; 120; 120; 120; 120; 120";
            }
            string[] swl        = SWL.Split(';');
            double[] swl_values = new double[8];

            Vector upper = new Vector(0, 1, 0);

            int umax, vmax;

            switch (Type)
            {
            case 0:
                umax = 19;
                vmax = 36;
                break;

            case 1:
                umax = 37;
                vmax = 72;
                break;

            default:
                throw new Exception();
            }

            m_HareMesh = new Topology[8];
            for (int oct = 1; oct < 9; oct++)
            {
                string[] values;
                swl_values[oct - 1] = double.Parse(swl[oct - 1]);
                if (code[oct - 1] != "")
                {
                    values = code[oct - 1].Split(';');
                }
                else
                {
                    values = new string[umax * vmax];
                    for (int i = 0; i < values.Length; i++)
                    {
                        values[i] = "0";
                    }
                }

                Vector[,] Magnitude = new Vector[umax, vmax];
                double Theta, Phi;
                int    idx = 0;

                for (int v = 0; v < vmax; v++)
                {
                    for (int u = 0; u < umax; u++)
                    {
                        if (double.IsInfinity(swl_values[oct - 1]) || double.IsNaN(swl_values[oct - 1]))
                        {
                            Magnitude[u, v] = new Vector();
                        }
                        else
                        {
                            Theta           = u * System.Math.PI / (umax - 1);
                            Phi             = 2 * v * System.Math.PI / (vmax) + System.Math.PI / 2;
                            Magnitude[u, v] = new Vector(Math.Sin(Theta) * Math.Cos(Phi), Math.Cos(Theta), Math.Sin(Theta) * Math.Sin(Phi));
                            Magnitude[u, v].Normalize();
                            double swlmag = (double.Parse(values[idx]) + 60);
                            if (swlmag < 0)
                            {
                                swlmag = 0;
                            }
                            Magnitude[u, v] *= swlmag;
                        }
                        idx++;
                    }
                }

                //Create a mesh of the points...
                List <Hare.Geometry.Point[]> list = new List <Hare.Geometry.Point[]>();
                double Minx = double.MaxValue, Miny = double.MaxValue, Minz = double.MaxValue, Maxx = double.MinValue, Maxy = double.MinValue, Maxz = double.MinValue;

                for (int u = 0; u < umax - 1; u++)
                {
                    for (int v = 0; v < vmax; v++)
                    {
                        Hare.Geometry.Point[] Poly = new Hare.Geometry.Point[4];
                        Poly[0] = Magnitude[u, v];
                        Poly[1] = Magnitude[u, (v + 1) % vmax];
                        Poly[2] = Magnitude[u + 1, (v + 1) % vmax];
                        Poly[3] = Magnitude[u + 1, v];
                        list.Add(Poly);

                        foreach (Hare.Geometry.Point p in Poly)
                        {
                            if (p.x < Minx)
                            {
                                Minx = p.x;
                            }
                            if (p.y < Miny)
                            {
                                Miny = p.y;
                            }
                            if (p.z < Minz)
                            {
                                Minz = p.z;
                            }
                            if (p.x > Maxx)
                            {
                                Maxx = p.x;
                            }
                            if (p.y > Maxy)
                            {
                                Maxy = p.y;
                            }
                            if (p.z > Maxz)
                            {
                                Maxz = p.z;
                            }
                        }
                    }
                }

                m_HareMesh[oct - 1] = new Topology(new Hare.Geometry.Point(Minx, Miny, Minz), new Hare.Geometry.Point(Maxx, Maxy, Maxz));
                foreach (Hare.Geometry.Point[] Poly in list)
                {
                    m_HareMesh[oct - 1].Add_Polygon(Poly);
                }
                if (oct == 4)
                {
                    m_DisplayMesh = new Topology(new Hare.Geometry.Point(Minx, Miny, Minz), new Hare.Geometry.Point(Maxx, Maxy, Maxz));
                    foreach (Hare.Geometry.Point[] Poly in list)
                    {
                        m_DisplayMesh.Add_Polygon(Poly);
                    }
                }
            }
            Update_Position(Center);
        }
예제 #33
0
        /// <summary>
        /// This function calculates the actual path of the specular reflection.
        /// </summary>
        /// <param name="Images">The list of images.</param>
        /// <param name="Sequence">The list of surface indices for reflection.</param>
        /// <param name="Threadid">The id of the calling thread.</param>
        private void ProcessImages(Hare.Geometry.Point[] Images, int[] Sequence, int rec_id, int Threadid)
        {
            double[] Trans_Mod = new double[8];
            int[] Seq_Polys = new int[Sequence.Length];
            for (int t_oct = 0; t_oct < 8; t_oct++) Trans_Mod[t_oct] = 1;
            Hare.Geometry.Point[] PathVertices = new Hare.Geometry.Point[Sequence.Length + 2];
            PathVertices[0] = Src.H_Origin();
            PathVertices[PathVertices.Length - 1] = Rec[rec_id];

            //Find all Path Legs from Receiver to Source
            for (int q = Sequence.Length; q > 0; q--) if (!OcclusionIntersect(PathVertices[q + 1], Images[q - 1], Sequence[q - 1], ref Trans_Mod, ref PathVertices[q], ref Seq_Polys[q - 1], Threadid)) return;

            //Final Occlusion Check:
            if (FinalOcclusion(PathVertices[0], PathVertices[1], Sequence[0], ref Trans_Mod, Threadid)) return;
            Specular_Path SP = new Specular_Path(PathVertices, Sequence, Seq_Polys, Room, Src, Speed_of_Sound, Trans_Mod, ref Direct_Time[rec_id], Threadid, Rnd[Threadid].Next());
            ThreadPaths[rec_id, Threadid].Add(SP);
        }
예제 #34
0
        /// <summary>
        /// This function calculates the actual path of the specular reflection.
        /// </summary>
        /// <param name="Images">The list of images.</param>
        /// <param name="Sequence">The list of surface indices for reflection.</param>
        /// <param name="Threadid">The id of the calling thread.</param>
        private void ProcessImages(Hare.Geometry.Point[][] Images, int[] Sequence, int Threadid)
        {
            for (int rec_id = 0; rec_id < Rec.Length; rec_id++)
            {
                double c_sound =  Room.Sound_speed(Rec[rec_id]);

                double[][] Trans_Mod = new double[Images.Length][];
                int[] Seq_Polys = new int[Sequence.Length];
                List<Hare.Geometry.Point[]> PathVertices = new List<Hare.Geometry.Point[]>();
                Hare.Geometry.Point S = Src.H_Origin();
                Hare.Geometry.Point E = Rec[rec_id];
                double df = SampleRate * .5 / 4096;

                //Find all Path Legs from Receiver to Source
                
                for (int r = 0; r < Images.Length; r++)
                {
                    Trans_Mod[r] = new double[8];
                    for (int t_oct = 0; t_oct < 8; t_oct++) Trans_Mod[r][t_oct] = 1;
                
                    Hare.Geometry.Point[] path = new Hare.Geometry.Point[Sequence.Length + 2];
                    path[0] = S;
                    path[path.Length - 1] = E;

                    for (int q = Sequence.Length - 1; q >= 0; q--)
                    {
                        if (Sequence[q] > Room.PlaneCount - 1)
                        {
                            //It's an edge!
                            int EdgeID = Sequence[q] - Room.PlaneCount;
                            //for (int i = 1; i < Room.Edge_Nodes[EdgeID].EdgeSources.Count; i++)
                            if (!OcclusionIntersectED(path[q + 2], Images[r][q], Sequence[q], ref Trans_Mod[r], ref path[q + 1], Threadid))// ref Trans_Mod, , ref Seq_Polys[q], 
                            {
                                path = null;
                                break;
                            }
                        }
                        else
                        {
                            if (!OcclusionIntersect(path[q + 2], Images[r][q], Sequence[q], ref Trans_Mod[r], ref path[q + 1], ref Seq_Polys[q], Threadid))
                            {
                                path = null;
                                break;
                            }
                        }
                    }
                    PathVertices.Add(path);
                }

                //Check that any path was unoccluded... if so, then record this entry. If not, move on...
                if (PathVertices.Count(item => item != null) == 0) continue; //goto Next;
                
                //Final Occlusion Check:
                for (int r = 0; r < PathVertices.Count; r++)
                {
                    if (PathVertices[r] == null) continue;
                    if (Sequence[0] < Room.PlaneCount)
                    {
                        if (FinalOcclusion(PathVertices[r][0], PathVertices[r][1], Sequence[0], ref Trans_Mod[r], Threadid))
                            PathVertices[r] = null;
                    }
                    else
                    {
                        int edge_id = Sequence[0] - Room.PlaneCount;
                        if (FinalOcclusion(PathVertices[r][0], PathVertices[r][1], 0.00001, Room.Edge_Nodes[edge_id].ParentBreps[0], Room.Edge_Nodes[edge_id].ParentBreps[1], ref Trans_Mod[r], Threadid))
                            PathVertices[r] = null;
                    }
                }

                //Check again for null(occluded) paths...
                if (PathVertices.Count(item => item != null) == 0) continue; //goto Next;

                ///Process all paths for pulse entry...
                if (PathVertices.Count == 0) continue;//goto Next;

                if (PathVertices.Count == 1)
                {
                    ThreadPaths[rec_id, Threadid].Add(new Specular_Path(PathVertices[0], Sequence, Seq_Polys, Room, Src, Speed_of_Sound, Trans_Mod[0], ref Direct_Time[rec_id], Threadid, Rnd[Threadid].Next()));
                    continue;
                }

                //Process Compound Path before storing it.
                double[] H = new double[0];
                Environment.Material[] M = new Environment.Material[Sequence.Length];
                for (int i = 0; i < M.Length; i++) M[i] = (Sequence[i] < Room.PlaneCount) ? Room.Surface_Material(Sequence[i]) : null;

                //Arrange all information to build filtered response...
                List<List<double>> Times = new List<List<double>>();
                List<List<double>> Pr = new List<List<double>>();
                List<double> Time = new List<double>();
                List<double> Bs = new List<double>();
                List<double> X = new List<double>();
                List<double> Y = new List<double>();
                List<double> Z = new List<double>();
                List<List<double>> Xe = new List<List<double>>();
                List<List<double>> Ye = new List<List<double>>();
                List<List<double>> Ze = new List<List<double>>();
                List<double> X_ = new List<double>();
                List<double> Y_ = new List<double>();
                List<double> Z_ = new List<double>();
                List<List<double>> Xs = new List<List<double>>();
                List<List<double>> Ys = new List<List<double>>();
                List<List<double>> Zs = new List<List<double>>();

                double deltaS = 0;
                double dt = 1.0f / SampleRate;
                List<double[]> t_limits = new List<double[]>();
                    
                    for (int i = 0; i < PathVertices.Count; i++)
                    {
                        if (PathVertices[i] == null)
                        {
                            if (Bs.Count > 0)
                            {
                                t_limits.Add(new double[2] { Time.Min(), Time.Max() });
                                Pr.Add(Bs);
                                Bs = new List<double>();
                                Times.Add(Time);
                                Time = new List<double>();
                                Xe.Add(X);
                                X = new List<double>();
                                Ye.Add(Y);
                                Y = new List<double>();
                                Ze.Add(Z);
                                Z = new List<double>();
                                Xs.Add(X_);
                                X_ = new List<double>();
                                Ys.Add(Y_);
                                Y_ = new List<double>();
                                Zs.Add(Z_);
                                Z_ = new List<double>();
                            }
                            continue;
                        }
                        double l = 0;
                        double[] dm = null, dl = null;
                        double length1 = 0, length2 = 0;
                        double Pres = 1;
                        int s, c, e;
                        for (s = 0, c = 1, e = 2; e < PathVertices[i].Length; s++, c++, e++)
                        {
                            if (Sequence[s] < Room.PlaneCount)
                            {
                                length1 += (PathVertices[i][1] - PathVertices[i][c]).Length();
                                length2 = length1;
                                dl = new double[2] { (PathVertices[i][c] - PathVertices[i][e]).Length(), (PathVertices[i][c] - PathVertices[i][e]).Length() };
                            }
                            else if (Sequence[s] >= Room.PlaneCount)
                            {
                                double m = 0;
                                double B = Room.Edge_Nodes[Sequence[s] - Room.PlaneCount].EdgeSources[i].Flex_Solve(PathVertices[i][s], PathVertices[i][e], ref m, ref l, ref dm, ref dl);
                                Pres *= B;
                                length1 += dm[0];
                                length2 += dm[1];
                            }
                            else { throw new NotImplementedException("...well isn't that novel..."); }
                        }
                        length1 += dl[0];
                        length2 += dl[1];

                        double duration_s = SampleRate * Math.Abs(length2 - length1) / c_sound;

                        Vector DIR;
                        DIR = PathVertices[i][c-1] - PathVertices[i][e-1];
                        DIR.Normalize();
                        Pres /= duration_s;
                        double Tn = 0.5 * (length1 + length2) / c_sound;
                        if (Time.Count > 2)
                        {
                            double dtnew = Time[Time.Count - 2] - Tn;
                            if (deltaS != 0 && (dtnew > 0) != (deltaS > 0))
                            {
                                //Break it...
                                t_limits.Add(new double[2] { Time.Min(), Time.Max() });
                                if (Bs.Last() < Pres) { t_limits[t_limits.Count - 1][0] += dt; }
                                else { t_limits[t_limits.Count - 1][1] -= dt; }
                                Pr.Add(Bs);
                                Bs = new List<double>();
                                Times.Add(Time);
                                Time = new List<double>();
                                Xe.Add(X);
                                X = new List<double>();
                                Ye.Add(Y);
                                Y = new List<double>();
                                Ze.Add(Z);
                                Z = new List<double>();
                                Xs.Add(X_);
                                X_ = new List<double>();
                                Ys.Add(Y_);
                                Y_ = new List<double>();
                                Zs.Add(Z_);
                                Z_ = new List<double>();
                                ///Ensure Continuity...
                                //Time.Add(Times[Times.Count - 1].Last());
                                //Bs.Add(Pr[Pr.Count - 1].Last());
                                //X.Add(Xe[Xe.Count - 1].Last());
                                //Y.Add(Ye[Ye.Count - 1].Last());
                                //Z.Add(Ze[Ze.Count - 1].Last());
                                //X_.Add(Xs[Xs.Count - 1].Last());
                                //Y_.Add(Ys[Ys.Count - 1].Last());
                                //Z_.Add(Zs[Zs.Count - 1].Last());
                                //dtnew *= -1;
                            }
                            deltaS = dtnew;
                        }
                        Vector DIRs = PathVertices[i][1] - PathVertices[i][0];
                        DIRs.Normalize();
                        X_.Add(DIRs.x);
                        Y_.Add(DIRs.y);
                        Z_.Add(DIRs.z);

                        Bs.Add(Pres);
                        Time.Add(Tn);
                        X.Add(DIR.x);
                        Y.Add(DIR.y);
                        Z.Add(DIR.z);
                    }

                    if (Bs.Count > 0)
                    {
                        t_limits.Add(new double[2] { Time.Min(), Time.Max() });
                        Pr.Add(Bs);
                        Times.Add(Time);
                        Xe.Add(X);
                        Ye.Add(Y);
                        Ze.Add(Z);
                        Xs.Add(X_);
                        Ys.Add(Y_);
                        Zs.Add(Z_);
                    }
                    MathNet.Numerics.Interpolation.CubicSpline[] Pr_Spline = new MathNet.Numerics.Interpolation.CubicSpline[Pr.Count];
                    MathNet.Numerics.Interpolation.CubicSpline[] X_Spline = new MathNet.Numerics.Interpolation.CubicSpline[Xe.Count];
                    MathNet.Numerics.Interpolation.CubicSpline[] Y_Spline = new MathNet.Numerics.Interpolation.CubicSpline[Ye.Count];
                    MathNet.Numerics.Interpolation.CubicSpline[] Z_Spline = new MathNet.Numerics.Interpolation.CubicSpline[Ze.Count];
                    MathNet.Numerics.Interpolation.CubicSpline[] Xs_Spline = new MathNet.Numerics.Interpolation.CubicSpline[Xs.Count];
                    MathNet.Numerics.Interpolation.CubicSpline[] Ys_Spline = new MathNet.Numerics.Interpolation.CubicSpline[Ys.Count];
                    MathNet.Numerics.Interpolation.CubicSpline[] Zs_Spline = new MathNet.Numerics.Interpolation.CubicSpline[Zs.Count];
                    double min = double.PositiveInfinity;
                    for (int i = 0; i < Times.Count; i++)
                    {
                        Pr_Spline[i] = MathNet.Numerics.Interpolation.CubicSpline.InterpolateAkima(Times[i], Pr[i]);
                        X_Spline[i] = MathNet.Numerics.Interpolation.CubicSpline.InterpolateAkima(Times[i], Xe[i]);
                        Y_Spline[i] = MathNet.Numerics.Interpolation.CubicSpline.InterpolateAkima(Times[i], Ye[i]);
                        Z_Spline[i] = MathNet.Numerics.Interpolation.CubicSpline.InterpolateAkima(Times[i], Ze[i]);
                        Xs_Spline[i] = MathNet.Numerics.Interpolation.CubicSpline.InterpolateAkima(Times[i], Xs[i]);
                        Ys_Spline[i] = MathNet.Numerics.Interpolation.CubicSpline.InterpolateAkima(Times[i], Ys[i]);
                        Zs_Spline[i] = MathNet.Numerics.Interpolation.CubicSpline.InterpolateAkima(Times[i], Zs[i]);

                        min = Math.Min(min, t_limits[i][1]);
                    }

                    //TODO: Find a way to include absorption/transmission effects... which will not affect the entire multipath reflection...
                    Dictionary<int, double> H_d = new Dictionary<int, double>();
                    Dictionary<int, double>[] H_directional = new Dictionary<int, double>[6];
                    for (int i = 0; i < 6; i++) H_directional[i] = new Dictionary<int, double>(); 

                    for (int i = 0; i < t_limits.Count; i++)
                    {
                        for (double t = t_limits[i][0]; t < t_limits[i][1]; t += dt)
                        {
                            Vector dir = new Vector(Xs_Spline[i].Interpolate(t), Ys_Spline[i].Interpolate(t), Zs_Spline[i].Interpolate(t));

                            ////Compose Impulse Response...
                            //double T_current = (lengths[p_id] + dl[0]) / Room.Sound_speed(new Hare.Geometry.Point(0, 0, 0));
                            //double T_duration = (length2 + dl[1]) / Room.Sound_speed(new Hare.Geometry.Point(0, 0, 0)) - T_current;

                            ///Apply TransMod to TF...
                            ///Each sample will have it's own unique air attenuation and occlusion conditions, which means that it needs to be treated individually for input signal (for air attenuation and absorption).
                            //double[] TF = Audio.Pach_SP.Magnitude_Filter(new double[8] { Math.Sqrt(Trans_Mod[p_id][0] * SW[0]), Math.Sqrt(Trans_Mod[p_id][1] * SW[1]), Math.Sqrt(Trans_Mod[p_id][2] * SW[2]), Math.Sqrt(Trans_Mod[p_id][3] * SW[3]), Math.Sqrt(Trans_Mod[p_id][4] * SW[4]), Math.Sqrt(Trans_Mod[p_id][5] * SW[5]), Math.Sqrt(Trans_Mod[p_id][6] * SW[6]), Math.Sqrt(Trans_Mod[p_id][7] * SW[7]) }, 44100, 4096, Threadid);
                            double[] SW = Src.DirPower(Threadid, this.Rnd[Threadid].Next(), dir);
                            foreach (Environment.Material m in M)
                            {
                                if (m is Environment.Basic_Material) for (int oct = 0; oct < 8; oct++)
                                    {
                                        SW[oct] *= 1 - m.Coefficient_A_Broad(oct);
                                        //SW[oct] *= Trans_Mod[j][oct];
                                    }
                            }

                            System.Numerics.Complex[] TF = Audio.Pach_SP.Filter.Spectrum(new double[8] { Math.Sqrt(SW[0]), Math.Sqrt(SW[1]), Math.Sqrt(SW[2]), Math.Sqrt(SW[3]), Math.Sqrt(SW[4]), Math.Sqrt(SW[5]), Math.Sqrt(SW[6]), Math.Sqrt(SW[7]) }, 44100, 4096, Threadid);
                        //double[] ms = Audio.Pach_SP.Magnitude_Spectrum(new double[8] { Math.Sqrt(SW[0]), Math.Sqrt(SW[1]), Math.Sqrt(SW[2]), Math.Sqrt(SW[3]), Math.Sqrt(SW[4]), Math.Sqrt(SW[5]), Math.Sqrt(SW[6]), Math.Sqrt(SW[7]) }, 44100, 4096, Threadid);
                        //double[] ms = Audio.Pach_SP.Magnitude_Spectrum(new double[8] { Math.Sqrt(SW[0]), Math.Sqrt(SW[1]), Math.Sqrt(SW[2]), Math.Sqrt(SW[3]), Math.Sqrt(SW[4]), Math.Sqrt(SW[5]), Math.Sqrt(SW[6]), Math.Sqrt(SW[7]) }, 88200, 8096, Threadid);

                        //System.Numerics.Complex[] TF = new System.Numerics.Complex[ms.Length];
                        //    for (int j = 0; j < TF.Length; j++) TF[j] = ms[j];
                                //Array.Resize(ref TF, TF.Length / 2);

                            ///Apply Air attenuation to TF...
                            double[] atten = new double[0];
                            double[] freq = new double[0];
                            Room.AttenuationFilter(4096, 44100, t * c_sound, ref freq, ref atten, Rec[rec_id]);//sig is the magnitude response of the air attenuation filter...
                            //Room.AttenuationFilter(4096, 88200, t * c_sound, ref freq, ref atten, Rec[rec_id]);//sig is the magnitude response of the air attenuation filter...
                            for (int j = 0; j < TF.Length; j++) TF[j] *= atten[j];
                            
                            for (int j = 0; j < M.Length; j++)
                            {
                                if (!(M[j] is Environment.Basic_Material))
                                {
                                    if (Sequence[j] < Room.PlaneCount)
                                    {
                                        System.Numerics.Complex[] spec = M[j].Reflection_Spectrum(44100, 4096 / 2, Room.Normal(Sequence[j]), PathVertices[i][j] - PathVertices[i][j - 1], Threadid);
                                        for (int k = 0; k < TF.Length; k++) TF[k] *= spec[k];
                                    }
                                }
                            }

                            //Audio.Pach_SP.Filter.Response(TF, SampleRate, Threadid);

                            double[] pulse = Audio.Pach_SP.IFFT_Real4096(Audio.Pach_SP.Mirror_Spectrum(TF), Threadid);
                            //double[] pulse = new double[prepulse.Length];
                            Audio.Pach_SP.Scale(ref pulse);
                            //for (int j = 0; j < prepulse.Length; j++)
                            //{
                            //    pulse[j] = prepulse[(j + prepulse.Length/2) % prepulse.Length];
                            //}
                            ////////////////////////////////////////////////////////
                            //Pachyderm_Acoustic.Audio.Pach_SP.resample(ref pulse);
                            ////////////////////////////////////////////////////////
                            //Audio.Pach_SP.Raised_Cosine_Window(ref pulse);
                            //Manual convolution of each distinct contribution of edge...
                            int index = (int)Math.Floor(t * SampleRate);
                            double omni_pr = Pr_Spline[i].Interpolate(t);
                            dir = new Vector(X_Spline[i].Interpolate(t), Y_Spline[i].Interpolate(t), Z_Spline[i].Interpolate(t));
                            double[] dir_c = new double[6];
                            if (dir.x > 0) dir_c[0] = dir.x; else dir_c[1] = -dir.x;
                            if (dir.y > 0) dir_c[2] = dir.y; else dir_c[3] = -dir.y;
                            if (dir.z > 0) dir_c[4] = dir.z; else dir_c[5] = -dir.z;

                            for (int j = 0; j < pulse.Length; j++)
                            {
                                //Todo: confirm that pulse comes in at right times...
                                int t_c = index + j;
                                double p_t = omni_pr * pulse[j] / 4096;

                                if (!H_d.Keys.Contains<int>(index + j))
                                {
                                    H_d.Add(t_c, p_t);
                                    H_directional[0].Add(t_c, p_t * dir_c[0]);
                                    H_directional[1].Add(t_c, p_t * dir_c[1]);
                                    H_directional[2].Add(t_c, p_t * dir_c[2]);
                                    H_directional[3].Add(t_c, p_t * dir_c[3]);
                                    H_directional[4].Add(t_c, p_t * dir_c[4]);
                                    H_directional[5].Add(t_c, p_t * dir_c[5]);
                                }
                                else
                                {
                                    H_d[t_c] += (float)(p_t);
                                    H_directional[0][t_c] += p_t * dir_c[0];
                                    H_directional[1][t_c] += p_t * dir_c[1];
                                    H_directional[2][t_c] += p_t * dir_c[2];
                                    H_directional[3][t_c] += p_t * dir_c[3];
                                    H_directional[4][t_c] += p_t * dir_c[4];
                                    H_directional[5][t_c] += p_t * dir_c[5];
                                }
                            }
                        }
                    }
                    int minsample = H_d.Keys.Min();
                    int maxsample = H_d.Keys.Max();
                    double T0 = (double)minsample / SampleRate;
                    H = new double[maxsample - minsample];
                    double[][] Hdir = new double[6][];
                    for(int j = 0; j < 6; j++) Hdir[j] = new double[maxsample - minsample];
                    for (int j = minsample; j < maxsample; j++) if (H_d.Keys.Contains<int>(j))
                        {
                            H[j - minsample] = H_d[j];
                            Hdir[0][j - minsample] = H_directional[0][j];
                            Hdir[1][j - minsample] = H_directional[1][j];
                            Hdir[2][j - minsample] = H_directional[2][j];
                            Hdir[3][j - minsample] = H_directional[3][j];
                            Hdir[4][j - minsample] = H_directional[4][j];
                            Hdir[5][j - minsample] = H_directional[5][j];
                        }
                    ///Enter the reflection
                    PathVertices.RemoveAll(item => item == null);
                    ThreadPaths[rec_id, Threadid].Add(new Compound_Path(PathVertices.ToArray(), Sequence, Src.Source_ID(), H, Hdir, T0, Speed_of_Sound, ref Direct_Time[rec_id], Threadid));
            }
        }
예제 #35
0
        /// <summary>
        /// Processes image source paths with input of only a sequence of indices.
        /// </summary>
        /// <param name="Sequence">The input sequence of surface indices.</param>
        /// <param name="Threadid">The id of the calling thread.</param>
        /// <param name="rec_id">The id of the receiver.</param>
        /// <returns>True if a valid path, false if not.</returns>
        private bool ProcessPath(int[] Sequence, int Threadid, int rec_id)
        {
            Hare.Geometry.Point RefPoint;
            Hare.Geometry.Point NextPoint = new Hare.Geometry.Point();
            Hare.Geometry.Point[] Images = new Hare.Geometry.Point[Sequence.Length];
            RefPoint = Src.H_Origin();
            int[] Seq_Polys = new int[Sequence.Length];
            double[] Trans_Mod = new double[8];
            for (int t_oct = 0; t_oct < 8; t_oct++) Trans_Mod[t_oct] = 1;

            //Find all Source Images
            for (int q = 0; q < Sequence.Length; q++)
            {
                //RefPM = Room.PlaneMembers[Sequence[q]];
                Images[q] = Room.Image(RefPoint, 0, Room.PlaneMembers[Sequence[q]][0]);
                RefPoint = Images[q];
            }

            ProcessImages(Images, Sequence, rec_id, Threadid);

            //Hare.Geometry.Point[] PathVertices = new Hare.Geometry.Point[Sequence.Length + 2];
            //PathVertices[0] = Src.H_Origin();
            //PathVertices[PathVertices.Length - 1] = Rec[rec_id];
            //RefPoint = Rec[rec_id];
            ////Find all Path Legs from End to Start
            //int Limit = Sequence.Length - 1;
            //for (int q = Limit; q >= 0; q--)
            //{
            //    if (!OcclusionIntersect(PathVertices[q + 2], Images[q], Sequence[q], ref Trans_Mod, ref RefPoint, ref Seq_Polys[q], Threadid)) 
            //        return false;
            //    PathVertices[q + 1] = RefPoint;
            //}

            ////Final Occlusion Check:
            //if (!FinalOcclusion(PathVertices[0], PathVertices[1], Sequence[0], ref Trans_Mod, ref RefPoint, Threadid)) 
            //    return false;
            //Specular_Path SP = new Specular_Path(PathVertices, Sequence, Seq_Polys, Oct_choice, Room, Src, Speed_of_Sound, Trans_Mod, ref Direct_Time[rec_id], Threadid, Rnd[Threadid].Next());

            //ThreadPaths[rec_id, Threadid].Add(SP);
            return true;
        }
            private void Fill_in(Source Src_Pt, int SampleRate_in, double Increment_in, Scene Sc, int RCT, double Cutoff_time, bool Time_1Pt, bool Z_displacementIn, bool DirectionalIn, bool RecOnVertex, bool Offset_Mesh)
            {
                _Sc = Sc;
                Src = Src_Pt.Origin();
                SrcType = Src_Pt.Type();
                CutOffTime = Cutoff_time;
                SampleRate = SampleRate_in;
                increment = Increment_in;
                Rec_Vertex = RecOnVertex;
                Mesh_Offset = Offset_Mesh;
                Z_Displacement = Z_displacementIn;
                Directional = DirectionalIn;
                Time1Pt = Time_1Pt;

                SampleCT = Time1Pt ? 1 : (int)Math.Floor(CutOffTime * SampleRate / 1000);
                Max = new Hare.Geometry.Point(Double.NegativeInfinity, Double.NegativeInfinity, Double.NegativeInfinity);
                Min = new Hare.Geometry.Point(Double.PositiveInfinity, Double.PositiveInfinity, Double.PositiveInfinity);
                Rec_List = Rec_Vertex ? new Map_Receiver[Map_Mesh.Vertices.Count] : new Map_Receiver[Map_Mesh.Faces.Count];
                lock (Map_Mesh)
                {
                    bool FN = Map_Mesh.FaceNormals.ComputeFaceNormals();
                }
            }
        /// <summary>
        /// Called by each thread from the begin method.
        /// </summary>
        /// <param name="i">the object is type "Calc_Params" which holds all the necessary information to run a portion of the simulation.</param>
        public void Calculate(object i)
        {
            Calc_Params Params = (Calc_Params)i;
            Random      RND    = new Random(Params.RandomSeed);

            ST = DateTime.Now;
            Hare.Geometry.Point Origin = Source.H_Origin();
            ///'''''''''''''Renewable Variables''''''''''''''''''
            double SumLength;
            double u = 0;
            double v = 0;

            Hare.Geometry.Point Point = new Hare.Geometry.Point();
            int ChosenIndex           = 0;
            List <Hare.Geometry.Point> Start;
            int        Reflections;
            List <int> Sequence = new List <int>();

            ///''''''''''''''''''''''''''''''''''''''''''''''''''

            for (Current_Ray[Params.ThreadID] = 0; Current_Ray[Params.ThreadID] < Params.EndIndex - Params.StartIndex; Current_Ray[Params.ThreadID]++)
            {
                BroadRay R = Source.Directions(Current_Ray[Params.ThreadID] + Params.StartIndex, Params.ThreadID, ref RND);
                SumLength   = 0;
                Reflections = 0;
                Sequence.Clear();
                List <int> code = new List <int> {
                    0
                };
                List <double> leg = new List <double> {
                    0
                };
                do
                {
                    ///Only useable with homogeneous media///
                    SumLength += leg[0];
                    R.Ray_ID   = RND.Next();
                    if (Room.shoot(R, out u, out v, out ChosenIndex, out Start, out leg, out code))
                    {
                        if (!Room.IsPlanar(ChosenIndex))
                        {
                            break;
                        }
                        Reflections++;
                        ReflectRay(ref R, ref u, ref v, ref ChosenIndex);
                        if (Reflections > ImageOrder + 1)
                        {
                            bool[] B = Receiver.SimpleCheck(R, Start[0], SumLength);
                            for (int q = 0; q < B.Length; q++)
                            {
                                if (B[q])
                                {
                                    Detections[q, Params.ThreadID].Add(Sequence.ToArray());
                                }
                            }
                        }
                    }
                    else
                    {
                        //Rhino.RhinoDoc.ActiveDoc.Objects.AddCurve(new LineCurve(Pachyderm_Acoustic.Utilities.PachTools.HPttoRPt(R.origin), Pachyderm_Acoustic.Utilities.PachTools.HPttoRPt(R.origin + R.direction) * 5));
                        break;
                    }
                    Sequence.Add(Room.PlaneID(ChosenIndex));
                    R.origin = Start[0];
                }while (SumLength < CutoffLength);
            }
        }
        public Balloon(string[] ballooncodes, Hare.Geometry.Point Center) //, double[] SWL
        {
            string[][][] balloons = new string[8][][];
            Code = ballooncodes;

            int minstable = 8;

            for (int oct = 0; oct < 8; oct++)
            {
                if (ballooncodes[oct] == null)
                {
                    continue;
                }
                minstable = Math.Min(minstable, oct);
                string[] lines = ballooncodes[oct].Split(new char[1] {
                    ';'
                }, StringSplitOptions.RemoveEmptyEntries);
                balloons[oct] = new string[lines.Length][];
                for (int i = 0; i < lines.Length; i++)
                {
                    balloons[oct][i] = lines[i].Split(new char[1] {
                        ' '
                    }, StringSplitOptions.RemoveEmptyEntries);
                }
            }

            int umax, vmax;

            if (balloons[minstable][0].Length == 19) //[36].Count == 36 || balloons[4].Count == 19 || balloons[4].Count == 10)
            {
                Type = 0;
                umax = 19;
                vmax = 36;
            }
            else if (balloons[minstable][0].Length == 37)//[72].Count == 72 || balloons[4].Count == 37 || balloons[4].Count == 19)
            {
                Type = 1;
                umax = 37;
                vmax = 72;
            }
            else
            {
                throw new Exception("Balloon Resolution - the number of samples in the balloon is non-standard. This is not supported in Pachyderm at this time...");
            }

            for (int oct = 0; oct < 8; oct++)
            {
                if (balloons[oct] == null)
                {
                    balloons[oct] = new string[vmax][];
                    for (int v = 0; v < vmax; v++)
                    {
                        balloons[oct][v] = new string[umax];
                        for (int u = 0; u < umax; u++)
                        {
                            balloons[oct][v][u] = "40";
                        }
                    }
                }
            }

            m_HareMesh = new Topology[8];
            for (int oct = 0; oct < 8; oct++)
            {
                Vector[,] Magnitude = new Vector[umax, vmax];
                double[,] mag       = new double[umax, vmax];
                double Theta, Phi;
                //int idx = 0;

                for (int v = 0; v < balloons[oct].Length; v++)
                {
                    for (int u = 0; u < balloons[oct][v].Length; u++)
                    {
                        Theta           = u * System.Math.PI / (umax - 1);
                        Phi             = 2 * v * System.Math.PI / (vmax) + System.Math.PI / 2;
                        Magnitude[u, v] = new Vector(Math.Sin(Theta) * Math.Cos(Phi), Math.Cos(Theta), Math.Sin(Theta) * Math.Sin(Phi));
                        Magnitude[u, v].Normalize();

                        double swlmag = (-double.Parse(balloons[oct][v][u]) + 60);
                        if (swlmag < 0)
                        {
                            swlmag = 0;
                        }
                        Magnitude[u, v] *= swlmag;
                        mag[u, v]        = swlmag;

                        if (balloons[oct].Length == vmax / 4 + 1)    //Quarter data
                        {
                            int v_2 = vmax / 2 + 1;
                            Magnitude[(vmax - u) % vmax, v] = Magnitude[u, v];
                            Magnitude[v_2 - u, v]           = Magnitude[u, v];
                            Magnitude[v_2 + u, v]           = Magnitude[u, v];
                            mag[(vmax - u) % 36, v]         = mag[u, v];
                            mag[v_2 - u, v] = mag[u, v];
                            mag[v_2 + u, v] = mag[u, v];
                        }
                        if (balloons[oct].Length == vmax / 2 + 1)    //Half data
                        {
                            Magnitude[(vmax - u) % vmax, v] = Magnitude[u, v];
                            mag[(vmax - u) % vmax, v]       = mag[u, v];
                        }
                    }
                }

                if (Code[oct] == null)
                {
                    Code[oct] = "";
                    for (int v = 0; v < balloons[oct].Length; v++)
                    {
                        for (int u = 0; u < balloons[oct][v].Length; u++)
                        {
                            Code[oct] += "0.0 ";
                        }
                        Code[oct] += ';';
                    }
                }
                //Create a mesh of the points...
                List <Hare.Geometry.Point[]> list = new List <Hare.Geometry.Point[]>();
                double Minx = double.MaxValue, Miny = double.MaxValue, Minz = double.MaxValue, Maxx = double.MinValue, Maxy = double.MinValue, Maxz = double.MinValue;

                for (int u = 0; u < umax - 1; u++)
                {
                    for (int v = 0; v < vmax; v++)
                    {
                        Hare.Geometry.Point[] Poly = new Hare.Geometry.Point[4];
                        Poly[0] = new Hare.Geometry.Point(Magnitude[u, v].x, Magnitude[u, v].y, Magnitude[u, v].z);
                        Poly[1] = new Hare.Geometry.Point(Magnitude[u, (v + 1) % vmax].x, Magnitude[u, (v + 1) % vmax].y, Magnitude[u, (v + 1) % vmax].z);
                        Poly[2] = new Hare.Geometry.Point(Magnitude[u + 1, (v + 1) % vmax].x, Magnitude[u + 1, (v + 1) % vmax].y, Magnitude[u + 1, (v + 1) % vmax].z);
                        Poly[3] = new Hare.Geometry.Point(Magnitude[u + 1, v].x, Magnitude[u + 1, v].y, Magnitude[u + 1, v].z);
                        list.Add(Poly);

                        foreach (Hare.Geometry.Point p in Poly)
                        {
                            if (p.x < Minx)
                            {
                                Minx = p.x;
                            }
                            if (p.y < Miny)
                            {
                                Miny = p.y;
                            }
                            if (p.z < Minz)
                            {
                                Minz = p.z;
                            }
                            if (p.x > Maxx)
                            {
                                Maxx = p.x;
                            }
                            if (p.y > Maxy)
                            {
                                Maxy = p.y;
                            }
                            if (p.z > Maxz)
                            {
                                Maxz = p.z;
                            }
                        }
                    }
                }

                m_HareMesh[oct] = new Topology(new Hare.Geometry.Point(Minx, Miny, Minz), new Hare.Geometry.Point(Maxx, Maxy, Maxz));
                foreach (Hare.Geometry.Point[] Poly in list)
                {
                    m_HareMesh[oct].Add_Polygon(Poly);
                }
                if (oct == 4)
                {
                    m_DisplayMesh = new Topology(new Hare.Geometry.Point(Minx, Miny, Minz), new Hare.Geometry.Point(Maxx, Maxy, Maxz));
                    foreach (Hare.Geometry.Point[] Poly in list)
                    {
                        m_DisplayMesh.Add_Polygon(Poly);
                    }
                    for (int i = 0; i < m_DisplayMesh.Vertex_Count; i++)
                    {
                        m_DisplayMesh.Set_Vertex(i, m_DisplayMesh[i] / 90);
                    }
                }
            }
            Update_Position(Center);
        }
 public override bool shoot(Hare.Geometry.Ray R, out double u, out double v, out int Poly_ID, out Hare.Geometry.Point X_PT, out double t)
 {
     Hare.Geometry.X_Event X = new Hare.Geometry.X_Event();
     if (SP.Shoot(R, 0, out X))
     {
         Poly_ID = X.Poly_id;
         X_PT = X.X_Point;
         t = X.t;
         u = 0;
         v = 0;
         return true;
     }
     Poly_ID = 0;
     X_PT = new Hare.Geometry.Point();
     //Rhino.RhinoDoc.ActiveDoc.Objects.Add(new Rhino.Geometry.LineCurve(Utilities.PachTools.HPttoRPt(R.origin), Utilities.PachTools.HPttoRPt(R.origin + R.direction)));
     t = 0;
     u = 0;
     v = 0;
     return false;
 }
        /// <summary>
        /// Called by each thread from the begin method.
        /// </summary>
        /// <param name="i">the object is type "Calc_Params" which holds all the necessary information to run a portion of the simulation.</param>
        public void Calculate(object i)
        {
            Calc_Params Params = (Calc_Params)i;
            Random RND = new Random(Params.RandomSeed);
            ST = DateTime.Now;
            Hare.Geometry.Point Origin = Source.H_Origin();
            ///'''''''''''''Renewable Variables''''''''''''''''''
            double SumLength;
            double u = 0;
            double v = 0;
            Hare.Geometry.Point Point = new Hare.Geometry.Point();
            int ChosenIndex = 0;
            List<Hare.Geometry.Point> Start;
            int Reflections;
            List<int> Sequence = new List<int>();
            ///''''''''''''''''''''''''''''''''''''''''''''''''''

            for (Current_Ray[Params.ThreadID] = 0; Current_Ray[Params.ThreadID] < Params.EndIndex-Params.StartIndex; Current_Ray[Params.ThreadID]++)
            {
                BroadRay R = Source.Directions(Current_Ray[Params.ThreadID] + Params.StartIndex, Params.ThreadID, ref RND);
                SumLength = 0;
                Reflections = 0;
                Sequence.Clear();
                List<int> code = new List<int> { 0 };
                List<double> leg = new List<double> { 0 };
                do
                {
                    ///Only useable with homogeneous media///
                    SumLength += leg[0];
                    R.Ray_ID = RND.Next();
                    if (Room.shoot(R, out u, out v, out ChosenIndex, out Start, out leg, out code))
                    {
                        if (!Room.IsPlanar(ChosenIndex)) break;
                        Reflections ++;
                        ReflectRay(ref R, ref u, ref v, ref ChosenIndex);
                        if (Reflections > ImageOrder + 1)
                        {
                            bool[] B = Receiver.SimpleCheck(R, Start[0], SumLength);
                            for (int q = 0; q < B.Length; q++)
                            {
                                if (B[q]) Detections[q, Params.ThreadID].Add(Sequence.ToArray());
                            }
                        }
                    }
                    else
                    {
                        //Rhino.RhinoDoc.ActiveDoc.Objects.AddCurve(new LineCurve(Pachyderm_Acoustic.Utilities.PachTools.HPttoRPt(R.origin), Pachyderm_Acoustic.Utilities.PachTools.HPttoRPt(R.origin + R.direction) * 5));
                        break;
                    }
                    Sequence.Add(Room.PlaneID(ChosenIndex));
                    R.origin = Start[0];
                }
                while (SumLength < CutoffLength);
            }
        }
 public override Hare.Geometry.Point ClosestPt(Hare.Geometry.Point P, ref double Dist)
 {
     double Max = double.MaxValue;
     Hare.Geometry.Point RP = new Hare.Geometry.Point();
     Hare.Geometry.Point TP;
     for (int i = 0; i < Topo[0].Polygon_Count; i++)
     {
         TP = Topo[0].Closest_Point(P, i);
         Dist = TP.x * TP.x + TP.y * TP.y + TP.z * TP.z;
         if (Dist < Max)
         {
             RP = TP;
             Max = Dist;
         }
     }
     Dist = Math.Sqrt(Max);
     return RP;
 }
        public override Topology[] Balloons(double[] spl_values)
        {
            Topology[] Balloon = new Topology[8];

            int umax, vmax;

            switch (Type)
            {
            case 0:
                umax = 19;
                vmax = 36;
                break;

            case 1:
                umax = 37;
                vmax = 72;
                break;

            default:
                throw new Exception("Balloon type not valid for this version of CLF.");
            }

            for (int oct = 1; oct < 9; oct++)
            {
                string[] values;
                if (code[oct - 1] != "")
                {
                    values = code[oct - 1].Split(';');
                }
                else
                {
                    values = new string[umax * vmax];
                    for (int i = 0; i < values.Length; i++)
                    {
                        values[i] = "0";
                    }
                }

                Vector[,] Magnitude = new Vector[umax, vmax];
                double Theta, Phi;
                int    idx = 0;
                for (int v = 0; v < vmax; v++)
                {
                    for (int u = 0; u < umax; u++)
                    {
                        if (double.IsInfinity(spl_values[oct - 1]) || double.IsNaN(spl_values[oct - 1]))
                        {
                            Magnitude[u, v] = new Vector();
                        }
                        else
                        {
                            Theta           = u * System.Math.PI / (umax - 1);
                            Phi             = 2 * v * System.Math.PI / (vmax) + System.Math.PI / 2;
                            Magnitude[u, v] = new Vector(Math.Sin(Theta) * Math.Cos(Phi), Math.Cos(Theta), Math.Sin(Theta) * Math.Sin(Phi));
                            Magnitude[u, v].Normalize();
                            Magnitude[u, v] *= (double.Parse(values[idx]) + spl_values[oct - 1]);
                        }
                        idx++;
                    }
                }

                for (int u = 0; u < umax; u++)
                {
                    for (int v = 0; v < vmax; v++)
                    {
                        double roll  = CurrentAxi * Math.PI / 180;
                        double yaw   = CurrentAlt * Math.PI / 180;
                        double pitch = CurrentAzi * Math.PI / 180;

                        double x = Magnitude[u, v].x;
                        Magnitude[u, v].x = x * Math.Cos(roll) - Magnitude[u, v].z * Math.Sin(roll);
                        Magnitude[u, v].z = x * Math.Sin(roll) + Magnitude[u, v].z * Math.Cos(roll);
                        double y = Magnitude[u, v].y;
                        Magnitude[u, v].y = y * Math.Cos(yaw) - Magnitude[u, v].z * Math.Sin(yaw);
                        Magnitude[u, v].z = y * Math.Sin(yaw) + Magnitude[u, v].z * Math.Cos(yaw);
                        x = Magnitude[u, v].x;
                        Magnitude[u, v].x = x * Math.Cos(pitch) - Magnitude[u, v].y * Math.Sin(pitch);
                        Magnitude[u, v].y = x * Math.Sin(pitch) + Magnitude[u, v].y * Math.Cos(pitch);
                    }
                }

                List <Hare.Geometry.Point[]> list = new List <Hare.Geometry.Point[]>();
                //Create a mesh of the points...
                for (int u = 0; u < umax - 1; u++)
                {
                    for (int v = 0; v < vmax; v++)
                    {
                        Hare.Geometry.Point[] Poly = new Hare.Geometry.Point[3];
                        Poly[0] = Magnitude[u, v];
                        Poly[1] = Magnitude[u, (v + 1) % vmax];
                        Poly[2] = Magnitude[u + 1, v];
                        list.Add(Poly);
                        //Balloon[oct - 1].Add_Polygon(Poly);

                        Poly    = new Hare.Geometry.Point[3];
                        Poly[0] = Magnitude[u, (v + 1) % vmax];
                        Poly[1] = Magnitude[u + 1, (v + 1) % vmax];
                        Poly[2] = Magnitude[u + 1, v];
                        list.Add(Poly);
                        //Balloon[oct - 1].Add_Polygon(Poly);
                    }
                }

                double Minx = double.MaxValue, Miny = double.MaxValue, Minz = double.MaxValue, Maxx = double.MinValue, Maxy = double.MinValue, Maxz = double.MinValue;
                foreach (Hare.Geometry.Point[] p in list)
                {
                    foreach (Hare.Geometry.Point p0 in p)
                    {
                        if (p0.x < Minx)
                        {
                            Minx = p0.x;
                        }
                        if (p0.y < Miny)
                        {
                            Miny = p0.y;
                        }
                        if (p0.z < Minz)
                        {
                            Minz = p0.z;
                        }
                        if (p0.x > Maxx)
                        {
                            Maxx = p0.x;
                        }
                        if (p0.y > Maxy)
                        {
                            Maxy = p0.y;
                        }
                        if (p0.z > Maxz)
                        {
                            Maxz = p0.z;
                        }
                    }
                }

                Balloon[oct - 1] = new Topology(new Hare.Geometry.Point(Minx, Miny, Minz), new Hare.Geometry.Point(Maxx, Maxy, Maxz));
                foreach (Hare.Geometry.Point[] p in list)
                {
                    Balloon[oct - 1].Add_Polygon(p);
                }
            }
            Balloon[0].Finish_Topology(new List <Point>());
            Balloon[1].Finish_Topology(new List <Point>());
            Balloon[2].Finish_Topology(new List <Point>());
            Balloon[3].Finish_Topology(new List <Point>());
            Balloon[4].Finish_Topology(new List <Point>());
            Balloon[5].Finish_Topology(new List <Point>());
            Balloon[6].Finish_Topology(new List <Point>());
            Balloon[7].Finish_Topology(new List <Point>());
            return(Balloon);
        }
 public override Point3d ClosestPt(Point3d P, ref double Dist)
 {
     Hare.Geometry.Point PH = new Hare.Geometry.Point(P.X, P.Y, P.Z);
     PH = ClosestPt(PH, ref Dist);
     return new Point3d(PH.x, PH.y, PH.z);
 }
예제 #44
0
 /// <summary>
 /// Constructor which takes Hare Point input.
 /// </summary>
 /// <param name="Center"></param>
 /// <param name="SrcCenter"></param>
 /// <param name="room"></param>
 /// <param name="RCT"></param>
 /// <param name="C_Sound_in"></param>
 /// <param name="SampleRate_in"></param>
 /// <param name="COTime_in"></param>
 public Spherical_Receiver(Hare.Geometry.Point Center, Hare.Geometry.Point SrcCenter, Scene room, double C_Sound_in, int SampleRate_in, double COTime_in)
 {
     D_Length = Math.Sqrt(Center.x * SrcCenter.x + Center.y * SrcCenter.y * Center.z * SrcCenter.z);
     Radius = 1;
     Radius2 = Radius * Radius;
     CO_Time = COTime_in;
     SampleRate = SampleRate_in;
     H_Origin = Center;
     //Origin = new Point3d(Center.x, Center.y, Center.z);
     Sound_Speed = C_Sound_in;
     Atten = room.Attenuation(Center);
     SizeMod = 1 / Math.PI;
     Recs = new Directional_Histogram(SampleRate, CO_Time);
 }
            public override void EdgeFrame_Tangents(Hare.Geometry.Point Origin, Vector Normal, int[] PlaneIDs, ref List<double> dist2, List<Vector> Dir, List<int> EdgeIDs)
            {
                double d = Hare_math.Dot(Normal, Origin);
                //for (int i = 0; i < PlaneCount; i++)
                foreach(int i in EdgeIDs)
                {
                    Hare.Geometry.Point[] Pts = new Hare.Geometry.Point[2];
                    double d_min = double.MaxValue;
                    double d_max = double.MinValue;
                    foreach (int j in Topo[0].Plane_Members[i])
                    {
                        //Do the polygon/plane intersection for each member 'j' of i.
                        Hare.Geometry.Point[] vtx = Topo[0].Polygon_Vertices(j);
                        Hare.Geometry.Point[] temp = new Hare.Geometry.Point[1];
                        uint tmpcount = 0;

                        for (int k = 0, h = 1; k < vtx.Length; k++, h++)
                        {
                            Vector ab = vtx[h % vtx.Length] - vtx[k];
                            double t = (d - Hare_math.Dot(Normal, vtx[k])) / Hare_math.Dot(Normal, ab);

                            // If t in [0..1] compute and return intersection point
                            if (t >= 0.0f && t <= 1.0f)
                            {
                                temp[tmpcount] = vtx[k] + t * ab;
                                tmpcount++;
                            }
                            if (h == 0 && tmpcount == 0) break;
                            if (tmpcount > 1) break;
                        }
                        foreach (Hare.Geometry.Point p in temp)
                        {
                            Hare.Geometry.Point v = Origin - p;
                            double tmp = v.x * v.x + v.y * v.y + v.z * v.z;
                            if (tmp > d_max)
                            {
                                Pts[1] = p;
                                d_max = tmp;
                            }
                            if (tmp < d_min)
                            {
                                Pts[0] = p;
                                d_min = tmp;
                            }
                        }
                    }
                    dist2.Add(d_min);
                    EdgeIDs.Add(i);
                    Vector direction = (Pts[1] - Pts[0]);
                    direction.Normalize();
                    Dir.Add(direction);
                }
            }
 public override double Sound_speed(Hare.Geometry.Point pt)
 {
     return(this.Env_Prop.Sound_Speed(pt));
 }
            private void Construct(List<Rhino.DocObjects.RhinoObject> ObjectList)
            {
                BoundingBox Box = ObjectList[0].Geometry.GetBoundingBox(true);
                for (int i = 1; i < ObjectList.Count; i++) Box.Union(ObjectList[i].Geometry.GetBoundingBox(true));

                List<GeometryBase> BList = new List<GeometryBase>();

                Brep_ids = new List<int>();

                List<Material> Mat_Layer = new List<Material>();
                List<Scattering> Scat_Layer = new List<Scattering>();
                List<Material> Mat_Obj = new List<Material>();
                List<Scattering> Scat_Obj = new List<Scattering>();
                List<double[]> Trans_Layer = new List<double[]>();
                List<double[]> Trans_Obj = new List<double[]>();
                List<bool> Finite_Layers = new List<bool>();
                List<bool> Finite_Obj = new List<bool>();
                //Organize the geometry into Breps
                //Get materials for each layer:
                for (int l = 0; l < Rhino.RhinoDoc.ActiveDoc.Layers.Count; l++)
                {
                    Rhino.DocObjects.Layer Layer = Rhino.RhinoDoc.ActiveDoc.Layers[l];
                    string abstype = Layer.GetUserString("ABSType");
                    if (abstype == "Buildup")
                    {
                        Finite_Layers.Add(false);
                        string BU = Layer.GetUserString("BuildUp");
                        string[] BU_split = BU.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                        List<AbsorptionModels.ABS_Layer> Buildup = new List<AbsorptionModels.ABS_Layer>();
                        foreach (string swatch in BU_split) Buildup.Add(AbsorptionModels.ABS_Layer.LayerFromCode(swatch));
                        Mat_Layer.Add(new Environment.Smart_Material(Buildup, 44100, Env_Prop.Rho(0), Env_Prop.Sound_Speed(0), 2));

                        double[] Abs = new double[8], Scat = new double[8], Trans = new double[8];
                        Pachyderm_Acoustic.UI.PachydermAc_PlugIn.DecodeAcoustics(Layer.GetUserString("Acoustics"), ref Abs, ref Scat, ref Trans);
                        ///Other properties are still coefficient based...
                        Scat_Layer.Add(new Environment.Lambert_Scattering(Scat, SplitRatio));
                        Trans_Layer.Add(Trans);
                    }
                    else if (abstype == "Buildup_Finite")
                    {
                        Finite_Layers.Add(true);
                        string BU = Layer.GetUserString("BuildUp");
                        string[] BU_split = BU.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                        List<AbsorptionModels.ABS_Layer> Buildup = new List<AbsorptionModels.ABS_Layer>();
                        foreach (string swatch in BU_split) Buildup.Add(AbsorptionModels.ABS_Layer.LayerFromCode(swatch));
                        Environment.Smart_Material sm = new Environment.Smart_Material(Buildup, 44100, Env_Prop.Rho(0), Env_Prop.Sound_Speed(0), 2);
                        Mat_Layer.Add(sm);
                        double[] Abs = new double[8], Scat = new double[8], Trans = new double[8];
                        Pachyderm_Acoustic.UI.PachydermAc_PlugIn.DecodeAcoustics(Layer.GetUserString("Acoustics"), ref Abs, ref Scat, ref Trans);
                        ///Other properties are still coefficient based...
                        Scat_Layer.Add(new Environment.Lambert_Scattering(Scat, SplitRatio));
                        Trans_Layer.Add(Trans);
                    }
                    else
                    {
                        Finite_Layers.Add(false);
                        string spec = Layer.GetUserString("Acoustics");

                        if (spec == "")
                        {
                            ///Layer is not used. As long as there is no geometry for pachyderm on this layer without object set properties, this is ok.
                            Mat_Layer.Add(null);
                            Scat_Layer.Add(null);
                            Trans_Layer.Add(null);
                            continue;
                        }

                        double[] Abs = new double[8], Scat = new double[8], Trans = new double[8];
                        Pachyderm_Acoustic.UI.PachydermAc_PlugIn.DecodeAcoustics(spec, ref Abs, ref Scat, ref Trans);
                        Mat_Layer.Add(new Environment.Basic_Material(Abs, new double[8] { 0, 0, 0, 0, 0, 0, 0, 0 }));
                        Scat_Layer.Add(new Environment.Lambert_Scattering(Scat, SplitRatio));
                        Trans_Layer.Add(Trans);
                    }
                }

                for (int q = 0; q <= ObjectList.Count - 1; q++)
                {
                    List<Brep> B = new List<Brep>();
                    if (ObjectList[q].ObjectType == Rhino.DocObjects.ObjectType.Brep)
                    {
                        Rhino.DocObjects.BrepObject BObj = ((Rhino.DocObjects.BrepObject)ObjectList[q]);
                        B.Add(BObj.BrepGeometry.DuplicateBrep());
                        //string m = ObjectList[q].Geometry.GetUserString("Acoustics_User");
                        if (ObjectList[q].Geometry.GetUserString("Acoustics_User") == "yes")
                        {
                            double[] ABS = new double[8], SCAT = new double[8], TRANS = new double[8];
                            Pachyderm_Acoustic.UI.PachydermAc_PlugIn.DecodeAcoustics(ObjectList[q].Geometry.GetUserString("Acoustics"), ref ABS, ref SCAT, ref TRANS);
                            Mat_Obj.Add(new Basic_Material(ABS, new double[] { 0, 0, 0, 0, 0, 0, 0, 0 }));
                            Finite_Obj.Add(false);
                            Scat_Obj.Add(new Lambert_Scattering(SCAT, SplitRatio));
                            Trans_Obj.Add(TRANS);
                        }
                        else
                        {
                            //Rhino.DocObjects.Layer Layer = Rhino.RhinoDoc.ActiveDoc.Layers[ObjectList[q].Attributes.LayerIndex];
                            //AcousticsData.Add(Layer.GetUserString("Acoustics"));
                            Mat_Obj.Add(Mat_Layer[ObjectList[q].Attributes.LayerIndex]);
                            Scat_Obj.Add(Scat_Layer[ObjectList[q].Attributes.LayerIndex]);
                            Trans_Obj.Add(Trans_Layer[ObjectList[q].Attributes.LayerIndex]);
                            Finite_Obj.Add(Finite_Layers[ObjectList[q].Attributes.LayerIndex]);
                        }
                    }
                    else if (ObjectList[q].ObjectType == Rhino.DocObjects.ObjectType.Extrusion)
                    {
                        Rhino.Geometry.Brep BObj = ((Rhino.DocObjects.ExtrusionObject)ObjectList[q]).ExtrusionGeometry.ToBrep();
                        for (int i = 0; i < BObj.Faces.Count; i++)
                        {
                            if (ObjectList[q].Geometry.GetUserString("Acoustics_User") == "yes")
                            {
                                //AcousticsData.Add(ObjectList[q].Geometry.GetUserString("Acoustics"));
                                double[] ABS = new double[8], SCAT = new double[8], TRANS = new double[8];
                                Pachyderm_Acoustic.UI.PachydermAc_PlugIn.DecodeAcoustics(ObjectList[q].Geometry.GetUserString("Acoustics"), ref ABS, ref SCAT, ref TRANS);
                                Mat_Obj.Add(new Basic_Material(ABS, new double[] { 0, 0, 0, 0, 0, 0, 0, 0 }));
                                Scat_Obj.Add(new Lambert_Scattering(SCAT, SplitRatio));
                                Trans_Obj.Add(TRANS);
                                Finite_Obj.Add(false);
                            }
                            else
                            {
                                //Rhino.DocObjects.Layer Layer = Rhino.RhinoDoc.ActiveDoc.Layers[ObjectList[q].Attributes.LayerIndex];
                                //AcousticsData.Add(Layer.GetUserString("Acoustics"));
                                //Rhino.DocObjects.Layer Layer = Rhino.RhinoDoc.ActiveDoc.Layers[ObjectList[q].Attributes.LayerIndex];
                                //AcousticsData.Add(Layer.GetUserString("Acoustics"));
                                Mat_Obj.Add(Mat_Layer[ObjectList[q].Attributes.LayerIndex]);
                                Scat_Obj.Add(Scat_Layer[ObjectList[q].Attributes.LayerIndex]);
                                Trans_Obj.Add(Trans_Layer[ObjectList[q].Attributes.LayerIndex]);
                                Finite_Obj.Add(Finite_Layers[ObjectList[q].Attributes.LayerIndex]);
                            }

                            //B.Add(BObj.Faces[0].ToBrep());
                            //for (int i = 1; i < BObj.Faces.Count; i++)
                            //{
                            //    if (ObjectList[q].Geometry.GetUserString("Acoustics_User") == "yes")
                            //    {
                            //        AcousticsData.Add(ObjectList[q].Geometry.GetUserString("Acoustics"));
                            //    }
                            //    else
                            //    {
                            //        Rhino.DocObjects.Layer Layer = Rhino.RhinoDoc.ActiveDoc.Layers[ObjectList[q].Attributes.LayerIndex];
                            //        AcousticsData.Add(Layer.GetUserString("Acoustics"));
                            //    }
                            B.Add(BObj.Faces[i].ToBrep());
                        }
                    }
                    else
                    {
                        continue;
                    }
                    BList.AddRange(B);
                }

                ////////////////////////////////////////
                Topo = new Hare.Geometry.Topology[1];
                Topo[0] = new Topology(Utilities.PachTools.RPttoHPt(Box.Min), Utilities.PachTools.RPttoHPt(Box.Max));
                ////////////////////////////////////////
                for (int q = 0; q < BList.Count; q++)
                {
                    for (int r = 0; r < ((Brep)BList[q]).Faces.Count; r++)
                    {
                        BrepList.Add(((Brep)BList[q]).Faces[r].DuplicateFace(false));

                        //Material Abs = null ;
                        //Scattering Scat = null;

                        //double[] Transparency = new double[8];
                        double[] Transmission = new double[8];

                        //double[] Scat = new double[8];
                        //if (!string.IsNullOrEmpty(AcousticsData[q]))
                        //if (Mat_Obj[q] != null)
                        //{
                        //    //double[] Absorption = new double[8];
                        //    //double[] phase = new double[8];
                        //    //double[] Scattering = new double[8];
                        //    ////double[,] Scattering = new double[8, 3];
                        //    //double[] Reflection = new double[8];
                        //    //UI.PachydermAc_PlugIn.DecodeAcoustics(AcousticsData[q], ref Absorption, ref Scattering, ref Transparency);
                        //    Abs = Mat_Obj[q];
                        //    Scat = Scat_Obj[q];
                        //    Transmission = Trans_Obj[q];
                        //}
                        //else
                        if ((Mat_Obj[q] == null) || (Scat_Obj[q] == null) || (Trans_Obj[q] == null))
                        {
                            if (!Custom_Method)
                            {
                                Status = System.Windows.Forms.MessageBox.Show("A material is not specified correctly. Please assign absorption and scattering to all layers in the model.", "Materials Error", System.Windows.Forms.MessageBoxButtons.OK);
                                Complete = false;
                                return;
                            }
                            ///Materials do not need to be specified, as it will not be used for an acoustical simulation... (hopefully...)
                        }

                        //for (int i = 0; i < 8; i++)
                        //{
                        //    Reflection[i] = (1 - Absorption[i]);
                        //    Transmission[i] = Transparency[i];
                        //    Scattering[i, 1] = Scat[i];
                        //    double Mod = ((Scattering[i, 1] < (1 - Scattering[i, 1])) ? (Scattering[i, 1] * SplitRatio / 2) : ((1 - Scattering[i, 1]) * SplitRatio / 2));
                        //    Scattering[i, 0] = Scattering[i, 1] - Mod;
                        //    Scattering[i, 2] = Scattering[i, 1] + Mod;
                        //    phase[i] = 0;
                        //}

                        Mesh[] meshes;
                        MeshingParameters mp = new MeshingParameters();
                        if (Finite_Obj[q])
                        {
                            mp.MinimumEdgeLength = 0.1;
                            mp.SimplePlanes = false;
                        }
                        else
                        {
                            mp.MinimumEdgeLength = 0.1;
                            mp.SimplePlanes = true;
                        }

                        meshes = Rhino.Geometry.Mesh.CreateFromBrep((Brep)BrepList[BrepList.Count - 1], mp);
                        if (meshes == null) throw new Exception("Problem with meshes");

                        for (int t = 0; t < meshes.Length; t++)
                        {
                            if (meshes[t].Faces.Count < 1)
                            {
                                Status = System.Windows.Forms.MessageBox.Show("A surface in the model does not generate a rendermesh. This surface will not be represented in the simulation. It is recommended that you cancel this simulation and repair the affected surface. It can be located in shaded view by finding the surface which generates boundary and isoparm lines, but does not generate a fill. It can sometimes be repaired by running the command 'ShrinkTrimmedSurface'. If this does not work, it will have to be replaced by some means which would generate a proper surface.", "Surface without Rendermesh", System.Windows.Forms.MessageBoxButtons.OKCancel);
                                if (Status == System.Windows.Forms.DialogResult.Cancel)
                                {
                                    Complete = false;
                                    return;
                                }
                                continue;
                            }

                            for (int u = 0; u < meshes[t].Faces.Count; u++)
                            {
                                Hare.Geometry.Point[] P;
                                if (meshes[t].Faces[u].IsQuad)
                                {
                                    P = new Hare.Geometry.Point[4];
                                    Point3f FP = meshes[t].Vertices[meshes[t].Faces[u][0]];
                                    P[0] = new Hare.Geometry.Point(FP.X, FP.Y, FP.Z);
                                    FP = meshes[t].Vertices[meshes[t].Faces[u][1]];
                                    P[1] = new Hare.Geometry.Point(FP.X, FP.Y, FP.Z);
                                    FP = meshes[t].Vertices[meshes[t].Faces[u][2]];
                                    P[2] = new Hare.Geometry.Point(FP.X, FP.Y, FP.Z);
                                    FP = meshes[t].Vertices[meshes[t].Faces[u][3]];
                                    P[3] = new Hare.Geometry.Point(FP.X, FP.Y, FP.Z);
                                }
                                else
                                {
                                    P = new Hare.Geometry.Point[3];
                                    Point3f FP = meshes[t].Vertices[meshes[t].Faces[u][0]];
                                    P[0] = new Hare.Geometry.Point(FP.X, FP.Y, FP.Z);
                                    FP = meshes[t].Vertices[meshes[t].Faces[u][1]];
                                    P[1] = new Hare.Geometry.Point(FP.X, FP.Y, FP.Z);
                                    FP = meshes[t].Vertices[meshes[t].Faces[u][2]];
                                    P[2] = new Hare.Geometry.Point(FP.X, FP.Y, FP.Z);
                                }

                                if (Finite_Obj[q])
                                {
                                    if (!(Mat_Obj[q] is Smart_Material)) throw new Exception("Finite Material must have a Smart_Material...");
                                    Smart_Material mat = Mat_Obj[q] as Smart_Material;
                                    AbsorptionData.Add(new Finite_Material(mat, BrepList[q], meshes[t], u, Env_Prop));
                                }
                                else AbsorptionData.Add(Mat_Obj[q]);
                                ScatteringData.Add(Scat_Obj[q]);
                                TransmissionData.Add(Trans_Obj[q]);

                                bool Trans = false;
                                for (int t_oct = 0; t_oct < 8; t_oct++)
                                {
                                    if (Transmission[t_oct] > 0)
                                    {
                                        Trans = true;
                                        break;
                                    }
                                }
                                Transmissive.Add(Trans);
                                if (BrepList[BrepList.Count - 1].Faces[t].IsPlanar())
                                {
                                    Topo[0].Add_Polygon(P);
                                    Brep_ids.Add(BrepList.Count - 1);
                                }
                                else
                                {
                                    Topo[0].Add_Polygon(new Hare.Geometry.Point[3] { P[0], P[1], P[2] });
                                    Brep_ids.Add(BrepList.Count - 1);
                                    if (P.Length > 3)
                                    {
                                        //break this quad into two polygons in order to avoid warping...
                                        if (Finite_Obj[q])
                                        {
                                            if (!(Mat_Obj[q] is Smart_Material)) throw new Exception("Finite Material must have a Smart_Material...");
                                            Smart_Material mat = Mat_Obj[q] as Smart_Material;
                                            AbsorptionData.Add(new Finite_Material(mat, BrepList[q], meshes[t], u, Env_Prop));
                                        }
                                        else AbsorptionData.Add(Mat_Obj[q]);
                                        ScatteringData.Add(Scat_Obj[q]);
                                        TransmissionData.Add(Trans_Obj[q]);
                                        Transmissive.Add(Trans);
                                        Topo[0].Add_Polygon(new Hare.Geometry.Point[3] { P[0], P[2], P[3] });
                                        Brep_ids.Add(BrepList.Count - 1);
                                    }
                                }
                            }
                        }
                    }
                }

                //Set up a system to find random points on planes.//
                Plane_Area = new double[Topo[0].Plane_Members.Length];
                PolyPlaneFract = new double[Topo[0].Plane_Members.Length][];

                for (int q = 0; q < Topo[0].Plane_Members.Length; q++)
                {
                    foreach (int t in Topo[0].Plane_Members[q])
                    {
                        Plane_Area[q] += Topo[0].Polygon_Area(t);
                    }
                }

                //////////////////////////
                for (int i = 0; i < Topo[0].planeList.Count; i++)
                    for (int j = 0; j < Topo[0].Plane_Members[i].Count; j++)
                    {
                        Point3d pt = Utilities.PachTools.HPttoRPt(Topo[0].Polygon_Centroid(Topo[0].Plane_Members[i][j]));
                        string n = Topo[0].Polys[Topo[0].Plane_Members[i][j]].Plane_ID.ToString();
                    }
                //////////////////////////

                for (int q = 0; q < Topo[0].Plane_Members.Length; q++)
                {
                    PolyPlaneFract[q] = new double[Topo[0].Plane_Members[q].Count];
                    PolyPlaneFract[q][0] = Topo[0].Polygon_Area(Topo[0].Plane_Members[q][0]) / Plane_Area[q];
                    for (int t = 1; t < Topo[0].Plane_Members[q].Count; t++)
                    {
                        PolyPlaneFract[q][t] += PolyPlaneFract[q][t - 1] + Topo[0].Polygon_Area(Topo[0].Plane_Members[q][t]) / Plane_Area[q];
                    }
                }
                Valid = true;

                //Utilities.PachTools.Plot_Hare_Topology(Topo[0]);
            }
예제 #48
0
 /// <summary>
 /// Constructor which takes Rhino point input.
 /// </summary>
 /// <param name="Center"></param>
 /// <param name="SrcCenter"></param>
 /// <param name="room"></param>
 /// <param name="RCT"></param>
 /// <param name="C_Sound_in"></param>
 /// <param name="SampleRate_in"></param>
 /// <param name="COTime_in"></param>
 public Spherical_Receiver(Point3d Center, Point3d SrcCenter, double[] Attenuation, double C_Sound_in, double rho, int SampleRate_in, double COTime_in)
 {
     D_Length = Center.DistanceTo(SrcCenter);
     Radius = 1;
     Radius2 = Radius * Radius;
     SampleRate = SampleRate_in;
     CO_Time = COTime_in;
     H_Origin = new Hare.Geometry.Point(Center.X, Center.Y, Center.Z);
     Sound_Speed = C_Sound_in;
     Rho_C = C_Sound_in * rho;
     Atten = new double[8];
     for (int o = 0; o < 8; o++) Atten[o] = Attenuation[o] * 2;
     SizeMod = 1 / Math.PI;
     Recs = new Directional_Histogram(SampleRate, CO_Time);
 }
            public SurfaceSource(IEnumerable<Brep> Surfaces, List<String> CodeList, int el_m, int SrcID, Phase_Regime ph)
                :base(new double[8]{0, 0, 0, 0, 0, 0, 0, 0}, new Point3d(0,0,0), ph, SrcID)
            {
                samplespermeter = el_m;
                
                Srfs = Surfaces.ToList<Brep>();
                Samples = new Point3d[Srfs.Count][];
                
                MeshingParameters mp = new MeshingParameters();
                mp.MaximumEdgeLength = 1.0 / (double)samplespermeter;
                mp.MinimumEdgeLength = 1.0 / (double)samplespermeter;

                Sub_A = new double[Srfs.Count];
                SubDomains = new double[Srfs.Count][];
                T = new Topology[Srfs.Count];

                //for(int i = 0; i < Curves.Count; i++)
                System.Threading.Tasks.Parallel.For(0, Srfs.Count, ips =>
                {
                    int i = (int)ips;
                    
                    
                    //Divide each curve up in ~equal length segments.
                    Mesh[] m = Mesh.CreateFromBrep(Srfs[i],mp);
                    BoundingBox Box = m[0].GetBoundingBox(true);
                    for (int j = 1; j < m.Length; j++) Box.Union(m[j].GetBoundingBox(true));
                    T[i] = new Topology(Utilities.PachTools.RPttoHPt(Box.Min), Utilities.PachTools.RPttoHPt(Box.Max));
                    
                    List<Point3d> pts = new List<Point3d>();
                    SubDomains[i] = new double[m[i].Faces.Count + 1];
                    for (int j = 0; j < m[i].Faces.Count; j++)
                    {
                        double u,v;
                        ComponentIndex ci;
                        Point3d no;
                        Vector3d V;
                        Point3d A = m[i].Vertices[m[i].Faces[j].A];
                        Srfs[i].ClosestPoint(A, out no, out ci, out u, out v, 1, out V);
                        A += V;
                        Point3d B = m[i].Vertices[m[i].Faces[j].B];
                        Srfs[i].ClosestPoint(B, out no, out ci, out u, out v, 1, out V);
                        B += V;
                        Point3d C = m[i].Vertices[m[i].Faces[j].C];
                        Srfs[i].ClosestPoint(C, out no, out ci, out u, out v, 1, out V);
                        C += V;
                        Point3d D = m[i].Vertices[m[i].Faces[j].D];
                        Srfs[i].ClosestPoint(D, out no, out ci, out u, out v, 1, out V);
                        D += V;
                        
                        if (m[i].Faces[j].IsQuad)
                        {
                            Hare.Geometry.Point[] poly = new Hare.Geometry.Point[4];
                            poly[0] = new Hare.Geometry.Point(A.X, A.Y, A.Z);
                            poly[1] = new Hare.Geometry.Point(B.X, B.Y, B.Z);
                            poly[2] = new Hare.Geometry.Point(C.X, C.Y, C.Z);
                            poly[3] = new Hare.Geometry.Point(D.X, D.Y, D.Z);
                            T[i].Add_Polygon(poly);
                        }
                        else
                        {
                            Hare.Geometry.Point[] poly = new Hare.Geometry.Point[3];
                            poly[0] = new Hare.Geometry.Point(A.X, A.Y, A.Z);
                            poly[1] = new Hare.Geometry.Point(B.X, B.Y, B.Z);
                            poly[2] = new Hare.Geometry.Point(C.X, C.Y, C.Z);
                            T[i].Add_Polygon(poly);
                        }

                        pts.Add(m[i].Faces[j].IsQuad ? new Point3d(A.X + B.X + C.X + D.X, A.Y + B.Y + C.Y + D.Y, A.Z + B.Z + C.Z + D.Z) / 4 : new Point3d(A.X + B.X + C.X, A.Y + B.Y + C.Y, A.Z + B.Z + C.Z) / 3);

                        SubDomains[i][j + 1] = Sub_A[i] += T[i].Polygon_Area(j);
                    }
                    Samples[i] = pts.ToArray();
                });

                Domains = new double[Srfs.Count+1];
                DomainLevel = new double[Srfs.Count][];
                DomainPower = new double[Srfs.Count][];
                Total_A = 0;
                
                for (int i = 0; i < Srfs.Count; i++)
                {
                    for (int j = 0; j < SubDomains[i].Length; j++) SubDomains[i][j] /= Sub_A[i];
                    double A = Srfs[i].GetArea();
                    Domains[i + 1] = Total_A += A;
                    DomainLevel[i] = Utilities.PachTools.DecodeSourcePower(CodeList[i]);
                    DomainPower[i] = new double[8];
                    double PowerMod = A;
                    for (int oct = 0; oct < 8; oct++) DomainPower[i][oct] = 1E-12 * Math.Pow(10, .1 * DomainLevel[i][oct]) / PowerMod;
                }

                for (int i = 0; i < Domains.Length; i++)
                {
                    Domains[i] /= Total_A;
                }
            }
            private void triangle(Vector P0, Vector P1, Vector P2, int Ord, int max)
            {
                if (Ord < max)
                {
                    Vector P3 = (P0 + P1) / 2;
                    P3.Normalize();

                    Vector P4 = (P1 + P2) / 2;
                    P4.Normalize();

                    Vector P5 = (P2 + P0) / 2;
                    P5.Normalize();

                    this.triangle(P0, P3, P5, Ord + 1, max);
                    this.triangle(P1, P4, P3, Ord + 1, max);
                    this.triangle(P2, P5, P4, Ord + 1, max);
                    this.triangle(P3, P4, P5, Ord + 1, max);
                }
                else
                {
                    P[Fnum] = new Hare.Geometry.Point[3] { P0, P1, P2 };
                    Fnum++;
                }
            }
예제 #51
0
            public SurfaceSource(IEnumerable <Brep> Surfaces, List <String> CodeList, int el_m, int SrcID, Phase_Regime ph)
                : base(new double[8] {
                0, 0, 0, 0, 0, 0, 0, 0
            }, new Point3d(0, 0, 0), ph, SrcID)
            {
                samplespermeter = el_m;

                Srfs    = Surfaces.ToList <Brep>();
                Samples = new Point3d[Srfs.Count][];

                MeshingParameters mp = new MeshingParameters();

                mp.MaximumEdgeLength = 1.0 / (double)samplespermeter;
                mp.MinimumEdgeLength = 1.0 / (double)samplespermeter;

                Sub_A      = new double[Srfs.Count];
                SubDomains = new double[Srfs.Count][];
                T          = new Topology[Srfs.Count];

                //for(int i = 0; i < Curves.Count; i++)
                System.Threading.Tasks.Parallel.For(0, Srfs.Count, ips =>
                {
                    int i = (int)ips;


                    //Divide each curve up in ~equal length segments.
                    Mesh[] m        = Mesh.CreateFromBrep(Srfs[i], mp);
                    BoundingBox Box = m[0].GetBoundingBox(true);
                    for (int j = 1; j < m.Length; j++)
                    {
                        Box.Union(m[j].GetBoundingBox(true));
                    }
                    T[i] = new Topology(Utilities.PachTools.RPttoHPt(Box.Min), Utilities.PachTools.RPttoHPt(Box.Max));

                    List <Point3d> pts = new List <Point3d>();
                    SubDomains[i]      = new double[m[i].Faces.Count + 1];
                    for (int j = 0; j < m[i].Faces.Count; j++)
                    {
                        double u, v;
                        ComponentIndex ci;
                        Point3d no;
                        Vector3d V;
                        Point3d A = m[i].Vertices[m[i].Faces[j].A];
                        Srfs[i].ClosestPoint(A, out no, out ci, out u, out v, 1, out V);
                        A        += V;
                        Point3d B = m[i].Vertices[m[i].Faces[j].B];
                        Srfs[i].ClosestPoint(B, out no, out ci, out u, out v, 1, out V);
                        B        += V;
                        Point3d C = m[i].Vertices[m[i].Faces[j].C];
                        Srfs[i].ClosestPoint(C, out no, out ci, out u, out v, 1, out V);
                        C        += V;
                        Point3d D = m[i].Vertices[m[i].Faces[j].D];
                        Srfs[i].ClosestPoint(D, out no, out ci, out u, out v, 1, out V);
                        D += V;

                        if (m[i].Faces[j].IsQuad)
                        {
                            Hare.Geometry.Point[] poly = new Hare.Geometry.Point[4];
                            poly[0] = new Hare.Geometry.Point(A.X, A.Y, A.Z);
                            poly[1] = new Hare.Geometry.Point(B.X, B.Y, B.Z);
                            poly[2] = new Hare.Geometry.Point(C.X, C.Y, C.Z);
                            poly[3] = new Hare.Geometry.Point(D.X, D.Y, D.Z);
                            T[i].Add_Polygon(poly);
                        }
                        else
                        {
                            Hare.Geometry.Point[] poly = new Hare.Geometry.Point[3];
                            poly[0] = new Hare.Geometry.Point(A.X, A.Y, A.Z);
                            poly[1] = new Hare.Geometry.Point(B.X, B.Y, B.Z);
                            poly[2] = new Hare.Geometry.Point(C.X, C.Y, C.Z);
                            T[i].Add_Polygon(poly);
                        }

                        pts.Add(m[i].Faces[j].IsQuad ? new Point3d(A.X + B.X + C.X + D.X, A.Y + B.Y + C.Y + D.Y, A.Z + B.Z + C.Z + D.Z) / 4 : new Point3d(A.X + B.X + C.X, A.Y + B.Y + C.Y, A.Z + B.Z + C.Z) / 3);

                        SubDomains[i][j + 1] = Sub_A[i] += T[i].Polygon_Area(j);
                    }
                    Samples[i] = pts.ToArray();
                });

                Domains     = new double[Srfs.Count + 1];
                DomainLevel = new double[Srfs.Count][];
                DomainPower = new double[Srfs.Count][];
                Total_A     = 0;

                for (int i = 0; i < Srfs.Count; i++)
                {
                    for (int j = 0; j < SubDomains[i].Length; j++)
                    {
                        SubDomains[i][j] /= Sub_A[i];
                    }
                    double A = Srfs[i].GetArea();
                    Domains[i + 1] = Total_A += A;
                    DomainLevel[i] = Utilities.PachTools.DecodeSourcePower(CodeList[i]);
                    DomainPower[i] = new double[8];
                    double PowerMod = A;
                    for (int oct = 0; oct < 8; oct++)
                    {
                        DomainPower[i][oct] = 1E-12 * Math.Pow(10, .1 * DomainLevel[i][oct]) / PowerMod;
                    }
                }

                for (int i = 0; i < Domains.Length; i++)
                {
                    Domains[i] /= Total_A;
                }
            }
        public Speaker_Balloon(string[] Ballooncode_in, string SWL_in, int Type_in, Point3d Center)//int sym_in,
        {
            code = Ballooncode_in;
            Type = Type_in;
            if (SWL_in != "" || SWL_in != null)
            {
                SWL = SWL_in;
            }
            else 
            {
                SWL_in = "120; 120; 120; 120; 120; 120; 120; 120";
            }
            string[] swl = SWL.Split(';');
            double[] swl_values = new double[8];

            Vector upper = new Vector(0, 1, 0);

            int umax, vmax;
            switch (Type)
            {
                case 0:
                    umax = 19;
                    vmax = 36;
                    break;
                case 1:
                    umax = 37;
                    vmax = 72;
                    break;
                default:
                    throw new Exception();
            }

            m_HareMesh = new Topology[8];
            for (int oct = 1; oct < 9; oct++)
            {
                string[] values;
                swl_values[oct - 1] = double.Parse(swl[oct - 1]);
                if (code[oct - 1] != "")
                {
                    values = code[oct - 1].Split(';');
                }
                else
                {
                    values = new string[umax * vmax];
                    for (int i = 0; i < values.Length; i++)
                    {
                        values[i] = "0";
                    }
                }

                Vector[,] Magnitude = new Vector[umax, vmax];
                double Theta, Phi;
                int idx = 0;

                for (int v = 0; v < vmax; v++)
                {
                    for (int u = 0; u < umax; u++)
                    {
                        if (double.IsInfinity(swl_values[oct - 1]) || double.IsNaN(swl_values[oct - 1]))
                        {
                            Magnitude[u, v] = new Vector();
                        }
                        else
                        {
                            Theta = u * System.Math.PI / (umax - 1);
                            Phi = 2 * v * System.Math.PI / (vmax) + System.Math.PI / 2;
                            Magnitude[u, v] = new Vector(Math.Sin(Theta) * Math.Cos(Phi), Math.Cos(Theta), Math.Sin(Theta) * Math.Sin(Phi));
                            Magnitude[u, v].Normalize();
                            double swlmag = (double.Parse(values[idx]) + 60);
                            if (swlmag < 0) swlmag = 0;
                            Magnitude[u, v] *= swlmag;
                        }
                        idx++;
                    }
                }

                //Create a mesh of the points...
                List<Hare.Geometry.Point[]> list = new List<Hare.Geometry.Point[]>();
                double Minx = double.MaxValue, Miny = double.MaxValue, Minz = double.MaxValue, Maxx = double.MinValue, Maxy = double.MinValue, Maxz = double.MinValue;
                
                for (int u = 0; u < umax - 1; u++)
                {
                    for (int v = 0; v < vmax; v++)
                    {
                        Hare.Geometry.Point[] Poly = new Hare.Geometry.Point[4];
                        Poly[0] = Magnitude[u, v];
                        Poly[1] = Magnitude[u, (v + 1) % vmax];
                        Poly[2] = Magnitude[u + 1, (v + 1) % vmax];
                        Poly[3] = Magnitude[u + 1, v];
                        list.Add(Poly);

                        foreach (Hare.Geometry.Point p in Poly) 
                        {
                            if (p.x < Minx) Minx = p.x;
                            if (p.y < Miny) Miny = p.y;
                            if (p.z < Minz) Minz = p.z;
                            if (p.x > Maxx) Maxx = p.x;
                            if (p.y > Maxy) Maxy = p.y;
                            if (p.z > Maxz) Maxz = p.z;
                        }
                    }
                }

                m_HareMesh[oct - 1] = new Topology(new Hare.Geometry.Point(Minx, Miny, Minz), new Hare.Geometry.Point(Maxx, Maxy, Maxz));
                
                foreach (Hare.Geometry.Point[] Poly in list) m_HareMesh[oct - 1].Add_Polygon(Poly);
            }
            //RhinoMeshStuff
            m_RhinoMesh = new Mesh();
            int ct = 0;
            for (int i = 0; i < m_HareMesh[4].Polygon_Count; i++)
            {
                Hare.Geometry.Point[] Pt = m_HareMesh[4].Polygon_Vertices(i);
                int[] F = new int[m_HareMesh[4].Polys[i].VertextCT];
                //List<Point3d> F = new List<Point3d>();
                for (int j = 0; j < m_HareMesh[4].Polys[i].VertextCT; j++)
                {
                    m_RhinoMesh.Vertices.Add(new Point3d(Pt[j].x, Pt[j].y, Pt[j].z) / 90);
                    F[j] = ct;
                    //F.Add(new Point3d(Pt[j].x, Pt[j].y, Pt[j].z) / 200);
                    ct++;
                }
                m_RhinoMesh.Faces.AddFace(F[2], F[1], F[0], F[3]);
            }
            m_RhinoMesh.FaceNormals.ComputeFaceNormals();
            m_RhinoMesh.Normals.ComputeNormals();
            m_DisplayMesh = m_RhinoMesh.DuplicateMesh();
            Update_Position(new Point3f((float)Center.X, (float)Center.Y, (float)Center.Z));
        }
        public Edge_Straight(ref IEnumerable<Hare.Geometry.Point> SPT, ref IEnumerable<Hare.Geometry.Point> RPT, Environment.Medium_Properties Att_Props, Rhino.Geometry.Brep[] Brep, int[] Brep_Index, Curve Be)
            : base(Brep, Be)
        {
            //Rhino.RhinoDoc.ActiveDoc.Objects.Add(Brep[0]);
            //Rhino.RhinoDoc.ActiveDoc.Objects.Add(Brep[1]);
            ParentBreps = Brep_Index;
            //Rhino.RhinoDoc.ActiveDoc.Objects.AddCurve(Be);

            //if (!Brep.Edges[edge_id].IsLinear()) throw new Exception("Straight_Edge object called for curved edge.");
            Rhino.Geometry.Point3d PA = Be.PointAtStart;
            Rhino.Geometry.Point3d PB = Be.PointAtEnd;
            PointA = Utilities.PachTools.RPttoHPt(PA);
            PointB = Utilities.PachTools.RPttoHPt(PB);

            //Get the open wedge angle. This needs the source location, and occlusion info...
            //Assuming tangent angles are always correctly oriented...
            Vector Z_Dir = PointA - PointB;
            double length = Z_Dir.Length();
            Z_Dir.Normalize();
            double MinAngle = double.PositiveInfinity;
            List<Hare.Geometry.Point> Dpt = new List<Hare.Geometry.Point>();

            //Find the secondary source spacing DeltaZ
            Dpt.AddRange(RPT);
            Dpt.AddRange(SPT);

            for (int j = 0; j < Dpt.Count; j++)
            {
                double angle = Math.Abs(Hare_math.Dot(PointA - Dpt[j], Z_Dir));
                if (angle < MinAngle) MinAngle = angle;
                angle = Math.Abs(Hare_math.Dot(PointB - Dpt[j], Z_Dir));
                if (angle < MinAngle) MinAngle = angle;
            }
            double fs = 176400; //Hz.
            double DeltaZ = Att_Props.Sound_Speed(this.PointA) / (fs * MinAngle);//TODO: Adjust depending on distance from source to receiver... (nearest, farthest?)
            
            double El_Ct = Math.Ceiling(length / DeltaZ);
            DeltaZ = length / El_Ct;

            Random r = new Random();

            Plane P;
            Curve[] Csects1;
            Curve[] Csects2;
            Point3d[] Psects;

            //for (;;)
            //{
                double t = r.NextDouble() * (Be.Domain.Max - Be.Domain.Min) + Be.Domain.Min;

                Be.PerpendicularFrameAt(t, out P);

                Rhino.Geometry.Intersect.Intersection.BrepPlane(Brep[0], P, 0.1, out Csects1, out Psects);
                Rhino.Geometry.Intersect.Intersection.BrepPlane(Brep[1], P, 0.1, out Csects2, out Psects);

                //if (Csects1 != null && Csects2 != null && Csects1.Length > 0 && Csects2.Length > 0) break;

                //Rhino.RhinoDoc.ActiveDoc.Objects.Add(Csects1[0]);
                //Rhino.RhinoDoc.ActiveDoc.Objects.Add(Csects2[0]);
            //}

            Vector3d[] Tangents = new Vector3d[2];
            ///Control Start Point of curve
            if ((Csects1[0].PointAtStart.X * P.Origin.X + Csects1[0].PointAtStart.Y * P.Origin.Y + Csects1[0].PointAtStart.Z * P.Origin.Z) < 0.00001) Csects1[0].Reverse();
            if ((Csects2[0].PointAtStart.X * P.Origin.X + Csects2[0].PointAtStart.Y * P.Origin.Y + Csects2[0].PointAtStart.Z * P.Origin.Z) < 0.00001) Csects2[0].Reverse();
            ///Get Tangent Vector
            Tangents[0] = (Csects1[0].PointAtNormalizedLength(0.05) - P.Origin);
            Tangents[0].Unitize();
            Tangents[1] = (Csects2[0].PointAtNormalizedLength(0.05) - P.Origin);
            Tangents[1].Unitize();
            Hare.Geometry.Vector[] HTangents = new Hare.Geometry.Vector[2] { new Hare.Geometry.Vector(Tangents[0].X, Tangents[0].Y, Tangents[0].Z), new Hare.Geometry.Vector(Tangents[1].X, Tangents[1].Y, Tangents[1].Z) };
            ///Get Normal
            double up, vp;
            ComponentIndex CI;
            Point3d outPt;
            Vector3d[] Normals = new Vector3d[2];
            Brep[0].ClosestPoint(P.Origin, out outPt, out CI, out up, out vp, 0.01, out Normals[0]);
            Brep[1].ClosestPoint(P.Origin, out outPt, out CI, out up, out vp, 0.01, out Normals[1]);
            Hare.Geometry.Vector[] HNormals = new Hare.Geometry.Vector[2] { new Hare.Geometry.Vector(Normals[0].X, Normals[0].Y, Normals[0].Z), new Hare.Geometry.Vector(Normals[1].X, Normals[1].Y, Normals[1].Z) };
            Hare.Geometry.Point Pt1 = new Hare.Geometry.Point(PointA.x, PointA.y, PointA.z);

            //TODO - Modify DeltaZ per change in velocity.
            for (int i = 1; i < El_Ct; i++)
            {
                Hare.Geometry.Point Pt2 = PointA - i * Z_Dir * DeltaZ;
                Sources.Add(new EdgeSource(Edge.Rigid, Pt1, Pt2, HTangents));
                //HTangents[1]*= -1;
                //Sources.Add(new EdgeSource(Edge.Rigid, Pt1, Pt2, HTangents));
                Pt1 = Pt2;
            }
        }
            public override bool shoot(Ray R, out double u, out double v, out int Srf_ID, out Hare.Geometry.Point X_PT, out double t)
            {
                S_Origin = Utilities.PachTools.HPttoRPt(R.origin);
                Srf_ID = 0;

                while (true)
                {
                    Point3d[] P = Rhino.Geometry.Intersect.Intersection.RayShoot(new Ray3d(S_Origin, new Vector3d(R.direction.x, R.direction.y, R.direction.z)), BrepList, 1);

                    if (P == null) { X_PT = default(Hare.Geometry.Point); u = 0; v = 0; t = 0; return false; }

                    Voxels.PointIsInVoxel(P[0], ref XVoxel, ref YVoxel, ref ZVoxel);
                    try
                    {
                        SurfaceIndex = Voxels.VoxelList(XVoxel, YVoxel, ZVoxel);
                    }
                    catch (Exception)
                    {
                        //Rare floating point error on some computers... abandon the ray and start the next...
                        //Explanation: This would never happen on my IBM T43P laptop, but happened 
                        //consistently millions of function calls into the calculation on my 
                        //ASUS K8N-DL based desktop computer. I believe it has something to do with some quirk of that system.
                        //This try...catch statement is here in case this ever manifests on any user's computer. 
                        //It is rare enough that this should not affect the accuracy of the calculation.
                        t = 0.0f;
                        X_PT = default(Hare.Geometry.Point);
                        u = 0;
                        v = 0;
                        return false;
                    }

                    Point3d CP;
                    Vector3d N;
                    ComponentIndex CI;
                    double MD = 0.0001;

                    foreach (int index in SurfaceIndex)
                    {
                        if (BrepList[index].ClosestPoint(P[0], out CP, out CI, out u, out v, MD, out N) && (CI.ComponentIndexType == ComponentIndexType.BrepFace))
                        {
                            if ((Math.Abs(P[0].X - CP.X) < 0.0001) && (Math.Abs(P[0].Y - CP.Y) < 0.0001) && (Math.Abs(P[0].Z - CP.Z) < 0.0001))
                            {
                                Srf_ID = index;
                                X_PT = new Hare.Geometry.Point(P[0].X, P[0].Y, P[0].Z);
                                t = (double)(S_Origin.DistanceTo(P[0]));
                                return true;
                            }
                        }
                    }
                    S_Origin = new Point3d(P[0]);
                }
            }
            private void Partition(Source Src_Pt, bool ProcessMesh)
            {
                int processorCt = UI.PachydermAc_PlugIn.Instance.ProcessorSpec();

                if (ProcessMesh)
                {
                    Hare.Geometry.Point p;
                    if (Z_Displacement)
                    {
                        Hare.Geometry.Point V = new Hare.Geometry.Point(0, 0, increment * .5);
                        if (Rec_Vertex)
                        {
                            for (int i = 0; i < Map_Mesh.Vertices.Count; i++)
                            {
                                p = new Hare.Geometry.Point(Map_Mesh.Vertices[i].X, Map_Mesh.Vertices[i].Y, Map_Mesh.Vertices[i].Z) + V;
                                Rec_List[i] = new Map_Receiver(increment, i, p, Src_Pt, _Sc.Sound_speed(p), _Sc.Rho(p), _Sc.Attenuation(p), 1000, CutOffTime, processorCt, Time1Pt, Directional);
                            }
                        }
                        else
                        {
                            for (int i = 0; i < Map_Mesh.Faces.Count; i++)
                            {
                                Point3f center = new Point3f();
                                center.X = Map_Mesh.Vertices[Map_Mesh.Faces[i].A].X+ Map_Mesh.Vertices[Map_Mesh.Faces[i].B].X + Map_Mesh.Vertices[Map_Mesh.Faces[i].C].X;
                                center.Y = Map_Mesh.Vertices[Map_Mesh.Faces[i].A].Y+ Map_Mesh.Vertices[Map_Mesh.Faces[i].B].Y + Map_Mesh.Vertices[Map_Mesh.Faces[i].C].Y;
                                center.Z = Map_Mesh.Vertices[Map_Mesh.Faces[i].A].Z+ Map_Mesh.Vertices[Map_Mesh.Faces[i].B].Z + Map_Mesh.Vertices[Map_Mesh.Faces[i].C].Z;
                                
                                if (Map_Mesh.Faces[i].IsQuad)
                                {
                                    center.X += Map_Mesh.Vertices[Map_Mesh.Faces[i].D].X;
                                    center.Y += Map_Mesh.Vertices[Map_Mesh.Faces[i].D].Y;
                                    center.Z += Map_Mesh.Vertices[Map_Mesh.Faces[i].D].Z;
                                    center.X /= 4; center.Y /= 4;center.Z /= 4;
                                } else { center.X /= 3; center.Y /= 3;center.Z /= 3; }
                                    
                                p = new Hare.Geometry.Point(center.X, center.Y, center.Z) + V;
                                Rec_List[i] = new Map_Receiver(increment, i, p, Src_Pt, _Sc.Sound_speed(p), _Sc.Rho(p), _Sc.Attenuation(p), 1000, CutOffTime, processorCt, Time1Pt, Directional);
                            }
                        }
                            
                        if (Mesh_Offset) for (int i = 0; i < Map_Mesh.Vertices.Count; i++)
                        {                                
                             Map_Mesh.Vertices[i] = new Point3f(Map_Mesh.Vertices[i].X + (float)V.x,
                             Map_Mesh.Vertices[i].Y + (float)V.y,
                             Map_Mesh.Vertices[i].Z + (float)V.z);
                        }
                    }
                    else
                    {
                        if (Rec_Vertex)
                        {
                            for (int i = 0; i < Map_Mesh.Vertices.Count; i++)
                            {
                                Vector3f V = new Vector3f((float)(Map_Mesh.Normals[i].X * increment * .5), (float)(Map_Mesh.Normals[i].Y * increment * .5), (float)(Map_Mesh.Normals[i].Z * increment * .5));

                                p = new Hare.Geometry.Point(Map_Mesh.Vertices[i].X+ V.X, Map_Mesh.Vertices[i].Y + V.Y, Map_Mesh.Vertices[i].Z+ V.Z);
                                Rec_List[i] = new Map_Receiver(increment, i, p, Src_Pt, _Sc.Sound_speed(p), _Sc.Rho(p), _Sc.Attenuation(p), 1000, CutOffTime, processorCt, Time1Pt, Directional);
                            }
                        }
                        else
                        {
                            for (int i = 0; i < Map_Mesh.Faces.Count; i++)
                            {
                                Point3f center = new Point3f();
                                center.X = Map_Mesh.Vertices[Map_Mesh.Faces[i].A].X + Map_Mesh.Vertices[Map_Mesh.Faces[i].B].X + Map_Mesh.Vertices[Map_Mesh.Faces[i].C].X;
                                center.Y = Map_Mesh.Vertices[Map_Mesh.Faces[i].A].Y + Map_Mesh.Vertices[Map_Mesh.Faces[i].B].Y + Map_Mesh.Vertices[Map_Mesh.Faces[i].C].Y;
                                center.Z = Map_Mesh.Vertices[Map_Mesh.Faces[i].A].Z + Map_Mesh.Vertices[Map_Mesh.Faces[i].B].Z + Map_Mesh.Vertices[Map_Mesh.Faces[i].C].Z;

                                if (Map_Mesh.Faces[i].IsQuad)
                                {
                                    center.X += Map_Mesh.Vertices[Map_Mesh.Faces[i].D].X;
                                    center.Y += Map_Mesh.Vertices[Map_Mesh.Faces[i].D].Y;
                                    center.Z += Map_Mesh.Vertices[Map_Mesh.Faces[i].D].Z;
                                    center.X /= 4; center.Y /= 4; center.Z /= 4;
                                }
                                else { center.X /= 3; center.Y /= 3; center.Z /= 3; }

                                Vector3f V = new Vector3f((float)(Map_Mesh.FaceNormals[i].X * increment * .5), (float)(Map_Mesh.FaceNormals[i].Y * increment * .5), (float)(Map_Mesh.FaceNormals[i].Z * increment * .5));

                                p = new Hare.Geometry.Point(center.X + V.X, center.Y + V.Y, center.Z + V.Z);
                                Rec_List[i] = new Map_Receiver(increment, i, p, Src_Pt, _Sc.Sound_speed(p),_Sc.Rho(p), _Sc.Attenuation(p), 1000, CutOffTime, processorCt, Time1Pt, Directional);
                            }
                        }

                        if (Mesh_Offset) for (int i = 0; i < Map_Mesh.Vertices.Count; i++)
                        {
                            Vector3f V = Map_Mesh.Normals[i];
                            Map_Mesh.Vertices[i] = new Point3f(Map_Mesh.Vertices[i].X + (float)V.X,
                            Map_Mesh.Vertices[i].Y + (float)V.Y,
                            Map_Mesh.Vertices[i].Z + (float)V.Z);
                        }
                    }
                }
                else 
                {
                    for (int i = 0; i < Map_Mesh.Vertices.Count; i++)
                    {
                        Hare.Geometry.Point V = new Hare.Geometry.Point(0, 0, increment * .5);
                        Hare.Geometry.Point p = new Hare.Geometry.Point(Map_Mesh.Vertices[i].X, Map_Mesh.Vertices[i].Y, Map_Mesh.Vertices[i].Z);
                        Rec_List[i] = new Map_Receiver(increment, i, p, Src_Pt, _Sc.Rho(p), _Sc.Sound_speed(p), _Sc.Attenuation(p), 1000, CutOffTime, processorCt, Time1Pt, Directional);
                    }
                }

                foreach (Spherical_Receiver R in Rec_List)
                {
                    //Find max and min bounds of all spheres...
                    if ((R.H_Origin.x + (increment * .5)) > Max.x) Max.x = R.H_Origin.x + (increment * .5);
                    if ((R.H_Origin.y + (increment * .5)) > Max.y) Max.y = R.H_Origin.y + (increment * .5);
                    if ((R.H_Origin.z + (increment * .5)) > Max.z) Max.z = R.H_Origin.z + (increment * .5);
                    if ((R.H_Origin.x - (increment * .5)) < Min.x) Min.x = R.H_Origin.x - (increment * .5);
                    if ((R.H_Origin.y - (increment * .5)) < Min.y) Min.y = R.H_Origin.y - (increment * .5);
                    if ((R.H_Origin.z - (increment * .5)) < Min.z) Min.z = R.H_Origin.z - (increment * .5);
                }
                OBox = new AABB(Min, Max);

                //Divide the Min and Max into separate sub-voxels...
                VoxelCtX = (int)Math.Ceiling((OBox.Max_PT.x - OBox.Min_PT.x) / (increment * 4));
                VoxelCtY = (int)Math.Ceiling((OBox.Max_PT.y - OBox.Min_PT.y) / (increment * 4));
                VoxelCtZ = (int)Math.Ceiling((OBox.Max_PT.z - OBox.Min_PT.z) / (increment * 2.5));

                Voxels = new AABB[VoxelCtX, VoxelCtY, VoxelCtZ];
                Voxel_Inv = new List<int>[VoxelCtX, VoxelCtY, VoxelCtZ];

                BoxDims = (Max - Min);
                VoxelDims = new Hare.Geometry.Point(BoxDims.x / VoxelCtX, BoxDims.y / VoxelCtY, BoxDims.z / VoxelCtZ);
                VoxelDims_Inv = new Hare.Geometry.Point(1 / VoxelDims.x, 1 / VoxelDims.y, 1 / VoxelDims.z);
                BoxDims_Inv = new Hare.Geometry.Point(1 / BoxDims.x, 1 / BoxDims.y, 1 / BoxDims.z);

                for (int x = 0; x < VoxelCtX; x++)
                {
                    for (int y = 0; y < VoxelCtY; y++)
                    {
                        for (int z = 0; z < VoxelCtZ; z++)
                        {
                            Voxel_Inv[x, y, z] = new List<int>();
                            Hare.Geometry.Point voxelmin = new Hare.Geometry.Point(x * VoxelDims.x, y * VoxelDims.y, z * VoxelDims.z);
                            Hare.Geometry.Point voxelmax = new Hare.Geometry.Point((x + 1) * VoxelDims.x, (y + 1) * VoxelDims.y, (z + 1) * VoxelDims.z);
                            AABB Box = new AABB(voxelmin + OBox.Min_PT, voxelmax + OBox.Min_PT);
                            Voxels[x, y, z] = Box;
                            for (int i = 0; i < Rec_List.Length; i++)
                            {
                                //Check for intersection between voxel x,y,z with Receiver i...
                                Hare.Geometry.Point PT = Box.ClosestPt(Rec_List[i].H_Origin);
                                PT -= Rec_List[i].H_Origin;
                                if ((PT.x * PT.x + PT.y * PT.y + PT.z * PT.z) < Rec_List[i].Radius2)
                                {
                                    Voxel_Inv[x, y, z].Add(i);
                                }
                            }
                        }
                    }
                }
            }