public WaveConduit(Pach_Graphics.colorscale C_in, double[] V_Bounds_in, Scene S) { min = Utilities.PachTools.HPttoRPt(S.Min()); Hare.Geometry.Vector range = S.Max() - S.Min(); nx = (int)System.Math.Ceiling(range.x); ny = (int)System.Math.Ceiling(range.y); nz = (int)System.Math.Ceiling(range.z); ptgrid = new List<int>[nx, ny, nz]; for (int x = 0; x < nx; x++) for (int y = 0; y < ny; y++) for (int z = 0; z < nz; z++) { ptgrid[x, y, z] = new List<int>(); } dx = range.x / nx; dy = range.y / ny; dz = range.z / nz; C = C_in; V_Bounds = V_Bounds_in; }
public WaveConduit(Pach_Graphics.colorscale C_in, double[] V_Bounds_in) { C = C_in; V_Bounds = V_Bounds_in; }
/// <summary> /// Allows user to change the colors of the particles. /// </summary> /// <param name="Colors"></param> /// <param name="Values"></param> public void SetColorScale(Pach_Graphics.colorscale C_in, double[] Values) { V_Bounds = Values; C = C_in; }
public static Mesh Get_EchoCritPercent_Map(PachMapReceiver[] Rec_List, double[] E_Bounds, Pach_Graphics.colorscale c, int Octave, List<int> SrcID, bool plotNumbers) { //T in ms. //Calculate C values... double[] E_Values = new double[Rec_List[0].Rec_List.Length]; bool Echo10, Echo50; double[] EKG, PercEcho; for (int i = 0; i < Rec_List[0].Rec_List.Length; i++) { double[] hist = null; //double E_Sum = 0; int zero = 0; double z = double.MaxValue; foreach (int S_ID in SrcID) { double t = (Rec_List[S_ID].Rec_List[i] as Map_Receiver).Direct_Time; if (z > t) z = t; } zero = (int)(z * Rec_List[0].SampleRate * 44.1); hist = new double[(int)Math.Ceiling(Rec_List[0].SampleCT * 44.1)]; foreach (int S_ID in SrcID) { double[] P; Rec_List[S_ID].GetPressure(i, out P); int arrival = (int)((Rec_List[S_ID].Rec_List[i] as Map_Receiver).Direct_Time * Rec_List[0].SampleRate) - zero; for (int j = 0; j < P.Length; j++) { int t = j + arrival; if (t >= hist.Length) break; hist[t] += P[j]; } } if (Octave < 8) hist = Audio.Pach_SP.FIR_Bandpass(hist, Octave, 44100, 0); AcousticalMath.EchoCriterion(hist, Rec_List[0].SampleRate, 0, true, out EKG, out PercEcho, out Echo10, out Echo50); E_Values[i] = PercEcho.Max(); } //Set each SPL value to a color on a color scale... double Scale_Breadth = E_Bounds[1] - E_Bounds[0]; if (plotNumbers) { int step = (int)Math.Ceiling((double)Rec_List[0].Rec_List.Length / 100); for (int i = 0; i < Rec_List[0].Rec_List.Length; i += step) { Plane P = Plane.WorldXY; P.Origin = Utilities.PachTools.HPttoRPt(Rec_List[0].Rec_List[i].H_Origin); Rhino.RhinoDoc.ActiveDoc.Objects.AddText(((int)E_Values[i]).ToString(), P, Rec_List[0].Rec_List[0].Radius, "Arial", true, false); } return null; } else { return PlotMesh(Rec_List, SetColors(E_Values, E_Bounds, c)); } }
/// <summary> /// Creates a map of the Reverberation Time in the room. /// </summary> /// <param name="STI_Bounds"></param> /// <param name="H_OFFSET">H value offset (HSV Color system.)</param> /// <param name="H_BREADTH">H value breadth (HSV Color system.)</param> /// <param name="S_OFFSET">S value offset (HSV Color system.)</param> /// <param name="S_BREADTH">S value breadth (HSV Color system.)</param> /// <param name="V_OFFSET">V value offset (HSV Color system.)</param> /// <param name="V_BREADTH">V value breadth (HSV Color system.)</param> /// <param name="Octave">The octave band to plot...</param> /// <returns>On Mesh with color assignments matching the input parameters and output variables.</returns> public static Mesh Get_RT_Map(PachMapReceiver[] Rec_List, double[] RT_Bounds, Pach_Graphics.colorscale c, int Decay_Depth, int Octave, List<int> SrcID, bool Coherent_Superposition, bool plotNumbers) { //T in ms. //Calculate T-X values... double[] RT_Values = new double[Rec_List[0].Rec_List.Length]; if (Coherent_Superposition) { for (int i = 0; i < Rec_List[0].Rec_List.Length; i++) { double[] hist = new double[(int)Math.Ceiling(Rec_List[0].SampleCT * 44.1)]; int zero = 0; double z = double.MaxValue; foreach (int S_ID in SrcID) { double t = (Rec_List[S_ID].Rec_List[i] as Map_Receiver).Direct_Time; if (z > t) z = t; } zero = (int)Math.Floor(z * Rec_List[0].SampleRate * 44.1); foreach (int S_ID in SrcID) { double[] P; Rec_List[S_ID].GetPressure(i, out P); int arrival = (int)Math.Floor((Rec_List[S_ID].Rec_List[i] as Map_Receiver).Direct_Time * Rec_List[0].SampleRate * 44.1) - zero; for (int j = 0; j < P.Length; j++) { int t = j + arrival; if (t >= hist.Length) break; hist[t] += P[j]; } } if (Octave < 8) hist = Audio.Pach_SP.FIR_Bandpass(hist, Octave, 44100, 0); for (int t = 0; t < hist.Length; t++) hist[t] *= hist[t]; double[] SI = AcousticalMath.Schroeder_Integral(hist); RT_Values[i] = AcousticalMath.T_X(SI, Decay_Depth, Rec_List[0].SampleRate); } } else { for (int i = 0; i < Rec_List[0].Rec_List.Length; i++) { double[] SI = AcousticalMath.Schroeder_Integral(AcousticalMath.ETCurve(null, null, Rec_List, Rec_List[0].CutOffTime, Rec_List[0].SampleRate, Octave, i, SrcID, true)); RT_Values[i] = AcousticalMath.T_X(SI, Decay_Depth, Rec_List[0].SampleRate); } } if (plotNumbers) { int step = (int)Math.Ceiling((double)Rec_List[0].Rec_List.Length / 100); for (int i = 0; i < Rec_List[0].Rec_List.Length; i += step) { Plane P = Plane.WorldXY; P.Origin = Utilities.PachTools.HPttoRPt(Rec_List[0].Rec_List[i].H_Origin); Rhino.RhinoDoc.ActiveDoc.Objects.AddText(((int)RT_Values[i]).ToString(), P, Rec_List[0].Rec_List[0].Radius, "Arial", true, false); } return null; } else { return PlotMesh(Rec_List, SetColors(RT_Values, RT_Bounds, c)); } }
/// <summary> /// Assigns colors to parameter values on a Rhinoceros mesh. /// </summary> /// <param name="Values">The values of the data points</param> /// <param name="Bounds">Parameter bounds</param> /// <param name="H_OFFSET">H value offset (HSV Color system.)</param> /// <param name="H_BREADTH">H value breadth (HSV Color system.)</param> /// <param name="S_OFFSET">S value offset (HSV Color system.)</param> /// <param name="S_BREADTH">S value breadth (HSV Color system.)</param> /// <param name="V_OFFSET">V value offset (HSV Color system.)</param> /// <param name="V_BREADTH">V value breadth (HSV Color system.)</param> /// <returns>the array of color assignments which fit neatly into the mesh </returns> public static System.Drawing.Color[] SetColors(double[] Values, double[] Bounds, Pach_Graphics.colorscale c) { System.Drawing.Color[] Mesh_Colors = new System.Drawing.Color[Values.Length]; double Scale_Breadth = Bounds[1] - Bounds[0]; for (int i = 0; i < Values.Length; i++) { System.Drawing.Color color = c.GetValue(Values[i], Bounds[0], Bounds[1]); Mesh_Colors[i] = color; } return Mesh_Colors; }
/// <summary> /// Create an integrated sound pressure level map based on the receiver positions extracted from the audience map surfaces. /// </summary> /// <param name="SPL_Bounds">The boundaries of SPL domain to be used.</param> /// <param name="T_Bounds">The boundaries of time domain to be used.</param> /// <param name="c">The Color Scale.</param> /// <param name="Octave">The octave band to plot...</param> /// <param name="SrcID">The IDs of the sources.</param> /// <returns>On Mesh with color assignments matching the input parameters and output variables.</returns> public static Mesh Get_SPLA_Map(PachMapReceiver[] Rec_List, double[] SPL_Bounds, double[] T_Bounds, Pach_Graphics.colorscale c, List<int> SrcID, bool Coherent_Superposition, bool plotNumbers) { //T in ms. //Calculate SPL values... int T_Max = (int)Math.Min(Rec_List[SrcID[0]].SampleCT, Math.Floor((T_Bounds[0]))); int T_Min = (int)Math.Floor((T_Bounds[1])); double[] SPL_Values = new double[Rec_List[0].Rec_List.Length]; Mesh MM = Rec_List[0].MapMesh(); double[] AFactors = new double[8] { Math.Pow(10, (-26.2 / 10)), Math.Pow(10, (-16.1 / 10)), Math.Pow(10, (-8.6 / 10)), Math.Pow(10, (-3.2 / 10)), 1, Math.Pow(10, (1.2 / 10)), Math.Pow(10, (1 / 10)), Math.Pow(10, (-1.1 / 10)) }; for (int i = 0; i < Rec_List[0].Rec_List.Length; i++) { if (Coherent_Superposition) { double[] hist = new double[(int)Math.Ceiling(Rec_List[0].SampleCT * 44.1)]; foreach (int S_ID in SrcID) { double[] P; Rec_List[S_ID].GetPressure(i, out P); int arrival = (int)Math.Floor((Rec_List[S_ID].Rec_List[i] as Map_Receiver).Direct_Time * Rec_List[0].SampleRate * 44.1); for (int j = 0; j < P.Length; j++) { int t = j + arrival; if (t >= hist.Length) break; hist[t] += P[j]; } } double[] histtemp; double histtotal = 0; for (int oct = 0; oct < 8; oct++) { histtemp = Audio.Pach_SP.FIR_Bandpass(hist, oct, 44100, 0); for (int j = 0; j < histtemp.Length; j++) histtotal += histtemp[j] * AFactors[oct]; } SPL_Values[i] = 10 * Math.Log10(histtotal / 1E-12); } else { double E_Sum = 0; foreach (int S_ID in SrcID) { for (int oct = 0; oct < 8; oct++) { double E_oct_Sum = 0; double[] hist = Rec_List[S_ID].GetEnergyHistogram(oct, i); for (int t = T_Min; t < T_Max; t++) { E_oct_Sum += hist[t]; } E_Sum += E_oct_Sum * AFactors[oct]; } } if (E_Sum < 0) { Rhino.RhinoApp.Write("MEEP"); } SPL_Values[i] = AcousticalMath.SPL_Intensity(Math.Abs(E_Sum)); } } if (plotNumbers) { int step = (int)Math.Ceiling((double)Rec_List[0].Rec_List.Length / 100); for (int i = 0; i < Rec_List[0].Rec_List.Length; i += step) { Plane P = Plane.WorldXY; P.Origin = Utilities.PachTools.HPttoRPt(Rec_List[0].Rec_List[i].H_Origin); Rhino.RhinoDoc.ActiveDoc.Objects.AddText(((int)SPL_Values[i]).ToString(), P, Rec_List[0].Rec_List[0].Radius, "Arial", true, false); } return null; } else { return PlotMesh(Rec_List, SetColors(SPL_Values, SPL_Bounds, c)); } }
/// <summary> /// Create an integrated sound pressure level map based on the receiver positions extracted from the audience map surfaces. /// </summary> /// <param name="SPL_Bounds">The boundaries of SPL domain to be used.</param> /// <param name="T_Bounds">The boundaries of time domain to be used.</param> /// <param name="c">The Color Scale.</param> /// <param name="Octave">The octave band to plot...</param> /// <param name="SrcID">The IDs of the sources.</param> /// <returns>On Mesh with color assignments matching the input parameters and output variables.</returns> public static Mesh Get_SPL_Map(PachMapReceiver[] Rec_List, double[] SPL_Bounds, double[] T_Bounds, Pach_Graphics.colorscale c, int Octave, List<int> SrcID, bool Coherent_Superposition, bool ZeroAtDirect, bool plotNumbers) { //T in ms. //Calculate SPL values... double[] SPL_Values = new double[Rec_List[0].Rec_List.Length]; Mesh MM = Rec_List[0].MapMesh(); for (int i = 0; i < Rec_List[0].Rec_List.Length; i++) { double[] hist; if (Coherent_Superposition) { hist = new double[(int)Math.Ceiling(Rec_List[0].SampleCT * 44.1)]; double E_Sum = 0; int T_Max = (int)Math.Floor((T_Bounds[0]) * 44.1); int T_Min = (int)Math.Floor((T_Bounds[1]) * 44.1); int zero = 0; if (ZeroAtDirect) { double z = double.MaxValue; foreach (int S_ID in SrcID) { double t = (Rec_List[S_ID].Rec_List[i] as Map_Receiver).Direct_Time; if (z > t) z = t; } zero = (int)Math.Floor(z * Rec_List[0].SampleRate * 44.1); } foreach (int S_ID in SrcID) { double[] P; Rec_List[S_ID].GetPressure(i, out P); int arrival = (int)Math.Floor((Rec_List[S_ID].Rec_List[i] as Map_Receiver).Direct_Time * Rec_List[0].SampleRate * 44.1) - zero; for (int j = 0; j < P.Length; j++) { int t = j + arrival; if (t >= hist.Length) break; hist[t] += P[j]; } } if (Octave < 8) { hist = Audio.Pach_SP.FIR_Bandpass(hist, Octave, 44100, 0); } else { double[] histtemp; double[] histtotal = new double[hist.Length]; for(int oct = 0; oct < 8; oct++) { histtemp = Audio.Pach_SP.FIR_Bandpass(hist, oct, 44100, 0); for (int j = 0; j < histtemp.Length; j++) histtotal[j] += histtemp[j]; } hist = histtotal; } for (int t = T_Min; t < T_Max; t++) { if (t >= hist.Length) break; E_Sum += hist[t] * hist[t]; } E_Sum /= Rec_List[0].Rec_List[i].Rho_C; SPL_Values[i] = 10 * Math.Log10(E_Sum / 1E-12); } else { hist = new double[Rec_List[0].SampleCT]; double E_Sum = 0; double[] temp; int T_Max = (int)Math.Floor(T_Bounds[0]); int T_Min = (int)Math.Floor(T_Bounds[1]); int zero = 0; if (ZeroAtDirect) { double z = double.MaxValue; foreach (int S_ID in SrcID) { double t = (Rec_List[S_ID].Rec_List[i] as Map_Receiver).Direct_Time; if (z > t) z = t; } zero = (int)(z * Rec_List[0].SampleRate); } foreach (int S_ID in SrcID) { temp = Rec_List[S_ID].GetEnergyHistogram(Octave, i); int arrival = (int)((Rec_List[S_ID].Rec_List[i] as Map_Receiver).Direct_Time * Rec_List[0].SampleRate) - zero; for (int j = 0; j < temp.Length; j++) { int t = j + arrival; if (t >= hist.Length) break; hist[t] += temp[j]; } } for (int t = T_Min; t < T_Max; t++) { if (t >= hist.Length) break; E_Sum += hist[t]; } SPL_Values[i] = AcousticalMath.SPL_Intensity(E_Sum); } } if (plotNumbers) { int step = (int)Math.Ceiling((double)Rec_List[0].Rec_List.Length / 100); for (int i = 0; i < Rec_List[0].Rec_List.Length; i += step) { Plane P = Plane.WorldXY; P.Origin = Utilities.PachTools.HPttoRPt(Rec_List[0].Rec_List[i].H_Origin); Rhino.RhinoDoc.ActiveDoc.Objects.AddText(((int)SPL_Values[i]).ToString(), P, Rec_List[0].Rec_List[0].Radius, "Arial", true, false); } return null; } else { return PlotMesh(Rec_List, SetColors(SPL_Values, SPL_Bounds, c)); } }
/// <summary> /// Creates a strength map /// </summary> /// <param name="G_Bounds"></param> /// <param name="Ref_Hist"></param> /// <param name="H_OFFSET">H value offset (HSV Color system.)</param> /// <param name="H_BREADTH">H value breadth (HSV Color system.)</param> /// <param name="S_OFFSET">S value offset (HSV Color system.)</param> /// <param name="S_BREADTH">S value breadth (HSV Color system.)</param> /// <param name="V_OFFSET">V value offset (HSV Color system.)</param> /// <param name="V_BREADTH">V value breadth (HSV Color system.)</param> /// <param name="Octave">The octave band to plot...</param> /// <returns>On Mesh with color assignments matching the input parameters and output variables.</returns> public static Mesh Get_G_Map(PachMapReceiver[] Rec_List, double[] G_Bounds, Pach_Graphics.colorscale c, int Octave, double SWL, int SrcID, bool Coherent_Superposition, bool plotNumbers) { //T in ms. //Calculate C values... double[] G_Values = new double[Rec_List[0].Rec_List.Length]; if (Coherent_Superposition) { for (int i = 0; i < Rec_List[0].Rec_List.Length; i++) { double[] hist = new double[(int)Math.Ceiling(Rec_List[0].SampleCT * 44.1)]; int zero = 0; double z = double.MaxValue; //foreach (int S_ID in SrcID) //{ double t = (Rec_List[SrcID].Rec_List[i] as Map_Receiver).Direct_Time; if (z > t) z = t; //} zero = (int)Math.Floor(z * Rec_List[0].SampleRate * 44.1); //} //foreach (int S_ID in SrcID) //{ double[] P; Rec_List[SrcID].GetPressure(i, out P); int arrival = (int)Math.Floor((Rec_List[SrcID].Rec_List[i] as Map_Receiver).Direct_Time * Rec_List[0].SampleRate * 44.1) - zero; for (int j = 0; j < P.Length; j++) { int ti = j + arrival; if (ti >= hist.Length) break; hist[ti] += P[j]; } //} if (Octave < 8) hist = Audio.Pach_SP.FIR_Bandpass(hist, Octave, 44100, 0); for (int j = 0; j < hist.Length; j++) hist[j] *= hist[j]; G_Values[i] = AcousticalMath.Strength(hist, SWL, Coherent_Superposition); } } else { for (int i = 0; i < Rec_List[0].Rec_List.Length; i++) { G_Values[i] = AcousticalMath.Strength(Rec_List[SrcID].Rec_List[i].GetEnergyHistogram(Octave), SWL, Coherent_Superposition); } } if (plotNumbers) { int step = (int)Math.Ceiling((double)Rec_List[0].Rec_List.Length / 100); for (int i = 0; i < Rec_List[0].Rec_List.Length; i += step) { Plane P = Plane.WorldXY; P.Origin = Utilities.PachTools.HPttoRPt(Rec_List[0].Rec_List[i].H_Origin); Rhino.RhinoDoc.ActiveDoc.Objects.AddText(((int)G_Values[i]).ToString(), P, Rec_List[0].Rec_List[0].Radius, "Arial", true, false); } return null; } else { return PlotMesh(Rec_List, SetColors(G_Values, G_Bounds, c)); } }
/// <summary> /// Creates a map of the Speech Transmission Index in the room. /// </summary> /// <param name="Rec_List"></param> /// <param name="STI_Bounds"></param> /// <param name="c"></param> /// <param name="NoiseSPL"></param> /// <param name="SrcID"></param> /// <param name="type"> 0 for 2003 general, 1 for Male, 2 for Female</param> /// <returns>On Mesh with color assignments matching the input parameters and output variables.</returns> public static Mesh Get_STI_Map(PachMapReceiver[] Rec_List, double[] STI_Bounds, Pach_Graphics.colorscale c, double[] NoiseSPL, List<int> SrcID, int type, bool Coherent_Superposition, bool plotNumbers) { if (type < 0 || type > 2) return Rec_List[0].Map_Mesh; double[] STI_Values = new double[Rec_List[0].Rec_List.Length]; if (Coherent_Superposition) { System.Threading.Tasks.Parallel.For(0, Rec_List[0].Rec_List.Length, i => { double[] hist = new double[(int)Math.Ceiling(Rec_List[0].SampleCT * 44.1)]; int zero = 0; double z = double.MaxValue; foreach (int S_ID in SrcID) { double t = (Rec_List[S_ID].Rec_List[i] as Map_Receiver).Direct_Time; if (z > t) z = t; } zero = (int)Math.Floor(z * Rec_List[0].SampleRate * 44.1); foreach (int S_ID in SrcID) { double[] P; Rec_List[S_ID].GetPressure(i, out P); int arrival = (int)Math.Floor((Rec_List[S_ID].Rec_List[i] as Map_Receiver).Direct_Time * Rec_List[0].SampleRate * 44.1) - zero; for (int j = 0; j < P.Length; j++) { int t = j + arrival; if (t >= hist.Length) break; hist[t] += P[j]; } } double[][] ETC = new double[8][]; for (int oct = 0; oct < 8; oct++) { double[] h = Audio.Pach_SP.FIR_Bandpass(hist, oct, 44100, 0); for (int t = 0; t < hist.Length; t++) ETC[oct][t] = h[t] * h[t] / Rec_List[0].Rec_List[i].Rho_C; } STI_Values[i] = AcousticalMath.Speech_Transmission_Index(ETC, 1.2 * 343, NoiseSPL, Rec_List[0].SampleRate)[type]; }); } else { System.Threading.Tasks.Parallel.For(0, Rec_List[0].Rec_List.Length, i => { double[][] ETC = new double[8][]; for (int oct = 0; oct < 8; oct++) ETC[oct] = AcousticalMath.ETCurve(null, null, Rec_List, Rec_List[0].CutOffTime, Rec_List[0].SampleRate, oct, i, SrcID, true); STI_Values[i] = AcousticalMath.Speech_Transmission_Index(ETC, 1.2 * 343, NoiseSPL, Rec_List[0].SampleRate)[type]; }); } if (plotNumbers) { int step = (int)Math.Ceiling((double)Rec_List[0].Rec_List.Length / 100); for (int i = 0; i < Rec_List[0].Rec_List.Length; i += step) { Plane P = Plane.WorldXY; P.Origin = Utilities.PachTools.HPttoRPt(Rec_List[0].Rec_List[i].H_Origin); Rhino.RhinoDoc.ActiveDoc.Objects.AddText(((int)STI_Values[i]).ToString(), P, Rec_List[0].Rec_List[0].Radius, "Arial", true, false); } return null; } else { return PlotMesh(Rec_List, SetColors(STI_Values, STI_Bounds, c)); } }