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; }
/// <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; }
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; }