public static List <TraceInfo> GetTraceInfo(double freq, double phase, double amplitude, Point3D targetPoint, List <ProcessorTrace> traces) { var w = freq * 2.0 * Math.PI; var result = new List <TraceInfo>(); foreach (var trace in traces) { if (trace.Parts.Count == 0) { continue; } var amp = amplitude; var ph = phase; var traceLength = 0.0; ProcessorTracePart prevPart = null; foreach (var tracePart in trace.Parts) { if (prevPart != null) { if (tracePart.ReflectionLayer == null) { // z1 = p1c1/cos(b) // z0 = p0c0/cos(a) //w = 2z1/(z1+z0) var z1 = tracePart.Layer.Impedance / Math.Cos(tracePart.Angle); var z0 = prevPart.Layer.Impedance / Math.Cos(prevPart.Angle); amp *= z1 * 2 / (z1 + z0); } else { var l0 = tracePart.Layer; var l1 = tracePart.ReflectionLayer; var a = tracePart.Angle; //z0 = p0c0/cos(a) //z1 = p1c1/cos(b) //v = (z1-z0)/(z1+z0) //b = asin(sina * c2/c1) var z0 = l0.Impedance / Math.Cos(a); var z1 = l1.Impedance / Math.Cos(Math.Asin(Math.Sin(a) * l0.WaveSpeed / l1.WaveSpeed)); amp *= (z1 - z0) / (z1 + z0); // phase shift if (l1.Impedance < l0.Impedance) { ph += Math.PI; } } } traceLength += tracePart.Length; amp *= Math.Exp(-tracePart.Length * tracePart.Layer.GetAttenuationFactor(freq)); ph += w * tracePart.Length / tracePart.Layer.WaveSpeed; prevPart = tracePart; } // ok result.Add(new TraceInfo { Trace = trace, AngularFrequency = w, Amplitude = amp / traceLength, PhaseBase = ph }); } return(result); }
public static double GetValue(double freq, double impulseTime, double phase, double amplitude, double time, double delay, Point3D targetPoint, List <ProcessorTrace> traces) { var sum = 0d; var travelTime = time - delay; if (travelTime <= 0) { return(sum); } var w = freq * 2.0 * Math.PI; foreach (var trace in traces) { if (trace.Parts.Count == 0) { continue; } if (travelTime < trace.TimeToPoint) { continue; } if (travelTime > trace.TimeToPoint + impulseTime) { continue; } var amp = amplitude; var ph = phase + w * travelTime; var traceLength = 0.0; ProcessorTracePart prevPart = null; foreach (var tracePart in trace.Parts) { if (prevPart != null) { if (tracePart.ReflectionLayer == null) { // z1 = p1c1/cos(b) // z0 = p0c0/cos(a) //w = 2z1/(z1+z0) var z1 = tracePart.Layer.Impedance / Math.Cos(tracePart.Angle); var z0 = prevPart.Layer.Impedance / Math.Cos(prevPart.Angle); amp *= z1 * 2 / (z1 + z0); } else { var l0 = tracePart.Layer; var l1 = tracePart.ReflectionLayer; var a = tracePart.Angle; //z0 = p0c0/cos(a) //z1 = p1c1/cos(b) //v = (z1-z0)/(z1+z0) //b = asin(sina * c2/c1) var z0 = l0.Impedance / Math.Cos(a); var z1 = l1.Impedance / Math.Cos(Math.Asin(Math.Sin(a) * l0.WaveSpeed / l1.WaveSpeed)); amp *= (z1 - z0) / (z1 + z0); // phase shift if (l1.Impedance < l0.Impedance) { ph += Math.PI; } } } traceLength += tracePart.Length; amp *= Math.Exp(-tracePart.Length * tracePart.Layer.GetAttenuationFactor(freq)); ph += w * tracePart.Length / tracePart.Layer.WaveSpeed; prevPart = tracePart; } // ok sum += amp / traceLength * Math.Sin(ph); } return(sum); }
public ProcessorTraceResult BuildTraces(IList <ProcessorLayerEx> layers, Point3D fromPoint, Point3D targetPoint) { var result = new ProcessorTrace { Parts = new List <ProcessorTracePart>() }; var x = targetPoint.X; var layer0 = layers[0]; var toPoint = Point3D.Subtract(targetPoint, fromPoint); var z = toPoint.Z; var y = toPoint.Y; var initialH = Math.Sqrt(z * z + y * y); var angleToPoint = Math.Atan2(initialH, toPoint.X); ProcessorLayerEx pointLayer; Int32 pointLayerIndex; if (x <= layer0.Thickness) { var trace = new ProcessorTracePart { Angle = angleToPoint, Length = toPoint.Length, Layer = layer0, Vector = toPoint }; result.Parts.Add(trace); pointLayer = layer0; pointLayerIndex = 0; } else { var vars = new List <ProcessorSolverVars> { new ProcessorSolverVars { C = 1, H = layer0.Thickness - fromPoint.X, Layer = layer0 } }; var currentPos = layer0.Thickness; var i = 0; while (++i < layers.Count - 1) { var layer = layers[i]; var h = layer.Thickness; var tmpPos = currentPos + h; if (tmpPos >= targetPoint.X) { break; } currentPos = tmpPos; vars.Add(new ProcessorSolverVars { C = layer.RatioToLayer0, H = h, Layer = layer, PrevLayer = layers[i - 1] }); } pointLayer = layers[i]; pointLayerIndex = i; vars.Add(new ProcessorSolverVars { C = pointLayer.RatioToLayer0, H = targetPoint.X - currentPos, Layer = pointLayer, PrevLayer = layers[i - 1] }); var alpha = Solve(vars, angleToPoint, initialH); if (alpha.HasValue) { var angle = alpha.Value; var h = vars[0].H; var length = h / Math.Cos(angle); var dn = new Vector3D(0, toPoint.Y, toPoint.Z); dn.Normalize(); dn = Vector3D.Multiply(h * Math.Tan(angle), dn); var toFirstBorder = Vector3D.Add(new Vector3D(h, 0, 0), dn); var trace = new ProcessorTracePart { Angle = angle, Length = length, Layer = layer0, Vector = toFirstBorder }; result.Parts.Add(trace); var sin1 = Math.Sin(angle); foreach (var arg in vars.Skip(1)) { var v = sin1 * arg.C; angle = Math.Asin(v); trace = new ProcessorTracePart { Angle = angle, Length = arg.H / Math.Cos(angle), Layer = arg.Layer, PrevLayer = arg.PrevLayer, //Vector = TODO !!! }; result.Parts.Add(trace); } } else { Log.Error("iterations max count reached for point " + targetPoint + " radiant " + fromPoint); } } var output = new ProcessorTraceResult { PointLayer = pointLayer, Traces = new List <ProcessorTrace>(1) { result } }; if (_reflectionDepth > 0) { //calc reflections if (pointLayerIndex != layers.Count - 1) { for (var reflectionLayerIndex = pointLayerIndex + 1; reflectionLayerIndex < layers.Count; reflectionLayerIndex++) { result = new ProcessorTrace { Parts = new List <ProcessorTracePart>() }; var reflectionLayer = layers[reflectionLayerIndex]; var vars = new List <ProcessorSolverVars>(); vars.Add(new ProcessorSolverVars { C = 1, H = layer0.Thickness - fromPoint.X, Layer = layer0 }); for (int j = 1; j < reflectionLayerIndex; j++) { var layer = layers[j]; vars.Add(new ProcessorSolverVars { C = layer.RatioToLayer0, H = layer.Thickness, Layer = layer, PrevLayer = layers[j - 1] }); } var refVarIndex = vars.Count; for (int j = reflectionLayerIndex - 1; j > pointLayerIndex; j--) { var layer = layers[j]; vars.Add(new ProcessorSolverVars { C = layer.RatioToLayer0, H = layer.Thickness, Layer = layer, PrevLayer = layers[j + 1] }); } vars.Add(new ProcessorSolverVars { C = pointLayer.RatioToLayer0, H = pointLayer.ThicknessAfter - targetPoint.X, Layer = pointLayer, PrevLayer = layers[pointLayerIndex + 1] }); var refVar = vars[refVarIndex]; refVar.PrevLayer = refVar.Layer; refVar.ReflectionLayer = reflectionLayer; var alpha = Solve(vars, angleToPoint, initialH); if (alpha.HasValue) { var angle = alpha.Value; var h = vars[0].H; var length = h / Math.Cos(angle); var dn = new Vector3D(0, toPoint.Y, toPoint.Z); dn.Normalize(); dn = Vector3D.Multiply(h * Math.Tan(angle), dn); var toFirstBorder = Vector3D.Add(new Vector3D(h, 0, 0), dn); var trace = new ProcessorTracePart { Angle = angle, Length = length, Layer = layer0, Vector = toFirstBorder }; result.Parts.Add(trace); var sin1 = Math.Sin(angle); foreach (var arg in vars.Skip(1)) { var v = sin1 * arg.C; angle = Math.Asin(v); trace = new ProcessorTracePart { Angle = angle, Length = arg.H / Math.Cos(angle), Layer = arg.Layer, PrevLayer = arg.PrevLayer, ReflectionLayer = arg.ReflectionLayer, //Vector = TODO }; result.Parts.Add(trace); } output.Traces.Add(result); } else { Log.Error("iterations max count reached for point " + targetPoint + " radiant " + fromPoint); } } } } foreach (var trace in output.Traces) { trace.TimeToPoint = trace.Parts.Sum(item => item.Length / item.Layer.WaveSpeed); } return(output); }