/// <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); } }
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; } } }
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; }
/// <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]); } }
/// <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; }
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) { }
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); } } } }
/// <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; } }
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; }
/// <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; }
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); } } } }