/// <summary>
 /// Constructor prepares image source calculation to run.
 /// </summary>
 /// <param name="Source"></param>
 /// <param name="Receiver"></param>
 /// <param name="Direct"></param>
 /// <param name="Rm"></param>
 /// <param name="MaxOrder_in">The maximum order to be calculated for.</param>
 public ImageSourceData(Source Source, Receiver_Bank Receiver, Direct_Sound Direct, Polygon_Scene Rm, int[] Octaves, int MaxOrder_in, bool Edge_Diffraction, int SourceID_in)
 {
     IncludeEdges = Edge_Diffraction;
     Diffraction = Edge_Diffraction;
     Oct_choice = new int[Octaves[1] - Octaves[0] + 1];
     for (int i = 0; i < Octaves.Length; i++) Oct_choice[i] = i + Octaves[0];
     SrcNo = SourceID_in;
     ValidPaths = new List<Deterministic_Reflection>[Receiver.Count];
     Speed_of_Sound = Rm.Sound_speed(0);
     MaxOrder = MaxOrder_in;
     Src = Source;
     Rec = new Hare.Geometry.Point[Receiver.Count];
     SampleCT = Receiver.SampleCT;
     SampleRate = Receiver.SampleRate;
     for(int i = 0; i < Receiver.Count; i++)
     {
         Rec[i] = Receiver.H_Origin(i);
     }
     Room = Rm;
     Direct_Time = new double[Receiver.Count];
     for (int q = 0; q < Receiver.Count; q++)
     {
         Direct_Time[q] = Direct.Min_Time(q);
     }
 }
Exemplo n.º 2
0
 public Detailed_Convergence_Check(Receiver_Bank R, int id, int _oct, int check_id)
     : base(R, id, _oct, check_id)
 {
     step     = (R.SampleRate / 1000);
     binct    = RunningSim.Length / step;
     Snapshot = new double[binct];
 }
        /// <summary>
        /// Constructor for the general case ray tracer.
        /// </summary>
        /// <param name="sourceIn"></param>
        /// <param name="receiverIn"></param>
        /// <param name="roomIn"></param>
        /// <param name="cutOffLengthIn"></param>
        /// <param name="rayCountIn"></param>
        /// <param name="octaveRange">Two values - the lowest octave to be calculated and the highest octave to be calculated - 0 being 62.5, and 7 being 8k.</param>
        /// <param name="isOrderIn">The highest order for which image source was calcualted. If no Image Source, then enter 0.</param>
        /// <param name="partitionedReceiver">Is the receiver partitioned... i.e., did you use a mapping receiver bank?</param>
        public SplitRayTracer(Source sourceIn, Receiver_Bank receiverIn, Scene roomIn, double cutoffTime, int rayCountIn, int[] octaveRange, int isOrderIn)
        {
            IS_Order = isOrderIn;
            Room = roomIn;
            RecMain = receiverIn;
            Raycount = rayCountIn;
            _octaves = new int[octaveRange[1]- octaveRange[0] + 1];
            for (int o = octaveRange[0]; o <= octaveRange[1]; o++) _octaves[o - octaveRange[0]] = o; 
            COTime = cutoffTime;
            Source = sourceIn;
            double[] totalAbs = new double[8];
            
            for (int s = 0; s < Room.Count(); s++)
            {
                double area = Room.SurfaceArea(s);
                foreach (int o in _octaves)
                {
                    totalAbs[o] += area * Room.AbsorptionValue[s].Coefficient_A_Broad(o);
                }
            }

            double min = double.PositiveInfinity;
            double octpower = 0;
            foreach (int o in _octaves) if (Source.SoundPower[o] > octpower) { octpower = Source.SoundPower[o]; }

            foreach(int o in _octaves)
            {
                if (Source.SoundPower[o] < octpower * 1E-6) continue;
                if (min > totalAbs[o])
                {
                    min = totalAbs[o];
                    h_oct = o;
                }
            }
        }
Exemplo n.º 4
0
 public Minimum_Convergence_Check(Source S, Scene Sc, Receiver_Bank R, int id, int _oct, int check_id)
     : base(R, id, _oct, check_id)
 {
     SampleStart = (int)Math.Floor((S.H_Origin() - R.Origin(id)).Length() / Sc.Sound_speed(R.Origin(id)) * R.SampleRate);
     Sample50    = (int)Math.Floor(50.0 * R.SampleRate / 1000) + SampleStart;
     Sample80    = (int)Math.Floor(80.0 * R.SampleRate / 1000) + SampleStart;
     SampleInf   = R.SampleCT;
 }
 public IS_Trace(Source Source_in, Receiver_Bank Receiver_in, Polygon_Scene Room_in, double CutOffLength_in, int RayCount_in, int ImageOrder_in, double Speed_of_sound, int Bincount_in)
 {
     C_Sound      = Speed_of_sound;
     CO_Time      = CutOffLength_in / Speed_of_sound;
     Room         = Room_in;
     Receiver     = Receiver_in;
     Raycount     = RayCount_in;
     CutoffLength = CutOffLength_in;
     ImageOrder   = ImageOrder_in;
     Source       = Source_in;
 }
 public IS_Trace(Source Source_in, Receiver_Bank Receiver_in, Polygon_Scene Room_in, double CutOffLength_in, int RayCount_in, int ImageOrder_in, double Speed_of_sound, int Bincount_in)
 {
     C_Sound = Speed_of_sound;
     CO_Time = CutOffLength_in / Speed_of_sound;
     Room = Room_in;
     Receiver = Receiver_in;
     Raycount = RayCount_in;
     CutoffLength = CutOffLength_in;
     ImageOrder = ImageOrder_in;
     Source = Source_in;
 }
 /// <summary>
 /// Private receiver bank constructer for file read-in.
 /// </summary>
 /// <param name="Rec_Count">The number of receivers specified by the user</param>
 /// <param name="SampleRate_in">the simulation histogram sampling frequency</param>
 /// <param name="CSound">the speed of sound in m/s</param>
 /// <param name="CO_Time_in">The Cut Off Time of the simulation in ms.</param>
 /// <param name="Type">The type of receiver to be used</param>
 private Receiver_Bank(int Rec_Count, int SampleRate_in, double CO_Time_in, double delayinms, double[] rho_c, int[] Octaves, Receiver_Bank.Type Type)
 {
     delay_ms = delayinms;
     SampleRate = SampleRate_in;
     SampleCT = (int)Math.Ceiling(CO_Time_in * SampleRate_in / 1000);
     this.CutOffTime = CO_Time_in;
     Rec_List = new Spherical_Receiver[Rec_Count];
     Rec_Type = Type;
     for (int i = 0; i < Rec_Count; i++)
     {
         Rec_List[i] = new Spherical_Receiver(SampleRate_in, CO_Time_in, rho_c[i]);
     }
 }
Exemplo n.º 8
0
        /// <summary>
        /// Constructor for the general case ray tracer.
        /// </summary>
        /// <param name="sourceIn"></param>
        /// <param name="receiverIn"></param>
        /// <param name="roomIn"></param>
        /// <param name="cutOffLengthIn"></param>
        /// <param name="rayCountIn"></param>
        /// <param name="octaveRange">Two values - the lowest octave to be calculated and the highest octave to be calculated - 0 being 62.5, and 7 being 8k.</param>
        /// <param name="isOrderIn">The highest order for which image source was calcualted. If no Image Source, then enter 0.</param>
        /// <param name="partitionedReceiver">Is the receiver partitioned... i.e., did you use a mapping receiver bank?</param>
        public SplitRayTracer(Source sourceIn, Receiver_Bank receiverIn, Scene roomIn, double cutoffTime, int rayCountIn, int[] octaveRange, int isOrderIn)
        {
            IS_Order = isOrderIn;
            Room     = roomIn;
            RecMain  = receiverIn;
            Raycount = rayCountIn;
            _octaves = new int[octaveRange[1] - octaveRange[0] + 1];
            for (int o = octaveRange[0]; o <= octaveRange[1]; o++)
            {
                _octaves[o - octaveRange[0]] = o;
            }
            COTime = cutoffTime;
            Source = sourceIn;
            double[] totalAbs = new double[8];

            for (int s = 0; s < Room.Count(); s++)
            {
                double area = Room.SurfaceArea(s);
                foreach (int o in _octaves)
                {
                    totalAbs[o] += area * Room.AbsorptionValue[s].Coefficient_A_Broad(o);
                }
            }

            double min      = double.PositiveInfinity;
            double octpower = 0;

            foreach (int o in _octaves)
            {
                if (Source.SoundPower[o] > octpower)
                {
                    octpower = Source.SoundPower[o];
                }
            }

            foreach (int o in _octaves)
            {
                if (Source.SoundPower[o] < octpower * 1E-6)
                {
                    continue;
                }
                if (min > totalAbs[o])
                {
                    min   = totalAbs[o];
                    h_oct = o;
                }
            }
        }
            public void Register_Edges(IEnumerable <Source> S, Receiver_Bank R)
            {
                List <Hare.Geometry.Point> HS = new List <Hare.Geometry.Point>();
                List <Hare.Geometry.Point> HR = new List <Hare.Geometry.Point>();

                foreach (Source SPT in S)
                {
                    HS.Add(SPT.Origin());
                }
                foreach (Point RPT in R.Origins())
                {
                    HR.Add(RPT);
                }

                Register_Edges(HS, HR);
            }
 /// <summary>
 /// Direct sound constructor. This prepares the simulation to run. 
 /// </summary>
 /// <param name="Src_in">The sound source</param>
 /// <param name="Rec_in">The collection of receivers</param>
 /// <param name="Room_in">The acoustical scene to render</param>
 /// <param name="RayCount">The number of rays which will be used </param>
 public Direct_Sound(Source Src_in, Receiver_Bank Rec_in, Scene Room_in, int[] Octaves)
 {
     type = Src_in.Type();
     Validity = new bool[Rec_in.Count];//[Rec_in.Count];
     Io = new double[Rec_in.Count][][];//[Rec_in.Count][t,8];
     Time_Pt = new double[Rec_in.Count];//[Rec_in.Count];
     Dir_Rec_Pos = new float[Rec_in.Count][][][];
     Dir_Rec_Neg = new float[Rec_in.Count][][][];
     Room = Room_in;
     C_Sound = Room_in.Sound_speed(0);
     SampleFreq = Rec_in.SampleRate;
     Src = Src_in;
     this.CO_Time = Rec_in.CO_Time;
     Receiver = new List<Point>();
     Rho_C = new double[Rec_in.Count];
     for(int i = 0; i < Rec_in.Count; i++)
     {
         Rho_C[i] = Room.Rho_C(Rec_in.H_Origin(i));
         Receiver.Add(Rec_in.H_Origin(i));
     }
     SWL = new double[8] { Src_in.SWL(0), Src_in.SWL(1), Src_in.SWL(2), Src_in.SWL(3), Src_in.SWL(4), Src_in.SWL(5), Src_in.SWL(6), Src_in.SWL(7) };
     Delay_ms = Src.Delay;
     Oct_choice = Octaves;
 }
Exemplo n.º 11
0
 public ImageSourceData(Source Source, Receiver_Bank Receiver, Direct_Sound Direct, Polygon_Scene Rm, int MaxOrder_in, bool ED, int SourceID_in)
     : this(Source, Receiver, Direct, Rm, new int[2] { 0, 7 }, MaxOrder_in, ED, SourceID_in)
 { }
Exemplo n.º 12
0
            private void Calculate_Click(object sender, System.EventArgs e)
            {
                string SavePath = null;

                CutoffTime = (double)this.CO_TIME.Value;

                if (plugin.Save_Results())
                {
                    System.Windows.Forms.SaveFileDialog sf = new System.Windows.Forms.SaveFileDialog();
                    sf.DefaultExt = ".pac1";
                    sf.AddExtension = true;
                    sf.Filter = "Pachyderm Ray Data file (*.pac1)|*.pac1|" + "All Files|";
                    if (sf.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                    {
                        SavePath = sf.FileName;
                    }
                }
                for (int i = 0; i < SourceList.Items.Count; i++) SourceList.SetItemChecked(i, false);

                SourceList.Items.Clear();
                Source_Aim.Items.Clear();
                Receiver_Choice.Text = "0";

                IS_Data = null;
                Direct_Data = null;
                List<Point3d> RPT;

                if (!(plugin.Receiver(out RPT) && plugin.Source(out Source)))
                {
                    Rhino.RhinoApp.WriteLine("Model geometry not specified... Exiting calculation...");
                    return;
                }

                List<Point3d> SPT = new List<Point3d>();
                foreach (Source S in Source)
                {
                    S.AppendPts(ref SPT);
                }
                IS_Data = new ImageSourceData[Source.Length];
                Direct_Data = new Direct_Sound[Source.Length];

                Calculate.Enabled = false;
                IS_Path_Box.Items.Clear();

                List<Point3d> P = new List<Point3d>();
                P.AddRange(RPT);
                P.AddRange(SPT);

                Polygon_Scene PScene = Utilities.PachTools.Get_Poly_Scene((double)Rel_Humidity.Value, (double)Air_Temp.Value, (double)Air_Pressure.Value, Atten_Method.SelectedIndex, EdgeFreq.Checked);
                if (PScene == null || !PScene.Complete)
                {
                    CancelCalc();
                    return;
                }
                PScene.partition(P);

                ///////////////
                if (BTM_ED.Checked) PScene.Register_Edges(SPT, RPT);
                ///////////////

                Scene Flex_Scene;
                if (PachydermAc_PlugIn.Instance.Geometry_Spec() == 0)
                {
                    RhCommon_Scene NScene = Utilities.PachTools.Get_NURBS_Scene((double)Rel_Humidity.Value, (double)Air_Temp.Value, (double)Air_Pressure.Value, Atten_Method.SelectedIndex, EdgeFreq.Checked);
                    if (!NScene.Complete)
                    {
                        CancelCalc();
                        return;
                    }
                    NScene.partition(P, plugin.VG_Domain());
                    Flex_Scene = NScene;
                }
                else
                {
                    Flex_Scene = PScene;
                }

                Receiver_Bank.Type T;

                switch ((string)ReceiverSelection.SelectedItem)
                {
                    case "1 m. Stationary Receiver":
                        T = Receiver_Bank.Type.Stationary;
                        break;
                    case "Expanding Receiver (Expanding)":
                        T = Receiver_Bank.Type.Variable;
                        break;
                    default:
                        Rhino.RhinoApp.WriteLine("Receiver Object Error");
                        Calculate.Enabled = true;
                        Source = null;
                        return;
                }

                Receiver = new Receiver_Bank[Source.Length];
                Pach_RunSim_Command command = Pach_RunSim_Command.Instance;

                if (command == null) { return; }

                for (int s = 0; s < Source.Length; s++)
                {
                    Receiver_Bank Rec = new Receiver_Bank(RPT.ToArray(), SPT[s], PScene, SampleRate, CutoffTime, Source[s].Delay, T);

                    command.Sim = new Direct_Sound(Source[s], Rec, PScene, new int[] { 0, 1, 2, 3, 4, 5, 6, 7 });
                    Rhino.RhinoApp.RunScript("Run_Simulation", false);
                    if (command.CommandResult != Rhino.Commands.Result.Cancel)
                    {
                        Direct_Data[s] = ((Direct_Sound)command.Sim);
                        Direct_Data[s].Create_Pressure();
                    }
                    else
                    {
                        CancelCalc();
                        return;
                    }
                    command.Reset();

                    if (ISBox.CheckState == CheckState.Checked)
                    {
                        command.Sim = new ImageSourceData(Source[s], Rec, Direct_Data[s], PScene, new int[] { 0, 7 }, (int)Image_Order.Value, BTM_ED.Checked, s);

                        Rhino.RhinoApp.RunScript("Run_Simulation", false);
                        if (command.CommandResult != Rhino.Commands.Result.Cancel)
                        {
                            IS_Data[s] = ((ImageSourceData)command.Sim);
                        }
                        else
                        {
                            CancelCalc();
                            return;
                        }
                        command.Reset();
                    }

                    if (ISBox.CheckState == CheckState.Checked && Specular_Trace.CheckState == CheckState.Checked)
                    {
                        command.Sim = new IS_Trace(Source[s], Rec, PScene, ((double)(CO_TIME.Value / 1000) * PScene.Sound_speed(0)), (int)Spec_RayCount.Value, (int)Image_Order.Value, PScene.Sound_speed(0), SampleRate);
                        Rhino.RhinoApp.RunScript("Run_Simulation", false);
                        if (command.CommandResult != Rhino.Commands.Result.Cancel)
                        {
                            IS_Data[s].Lookup_Sequences(((IS_Trace)(command.Sim)).IS_Sequences());
                        }
                        else
                        {
                            CancelCalc();
                            return;
                        }
                        command.Reset();
                    }
                    if (RTBox.CheckState == CheckState.Checked)
                    {
                        command.Sim = new SplitRayTracer(Source[s], Rec, Flex_Scene, ((double)(CO_TIME.Value / 1000) * PScene.Sound_speed(0)), (int)RT_Count.Value, Specular_Trace.Checked ? int.MaxValue : ISBox.Checked ? (int)Image_Order.Value : 0);

                        Rhino.RhinoApp.RunScript("Run_Simulation", false);
                        if (command.CommandResult != Rhino.Commands.Result.Cancel)
                        {
                            SplitRayTracer RT_Data = (SplitRayTracer)command.Sim;
                            Receiver[s] = RT_Data.GetReceiver;
                            Receiver[s].Create_Pressure();
                        }
                        else
                        {
                            CancelCalc();
                            return;
                        }
                        command.Reset();
                    }
                }

                if (Source != null)
                {
                    List<Point3d> R;
                    plugin.Receiver(out R);
                    Recs = new Hare.Geometry.Point[R.Count];
                    for (int q = 0; q < R.Count; q++)
                    {
                        Recs[q] = PachTools.RPttoHPt(R[q]);
                    }

                    if (SavePath != null) Utilities.FileIO.Write_Pac1(SavePath, ref Direct_Data, ref IS_Data, ref Receiver);

                    OpenAnalysis();
                    cleanup();
                }
                Populate_Sources();
            }
            public void Register_Edges(IEnumerable<Source> S, Receiver_Bank R)
            {
                List<Hare.Geometry.Point> HS = new List<Hare.Geometry.Point>();
                List<Hare.Geometry.Point> HR = new List<Hare.Geometry.Point>();

                foreach (Source SPT in S) HS.Add(Utilities.PachTools.RPttoHPt(SPT.Origin()));
                foreach (Point3d RPT in R.Origins()) HR.Add(Utilities.PachTools.RPttoHPt(RPT));

                Register_Edges(HS, HR);
            }
            /// <summary>
            /// this method creates a complete Receiver bank from saved data.
            /// </summary>
            /// <param name="BR">the binary reader from which the data will come.</param>
            /// <param name="Rec_CT">The number of receivers</param>
            /// <param name="SampleRate">the histogram sampling frequency</param>
            /// <returns>a complete receiver bank</returns>
            public static Receiver_Bank Read_Data(ref System.IO.BinaryReader BR, int Rec_CT, IEnumerable<Hare.Geometry.Point> RecPts, double[] rho_c, double delayms, ref int SampleRate, string version)
            {
                //2. Write the type of receivers used
                Type Rec_typ = (Type)Enum.ToObject(typeof(Type), BR.ReadUInt32());

                //3. Write the sample rate:int
                SampleRate = BR.ReadInt32();

                //4. Write the number of samples:int
                int SampleCT = BR.ReadInt32();

                //5. Write the Speed of Sound:double (deprecated as of v1.6...)
                //double C_Sound = BR.ReadDouble();

                //6. Write the cut off time:double
                double CutoffTime = BR.ReadDouble();

                Receiver_Bank Rec = new Receiver_Bank(Rec_CT, SampleRate, CutoffTime, delayms, rho_c, new int[]{0,1,2,3,4,5,6,7},Rec_typ);

                double v = double.Parse(version.Substring(0, 3));

                for (int q = 0; q < Rec_CT; q++)
                {
                    Rec.Rec_List[q].H_Origin = RecPts.ElementAt<Hare.Geometry.Point>(q);
                    Rec.Rec_List[q].Recs.Energy[0] = new double[SampleCT];
                    Rec.Rec_List[q].Recs.Energy[1] = new double[SampleCT];
                    Rec.Rec_List[q].Recs.Energy[2] = new double[SampleCT];
                    Rec.Rec_List[q].Recs.Energy[3] = new double[SampleCT];
                    Rec.Rec_List[q].Recs.Energy[4] = new double[SampleCT];
                    Rec.Rec_List[q].Recs.Energy[5] = new double[SampleCT];
                    Rec.Rec_List[q].Recs.Energy[6] = new double[SampleCT];
                    Rec.Rec_List[q].Recs.Energy[7] = new double[SampleCT];

                    //if (v == 1.7)
                    //{
                    //    for (int i = 0; i < 16; i++) BR.ReadSingle();
                    //}
                    ////////Initiates the directional Histogram////////
                    //Rec.Rec_List[q].Recs = new Spherical_Receiver.Directional_Histogram(SampleRate, SampleCT);
                    //7a. Reads in the speed of sound.
                    Rec.Rec_List[q].Sound_Speed = BR.ReadDouble();

                    for (int j = 0; j < SampleCT; j++)
                    {
                        //7b. Write the echogram sample and directional sample:(double + 3double) * 8
                        for (int oct = 0; oct < 8; oct++)
                        {
                            Rec.Rec_List[q].Recs.Energy[oct][j] = BR.ReadDouble();
                            if (v == 1.7)
                            {
                                BR.ReadSingle(); BR.ReadSingle();
                                Rec.Rec_List[q].Recs.Add_direction(oct, j, new Vector(BR.ReadSingle(), BR.ReadSingle(), BR.ReadSingle()), new Vector(BR.ReadSingle(), BR.ReadSingle(), BR.ReadSingle()));
                            }
                            else
                            {
                                Rec.Rec_List[q].Recs.Add_direction(oct, j, new Vector(BR.ReadDouble(), BR.ReadDouble(), BR.ReadDouble()), new Vector(BR.ReadDouble(), BR.ReadDouble(), BR.ReadDouble()));
                            }
                        }
                    }
                }

                Rec.Create_Pressure();
                return Rec;
            }
 /// <summary>
 /// combines all threadlocal results
 /// </summary>
 /// <param name="Rec">a receiver bank clone to combine with this receiver bank instance</param>
 public virtual void Combine_Clones(Receiver_Bank Rec)
 {
     //C_Sound = SoundSpeed;
     for (int R = 0; R < Rec.Count; R++)
     {
         for (int oct = 0; oct < 8; oct++)
         {
             for (int T = 0; T < Rec.Duration(); T++)
             {
                 Rec_List[R].Combine_Sample(T, Rec.Rec_List[R].Energy(T, oct), Rec.Rec_List[R].Directions_Pos(oct,T), Rec.Rec_List[R].Directions_Neg(oct,T), oct);
             }
         }
     }
 }
Exemplo n.º 16
0
        /// <summary>
        /// Constructor for the general case ray tracer.
        /// </summary>
        /// <param name="sourceIn"></param>
        /// <param name="receiverIn"></param>
        /// <param name="roomIn"></param>
        /// <param name="cutOffLengthIn"></param>
        /// <param name="rayCountIn"></param>
        /// <param name="octaveRange">Two values - the lowest octave to be calculated and the highest octave to be calculated - 0 being 62.5, and 7 being 8k.</param>
        /// <param name="isOrderIn">The highest order for which image source was calcualted. If no Image Source, then enter 0.</param>
        /// <param name="partitionedReceiver">Is the receiver partitioned... i.e., did you use a mapping receiver bank?</param>
        public SplitRayTracer(Source sourceIn, Receiver_Bank receiverIn, Scene roomIn, double cutoffTime, int[] octaveRange, int isOrderIn, int rayCountIn)
        {
            IS_Order = isOrderIn;
            Room     = roomIn;
            RecMain  = receiverIn;
            Raycount = rayCountIn;
            _octaves = new int[octaveRange[1] - octaveRange[0] + 1];
            for (int o = octaveRange[0]; o <= octaveRange[1]; o++)
            {
                _octaves[o - octaveRange[0]] = o;
            }
            COTime = cutoffTime;
            Source = sourceIn;
            double[] totalAbs = new double[8];

            for (int s = 0; s < Room.Count(); s++)
            {
                double area = Room.SurfaceArea(s);
                foreach (int o in _octaves)
                {
                    totalAbs[o] += area * Room.AbsorptionValue[s].Coefficient_A_Broad(o);
                }
            }

            double min      = double.PositiveInfinity;
            double octpower = 0;

            foreach (int o in _octaves)
            {
                if (Source.SoundPower[o] > octpower)
                {
                    octpower = Source.SoundPower[o];
                }
            }

            foreach (int o in _octaves)
            {
                if (Source.SoundPower[o] < octpower * 1E-6)
                {
                    continue;
                }
                if (min > totalAbs[o])
                {
                    min   = totalAbs[o];
                    h_oct = o;
                }
            }

            if (Raycount < 1)
            {
                List <Point> spt = new List <Point>();
                if (!(Source is LineSource) && !(Source is SurfaceSource))
                {
                    spt.Add(Source.Origin());
                }
                else if (Source is LineSource)
                {
                    foreach (Point p in (Source as LineSource).Samples)
                    {
                        spt.Add(p);
                    }
                }
                else
                {
                    foreach (Point p in (Source as SurfaceSource).Samples)
                    {
                        spt.Add(p);
                    }
                }
                Random r = new Random();
                Raycount = int.MaxValue;
                double maxT_T = 0;
                int    T_id   = -1;
                double maxT_F = 0;
                int    F_id   = -1;
                double t;
                for (int i = 0; i < RecMain.Rec_List.Length; i++)
                {
                    Hare.Geometry.Point s = new Point();
                    double d = double.MaxValue;
                    foreach (Point p in spt)
                    {
                        double dt = (p - RecMain.Rec_List[i].Origin).Length();
                        if (dt < d)
                        {
                            s = p;
                            d = dt;
                        }
                    }

                    if (Check_Validity(s, i, r.Next(), out t))
                    {
                        if (maxT_T < t)
                        {
                            T_id   = i;
                            maxT_T = t;
                        }
                    }
                    else
                    {
                        if (maxT_F < t)
                        {
                            F_id   = i;
                            maxT_F = t;
                        }
                    }
                }
                check = (rayCountIn < 0) ? new Convergence_Check[2] {
                    T_id < 0 ? null : new Minimum_Convergence_Check(this.Source, this.Room, receiverIn, T_id, h_oct, 0), F_id < 0 ? null : new Minimum_Convergence_Check(this.Source, this.Room, receiverIn, F_id, h_oct, 1)
                }
                : new Convergence_Check[2] {
                    T_id < 0 ? null : new Detailed_Convergence_Check(receiverIn, T_id, h_oct, 0), F_id < 0 ? null : new Detailed_Convergence_Check(receiverIn, F_id, h_oct, 1)
                };
                Convergence_Progress_WinForms.Instance.Show();
            }
            else
            {
                check = null;
            }
        }
Exemplo n.º 17
0
 public Convergence_Check(Receiver_Bank R, int id, int _oct, int check_id)
 {
     oct        = _oct;
     RunningSim = R.Rec_List[id].Recs.Energy[oct];
     check_no   = check_id;
 }
 /// <summary>
 /// Constructor for the general case ray tracer.
 /// </summary>
 /// <param name="sourcein"></param>
 /// <param name="receiverin"></param>
 /// <param name="roomin"></param>
 /// <param name="cutofflengthin"></param>
 /// <param name="raycountin"></param>
 /// <param name="isorderin"></param>
 /// <param name="partitionedreceiver"></param>
 public SplitRayTracer(Source sourcein, Receiver_Bank receiverin, Scene roomin, double cutoffTime, int raycountin, int isorderin)
     :this(sourcein, receiverin, roomin, cutoffTime, raycountin, new int[]{0, 7}, isorderin) 
 {
 }
            public static double[][] PTCurve_Fig8_3Axis(Direct_Sound Direct, ImageSourceData ISData, Receiver_Bank RTData, double CO_Time_ms, int Sampling_Frequency, int Rec_ID, bool Start_at_Zero, double xpos_alt, double xpos_azi, bool degrees)
            {
                double[][] Histogram = new double[3][];
                if (RTData != null)
                {
                    double[][] hist_temp = RTData.Pressure_3Axis(Rec_ID);
                    Histogram[0] = new double[hist_temp[0].Length];
                    Histogram[1] = new double[hist_temp[0].Length];
                    Histogram[2] = new double[hist_temp[0].Length];
                    for (int i = 0; i < hist_temp[0].Length; i++)
                    {
                        Hare.Geometry.Vector V = PachTools.Rotate_Vector(PachTools.Rotate_Vector(new Hare.Geometry.Vector(hist_temp[0][i] - hist_temp[1][i], hist_temp[2][i] - hist_temp[3][i], hist_temp[4][i] - hist_temp[5][i]), xpos_azi, 0, true), 0, xpos_alt, true);
                        Histogram[0][i] = V.x;
                        Histogram[1][i] = V.y;
                        Histogram[2][i] = V.z;
                    }
                }
                else
                {
                    Histogram[0] = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency) + 4096];
                    Histogram[1] = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency) + 4096];
                    Histogram[2] = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency) + 4096];
                }

                if (Direct != null && Direct.IsOccluded(Rec_ID))
                {
                    int D_Start = 0;
                    if (!Start_at_Zero) D_Start = (int)Math.Ceiling(Direct.Time(Rec_ID) * Sampling_Frequency);

                    double[][] V = Direct.Dir_Pressure(Rec_ID, xpos_alt, xpos_azi, degrees, true);
                    for (int i = 0; i < V.Length; i++)
                    {
                        Histogram[0][D_Start + i] += V[i][0];
                        Histogram[1][D_Start + i] += V[i][1];
                        Histogram[2][D_Start + i] += V[i][2];
                    }
                }

                if (ISData != null)
                {
                    foreach (Deterministic_Reflection value in ISData.Paths[Rec_ID])
                    {
                        if (Math.Ceiling(Sampling_Frequency * value.TravelTime) < Histogram[0].Length - 1)
                        {
                            int R_Start = (int)Math.Ceiling(Sampling_Frequency * value.TravelTime);

                            double[][] V = value.Dir_Pressure(Rec_ID, xpos_alt, xpos_azi, degrees, Sampling_Frequency);

                            Hare.Geometry.Vector dir = value.Path[0][value.Path[0].Length - 1] - value.Path[0][value.Path[0].Length - 2];
                            dir.Normalize();
                            for (int i = 0; i < value.Pressure.Length; i++)
                            {
                                Histogram[0][R_Start + i] += V[i][0];
                                Histogram[1][R_Start + i] += V[i][1];
                                Histogram[2][R_Start + i] += V[i][2];
                            }
                        }
                    }
                }
                return Histogram;
            }
Exemplo n.º 20
0
 /// <summary>
 /// Constructor for the general case ray tracer.
 /// </summary>
 /// <param name="sourcein"></param>
 /// <param name="receiverin"></param>
 /// <param name="roomin"></param>
 /// <param name="cutofflengthin"></param>
 /// <param name="raycountin"></param>
 /// <param name="isorderin"></param>
 /// <param name="partitionedreceiver"></param>
 public SplitRayTracer(Source sourcein, Receiver_Bank receiverin, Scene roomin, double cutoffTime, int raycountin, int isorderin)
     : this(sourcein, receiverin, roomin, cutoffTime, raycountin, new int[] { 0, 7 }, isorderin)
 {
 }
            public static double[] PTCurve_Directional(Direct_Sound Direct, ImageSourceData ISData, Receiver_Bank RTData, double CO_Time_ms, int Sampling_Frequency, int Octave, int Rec_ID, bool Start_at_Zero, double alt, double azi, bool degrees)
            {
                double[] Histogram;
                if (RTData != null)
                {
                    int[] ids = new int[3];
                    ids[0] = (azi > 90 && azi < 270) ? 1 : 0;
                    ids[0] = (azi <= 180) ? 3 : 4;
                    ids[0] = (alt > 0) ? 4 : 5;
                    double[][] hist_temp = RTData.Pressure_3Axis(Rec_ID);
                    Histogram = new double[hist_temp[0].Length];
                    for (int i = 0; i < hist_temp[0].Length; i++)
                    {
                        Hare.Geometry.Vector V = PachTools.Rotate_Vector(PachTools.Rotate_Vector(new Hare.Geometry.Vector(hist_temp[ids[0]][i], hist_temp[ids[1]][i], hist_temp[ids[2]][i]), azi, 0, true), 0, alt, true);
                        Histogram[i] = V.x;
                    }
                }
                else
                {
                    Histogram = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency) + 4096];
                }

                if (Direct != null && Direct.IsOccluded(Rec_ID))
                {
                    int D_Start = 0;
                    if (!Start_at_Zero) D_Start = (int)Math.Ceiling(Direct.Time(Rec_ID) * Sampling_Frequency);

                    double[][] V = Direct.Dir_Pressure(Rec_ID, alt, azi, degrees, false);
                    for (int i = 0; i < V.Length; i++)
                    {
                        Histogram[D_Start + i] += V[i][0];
                    }
                }

                if (ISData != null)
                {
                    foreach (Deterministic_Reflection value in ISData.Paths[Rec_ID])
                    {
                        if (Math.Ceiling(Sampling_Frequency * value.TravelTime) < Histogram.Length - 1)
                        {
                            int R_Start = (int)Math.Ceiling(Sampling_Frequency * value.TravelTime);

                            double[] V = value.Dir_Pressure(Rec_ID, alt, azi, degrees, false, Sampling_Frequency);
                            for (int i = 0; i < value.Pressure.Length; i++)
                            {
                                Histogram[R_Start + i] += V[i];
                            }
                        }
                    }
                }
                return Histogram;
            }
 public void GetSims(ref Direct_Sound[] D, ref ImageSourceData[] IS, ref Receiver_Bank[] RT)
 {
     if (Direct_Data != null) D = Direct_Data;
     if (IS_Data != null) IS = IS_Data;
     if (Receiver != null) RT = Receiver;
 }
            public static double[][] ETCurve_1d(Direct_Sound Direct, ImageSourceData ISData, Receiver_Bank RTData, double CO_Time_ms, int Sampling_Frequency, int Octave, int Rec_ID, bool Start_at_Zero, double alt, double azi, bool degrees)
            {
                double[][] Histogram = new double[3][];
                    Histogram[0] = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency)];
                    Histogram[1] = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency)];
                    Histogram[2] = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency)];
                    if (RTData != null)
                    {
                        for (int i = 0; i < Histogram[0].Length; i++)
                        {
                            Hare.Geometry.Vector Vpos = RTData.Directions_Pos(Octave, i, Rec_ID, alt, azi, degrees);
                            Hare.Geometry.Vector Vneg = RTData.Directions_Neg(Octave, i, Rec_ID, alt, azi, degrees);

                            double E = RTData.Rec_List[Rec_ID].Energy(i, Octave);
                            Hare.Geometry.Vector VTot = new Hare.Geometry.Vector(Math.Abs(Vpos.x) - Math.Abs(Vneg.x), Math.Abs(Vpos.y) - Math.Abs(Vneg.y), Math.Abs(Vpos.z) - Math.Abs(Vneg.z));
                            VTot.Normalize();
                            VTot *= E;

                            Histogram[0][i] = VTot.x;
                            Histogram[1][i] = VTot.y;
                            Histogram[2][i] = VTot.z;
                        }
                    }

                    if (Direct != null && Direct.IsOccluded(Rec_ID))
                    {
                        int D_Start = 0;
                        if (!Start_at_Zero) D_Start = (int)Math.Ceiling(Direct.Time(Rec_ID) * Sampling_Frequency);

                        Hare.Geometry.Vector[] DirectValue;
                        switch (Octave)
                        {
                            case 8:
                                DirectValue = Direct.Dir_Energy_Sum(Rec_ID, alt, azi, degrees);
                                break;
                            default:
                                DirectValue = Direct.Dir_Energy(Octave, Rec_ID, alt, azi, degrees);
                                break;
                        }

                        for (int i = 0; i < DirectValue.Length; i++)
                        {
                            Histogram[0][D_Start + i] += Math.Abs(DirectValue[i].x);
                            Histogram[1][D_Start + i] += Math.Abs(DirectValue[i].y);
                            Histogram[2][D_Start + i] += Math.Abs(DirectValue[i].z);
                        }
                    }

                    if (ISData != null)
                    {
                        switch (Octave)
                        {
                            case 8:
                                foreach (Deterministic_Reflection value in ISData.Paths[Rec_ID])
                                {
                                    if (Math.Ceiling(Sampling_Frequency * value.TravelTime) < Histogram[0].Length - 1)
                                    {
                                        Hare.Geometry.Vector[] E_Sum = value.Dir_EnergySum(alt, azi, degrees);
                                        for (int i = 0; i < E_Sum.Length; i++)
                                        {
                                            Histogram[0][(int)Math.Ceiling(Sampling_Frequency * value.TravelTime + i / Sampling_Frequency)] += Math.Abs(E_Sum[i].x);
                                            Histogram[1][(int)Math.Ceiling(Sampling_Frequency * value.TravelTime + i / Sampling_Frequency)] += Math.Abs(E_Sum[i].y);
                                            Histogram[2][(int)Math.Ceiling(Sampling_Frequency * value.TravelTime + i / Sampling_Frequency)] += Math.Abs(E_Sum[i].z);
                                        }
                                    }
                                }
                                break;
                            default:
                                foreach (Deterministic_Reflection value in ISData.Paths[Rec_ID])
                                {
                                    if (Math.Ceiling(Sampling_Frequency * value.TravelTime) < Histogram[0].Length - 1)
                                    {
                                        Hare.Geometry.Vector[] E_Dir = value.Dir_Energy(Octave, alt, azi, degrees);
                                        for (int i = 0; i < E_Dir.Length; i++)
                                        {
                                            Histogram[0][(int)Math.Ceiling(Sampling_Frequency * value.TravelTime + i / Sampling_Frequency)] += Math.Abs(E_Dir[i].x);
                                            Histogram[1][(int)Math.Ceiling(Sampling_Frequency * value.TravelTime + i / Sampling_Frequency)] += Math.Abs(E_Dir[i].y);
                                            Histogram[2][(int)Math.Ceiling(Sampling_Frequency * value.TravelTime + i / Sampling_Frequency)] += Math.Abs(E_Dir[i].z);
                                        }
                                    }
                                }
                                break;
                        }
                    }
                    return Histogram;
            }
Exemplo n.º 24
0
            public void GetSims(ref Hare.Geometry.Point[] Src, ref Hare.Geometry.Point[] Rec, ref Direct_Sound[] D, ref ImageSourceData[] IS, ref Receiver_Bank[] RT)
            {
                Src = new Hare.Geometry.Point[Source.Length];
                for (int i = 0; i < Source.Length; i++) Src[i] = Source[i].H_Origin();
                Rec = Recs;

                if (Direct_Data != null) D = Direct_Data;
                if (IS_Data != null) IS = IS_Data;
                if (Receiver != null) RT = Receiver;
            }
            public static double[] ETCurve_Directional(Direct_Sound Direct, ImageSourceData ISData, Receiver_Bank RTData, double CO_Time_ms, int Sampling_Frequency, int Octave, int Rec_ID, bool Start_at_Zero, double alt, double azi, bool degrees)
            {
                double[] Histogram = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency)];
                    if (RTData != null)
                    {
                        for (int i = 0; i < Histogram.Length; i++)
                        {
                            Hare.Geometry.Vector Vpos = RTData.Directions_Pos(Octave, i, Rec_ID, alt, azi, degrees);
                            Hare.Geometry.Vector Vneg = RTData.Directions_Neg(Octave, i, Rec_ID, alt, azi, degrees);

                            double E = RTData.Rec_List[Rec_ID].Energy(i, Octave);
                            Hare.Geometry.Vector VTot = new Hare.Geometry.Vector(Math.Abs(Vpos.x) - Math.Abs(Vneg.x), Math.Abs(Vpos.y) - Math.Abs(Vneg.y), Math.Abs(Vpos.z) - Math.Abs(Vneg.z));

                            if (Vpos.x > 0)
                            {
                                Histogram[i] += Math.Abs(Vpos.x);
                            }
                            if (Vneg.x > 0)
                            {
                                Histogram[i] += Math.Abs(Vneg.x);
                            }

                            double L = VTot.Length();
                            if (L > 0) Histogram[i] *= E / L;

                            if (AcousticalMath.SPL_Intensity(Histogram[i]) > 200)
                            {
                                Rhino.RhinoApp.Write("Super high SPLs... what's going on, man?");
                            }
                        }
                    }

                    if (Direct != null && Direct.IsOccluded(Rec_ID))
                    {
                        int D_Start = 0;
                        if (!Start_at_Zero) D_Start = (int)Math.Ceiling(Direct.Time(Rec_ID) * Sampling_Frequency);

                        Hare.Geometry.Vector[] DirectValue;
                        switch (Octave)
                        {
                            case 8:
                                DirectValue = Direct.Dir_Energy_Sum(Rec_ID, alt, azi, degrees);
                                break;
                            default:
                                DirectValue = Direct.Dir_Energy(Octave, Rec_ID, alt, azi, degrees);
                                break;
                        }

                        for (int i = 0; i < DirectValue.Length; i++)
                        {
                            if (DirectValue[i].x > 0) Histogram[D_Start + i] += Math.Abs(DirectValue[i].x);
                        }
                    }

                    if (ISData != null)
                    {
                        switch (Octave)
                        {
                            case 8:
                                foreach (Deterministic_Reflection value in ISData.Paths[Rec_ID])
                                {
                                    if (Math.Ceiling(Sampling_Frequency * value.TravelTime) < Histogram.Length - 1)
                                    {
                                        Hare.Geometry.Vector[] E_Sum = value.Dir_EnergySum(alt, azi, degrees);
                                        for (int i = 0; i < E_Sum.Length; i++)
                                        {
                                            if (E_Sum[i].x > 0) Histogram[(int)Math.Ceiling(Sampling_Frequency * value.TravelTime + i)] += Math.Abs(E_Sum[i].x);
                                        }
                                    }
                                }
                                break;
                            default:
                                foreach (Deterministic_Reflection value in ISData.Paths[Rec_ID])
                                {
                                    if (Math.Ceiling(Sampling_Frequency * value.TravelTime) < Histogram.Length - 1)
                                    {
                                        Hare.Geometry.Vector[] E_Dir = value.Dir_Energy(Octave, alt, azi, degrees);
                                        for (int i = 0; i < E_Dir.Length; i++)
                                        {
                                            if (E_Dir[i].x > 0) Histogram[(int)Math.Ceiling(Sampling_Frequency * value.TravelTime + i)] += Math.Abs(E_Dir[i].x);
                                        }
                                    }
                                }
                                break;
                        }
                    }
                    return Histogram;
            }
            /// <summary>
            /// Approximation of the 5 second order ambisonics channels. (Fig8 3Axis and omni are the first four).
            /// </summary>
            /// <param name="Direct"></param>
            /// <param name="ISData"></param>
            /// <param name="RTData"></param>
            /// <param name="CO_Time"></param>
            /// <param name="Sampling_Frequency"></param>
            /// <param name="Rec_ID"></param>
            /// <param name="Start_at_Zero"></param>
            /// <param name="xpos_alt"></param>
            /// <param name="xpos_azi"></param>
            /// <param name="degrees"></param>
            /// <returns></returns>
            public static double[][] PTCurve_Ambisonics2(Direct_Sound Direct, ImageSourceData ISData, Receiver_Bank RTData, double CO_Time_ms, int Sampling_Frequency, int Rec_ID, bool Start_at_Zero, double xpos_alt, double xpos_azi, bool degrees)
            {
                double[][] Histogram = new double[5][];
                if (RTData != null)
                {
                    double[][] hist_temp = RTData.Pressure_3Axis(Rec_ID);
                    Histogram[0] = new double[hist_temp[0].Length];
                    Histogram[1] = new double[hist_temp[0].Length];
                    Histogram[2] = new double[hist_temp[0].Length];
                    Histogram[3] = new double[hist_temp[0].Length];
                    Histogram[4] = new double[hist_temp[0].Length];
                    for (int i = 0; i < hist_temp[0].Length; i++)
                    {
                        Hare.Geometry.Vector Vpos = PachTools.Rotate_Vector(PachTools.Rotate_Vector(new Hare.Geometry.Vector(hist_temp[0][i], hist_temp[2][i], hist_temp[4][i]), xpos_azi, 0, true), 0, xpos_alt, true);
                        Hare.Geometry.Vector Vneg = PachTools.Rotate_Vector(PachTools.Rotate_Vector(new Hare.Geometry.Vector(-hist_temp[1][i], -hist_temp[3][i], -hist_temp[5][i]), xpos_azi, 0, true), 0, xpos_alt, true);
                        double magpos = Math.Sqrt(Vpos.x * Vpos.x + Vpos.y * Vpos.y + Vpos.z * Vpos.z);
                        double magneg = Math.Sqrt(Vneg.x * Vneg.x + Vneg.y * Vneg.y + Vneg.z * Vneg.z);
                        double phipos = Math.Asin(Vpos.z / magpos);
                        double phineg = Math.Asin(Vneg.z / magneg);
                        double thetapos = Math.Asin(Vpos.y / magpos / Math.Cos(phipos));
                        double thetaneg = Math.Asin(Vneg.y / magneg / Math.Cos(phineg));
                        double rt3_2 = Math.Sqrt(3) / 2;

                        double sin2phpos = Math.Sin(2 * phipos);
                        double sin2phneg = Math.Sin(2 * phineg);
                        double cossqphpos = Math.Cos(phipos) * Math.Cos(phipos);
                        double cossqphneg = Math.Cos(phineg) * Math.Cos(phineg);

                        Histogram[0][i] = magpos * (3 * (Math.Sin(phipos) * Math.Sin(phipos) - 1) / 2 + magneg * 3 * Math.Sin(phineg) * Math.Sin(phineg) - 1) / 2;
                        Histogram[1][i] = rt3_2 * (Math.Cos(thetapos) * sin2phpos * magpos + Math.Cos(thetaneg) * sin2phneg * magneg);
                        Histogram[2][i] = rt3_2 * (Math.Sin(thetapos) * sin2phpos * magpos + Math.Sin(thetaneg) * sin2phneg * magneg);
                        Histogram[3][i] = rt3_2 * (Math.Cos(2 * thetapos) * cossqphpos * magpos + Math.Cos(2 * thetaneg) * cossqphneg * magneg);
                        Histogram[4][i] = rt3_2 * (Math.Sin(2 * thetapos) * cossqphpos * magpos + Math.Sin(2 * thetaneg) * cossqphneg * magneg);
                    }
                }
                else
                {
                    Histogram[0] = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency) + 4096];
                    Histogram[1] = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency) + 4096];
                    Histogram[2] = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency) + 4096];
                    Histogram[4] = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency) + 4096];
                    Histogram[5] = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency) + 4096];
                }

                if (Direct != null && Direct.IsOccluded(Rec_ID))
                {
                    int D_Start = 0;
                    if (!Start_at_Zero) D_Start = (int)Math.Ceiling(Direct.Time(Rec_ID) * Sampling_Frequency);

                    double[][] V = Direct.Dir_Pressure(Rec_ID, xpos_alt, xpos_azi, degrees, true);
                    for (int i = 0; i < V.Length; i++)
                    {
                        double mag = Math.Sqrt(V[i][0] * V[i][0] + V[i][1] * V[i][1] + V[i][2] * V[i][2]);
                        double phi = Math.Asin(V[i][2] / mag);
                        double theta = Math.Asin(V[i][1] / mag / Math.Cos(phi));
                        double rt3_2 = Math.Sqrt(3) / 2;

                        double sin2phi = Math.Sin(2 * phi);
                        double cossqphi = Math.Cos(phi) * Math.Cos(phi);

                        Histogram[0][i + D_Start] += mag * 3 * (Math.Sin(phi) * Math.Sin(phi) - 1) / 2;
                        Histogram[1][i + D_Start] += rt3_2 * Math.Cos(theta) * sin2phi * mag;
                        Histogram[2][i + D_Start] += rt3_2 * Math.Sin(theta) * sin2phi * mag;
                        Histogram[3][i + D_Start] += rt3_2 * Math.Cos(2 * theta) * cossqphi * mag;
                        Histogram[4][i + D_Start] += rt3_2 * Math.Sin(2 * theta) * cossqphi * mag;
                    }
                }

                if (ISData != null)
                {
                    foreach (Deterministic_Reflection value in ISData.Paths[Rec_ID])
                    {
                        if (Math.Ceiling(Sampling_Frequency * value.TravelTime) < Histogram[0].Length - 1)
                        {
                            int R_Start = (int)Math.Ceiling(Sampling_Frequency * value.TravelTime);

                            double[][] V = value.Dir_Pressure(Rec_ID, xpos_alt, xpos_azi, degrees, Sampling_Frequency);

                            Hare.Geometry.Vector dir = value.Path[0][value.Path[0].Length - 1] - value.Path[0][value.Path[0].Length - 2];
                            dir.Normalize();
                            for (int i = 0; i < V.Length; i++)
                            {
                                double mag = Math.Sqrt(V[i][0] * V[i][0] + V[i][1] * V[i][1] + V[i][2] * V[i][2]);
                                double phi = Math.Asin(V[i][2] / mag);
                                double theta = Math.Asin(V[i][1] / mag / Math.Cos(phi));
                                double rt3_2 = Math.Sqrt(3) / 2;

                                double sin2phi = Math.Sin(2 * phi);
                                double cossqphi = Math.Cos(phi) * Math.Cos(phi);

                                Histogram[0][i + R_Start] += mag * 3 * (Math.Sin(phi) * Math.Sin(phi) - 1) / 2;
                                Histogram[1][i + R_Start] += rt3_2 * Math.Cos(theta) * sin2phi * mag;
                                Histogram[2][i + R_Start] += rt3_2 * Math.Sin(theta) * sin2phi * mag;
                                Histogram[3][i + R_Start] += rt3_2 * Math.Cos(2 * theta) * cossqphi * mag;
                                Histogram[4][i + R_Start] += rt3_2 * Math.Sin(2 * theta) * cossqphi * mag;
                            }
                        }
                    }
                }
                return Histogram;
            }
 /// <summary>
 /// Used after a multithreaded calculation to combine thread-local results.
 /// </summary>
 /// <param name="Rec_in">Thread-local results to be combined with this receiver.</param>
 public override void Combine_Clones(Receiver_Bank Rec_in)
 {
     PachMapReceiver Rec = (PachMapReceiver)Rec_in;
     //if (Rec.Rec_List[0].Recs.Directions(8,0).z = -1)
     for (int R = 0; R < Rec.Count; R++)
     {
         for (int oct = 0; oct < 8; oct++)
         {
             for (int T = 0; T < Rec.Duration(); T++)
             {
                 Rec_List[R].Combine_Sample(T, Rec.Rec_List[R].Energy(T, oct), Rec.Rec_List[R].Directions_Pos(oct, T), Rec.Rec_List[R].Directions_Neg(oct, T), oct);
             }
         }
     }
 }