using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; using System.Xml.Schema; namespace Shaker.Models.Tools { public static class Tools { public static void CalcSlope(double[] x, double[] y,ref double k,ref double b) { if(x ==null || y==null || x.Length!=2||y.Length!=2) { k = 0; b = 0; return; } k = (y[1] - y[0]) / (x[1] - x[0]); b = y[0] - x[0] * k; } public static int FindFrequencyIndex(this SweepConfigModel model, double freq) { if (model.SweepItems.Count < 2) return -1; uint uintfreq = (uint)(freq * 100); for (int i = 0; i < model.SweepItems.Count - 1; i++) { if ((uint)(model.SweepItems[i].Frequency * 100) <= uintfreq && uintfreq <= (uint)(model.SweepItems[i + 1].Frequency * 100)) return i; } return model.SweepItems.Count - 1; } public static void CalcAmpt(this SweepConfigModel model, double freq,ref double value,ref double upstop,ref double upwarn,ref double downstop,ref double downwarn) { int index = model.FindFrequencyIndex(freq); if (index == -1) return; value = 0; SweepItemModel nowmodel = model.SweepItems[index]; switch (nowmodel.SweepValueType) { case SweepValueType.FixedDisplacement: value = freq * nowmodel.Value * freq * 4 * Math.PI * Math.PI / 9800f; break; case SweepValueType.FixedVelocity: value = freq * 2 * Math.PI * nowmodel.Value / 9.8f; break; case SweepValueType.FixedAcceleration: value = nowmodel.Value; break; case SweepValueType.DynamicAcceleration: { if (index == model.SweepItems.Count - 1) { value = nowmodel.Value; } else { SweepItemModel nextmodel = model.SweepItems[index + 1]; double k = 0; double b = 0; Tools.CalcSlope([Math.Log10(nowmodel.Frequency), Math.Log10(nextmodel.Frequency)], [Math.Log10(nowmodel.Value), Math.Log10(nextmodel.Value)], ref k, ref b); value = Math.Pow(10, k * Math.Log10(freq) + b); } } break; } upstop = Math.Pow(10, nowmodel.UpStop / 20) * value; upwarn = Math.Pow(10, nowmodel.UpWarn / 20) * value; downstop = Math.Pow(10, nowmodel.DownStop / 20) * value; downwarn = Math.Pow(10, nowmodel.DownWarn / 20) * value; } public static double CalcAmpt(this SweepConfigModel model, double freq) { int index = model.FindFrequencyIndex(freq); if (index == -1) return 0; double value = 0; SweepItemModel nowmodel = model.SweepItems[index]; switch (nowmodel.SweepValueType) { case SweepValueType.FixedDisplacement: value = freq * nowmodel.Value * freq * 4 * MathF.PI*MathF.PI / 9800f; break; case SweepValueType.FixedVelocity: value = freq * 2 * MathF.PI * nowmodel.Value / 9.8f; break; case SweepValueType.FixedAcceleration: value = nowmodel.Value; break; case SweepValueType.DynamicAcceleration: { if (index == model.SweepItems.Count - 1) { value = nowmodel.Value; } else { SweepItemModel nextmodel = model.SweepItems[index + 1]; double k = 0; double b = 0; Tools.CalcSlope(new double[] { Math.Log10(nowmodel.Frequency), Math.Log10(nextmodel.Frequency) }, new double[] { Math.Log10(nowmodel.Value), Math.Log10(nextmodel.Value) }, ref k, ref b); value = Math.Pow(10, k * Math.Log10(freq) + b); } } break; } return value; } public static double TimeToOCT(this SweepConfigModel model, double time) { double oct = 0; switch(model.SweepType) { case SweepType.Linear: oct = (model.EndFrequency - model.StartFrequency) / time * 60; break; case SweepType.Log: default: oct = Math.Log2(model.EndFrequency / model.StartFrequency) / time * 60; break; } return oct; } public static double OCTToTime(this SweepConfigModel model, double oct) { double time = 0; switch(model.SweepType) { case SweepType.Linear: time = (model.EndFrequency - model.StartFrequency) / oct * 60; break; case SweepType.Log: default: time = Math.Log2(model.EndFrequency / model.StartFrequency) / oct * 60; break; } return time; } public static double DisplacementToVelocity(double displacement, double freq) { return displacement * 2 * Math.PI * freq / 1000; } public static double DisplacementToAcceleration(double displacement, double freq) { return displacement * 2 * Math.PI * freq * 2*Math.PI*freq / 9800; } public static double VelocityToAcceleration(double velocity, double freq) { return velocity * 2 * Math.PI * freq / 9.8; } public static double VelocityToDisplacement(double velocity, double freq) { return velocity * 1000 / (2 * Math.PI * freq); } public static double AccelerationToDisplacement(double acceleration, double freq) { return acceleration * 9800 / (2 * Math.PI * freq * 2 * Math.PI * freq); } public static double AccelerationToVelocity(double acceleration, double freq) { return acceleration * 9.8f / (2 * Math.PI * freq ); } /// /// 工程量转电压 /// /// 工程量 /// 灵敏度 /// 电压 public static double QuantitiesToVoltage(double value, double sensitivity) { return value * sensitivity / 1000; } /// /// 工程量转电压 /// /// 工程量 /// 灵敏度 /// 电压 public static float QuantitiesToVoltage(float value, float sensitivity) { return value * sensitivity / 1000; } /// /// 电压转工程量 /// /// 电压 /// 灵敏度 /// 工程量 public static double VoltageToQuantities(double value, double sensitivity) { return value * 1000 / sensitivity; } /// /// 电压转工程量 /// /// 电压 /// 灵敏度 /// 工程量 public static float VoltageToQuantities(float value, float sensitivity) { return value * 1000 / sensitivity; } /// /// 计算计数的间隔时间 /// /// 最大计数 /// public static double CalcInterval(uint maxCount) { return 1d / (maxCount << 1); } /// /// 二维数组转置 /// /// /// /// /// /// public static void ArrayTranspose(ref T source, ref T destination, int rowcount, int colnumcount,int maxcolnumcount) { if (rowcount == 0 || colnumcount == 0) return; for (int i = 0; i < rowcount; i++) { for (int j = 0; j < colnumcount; j++) { Unsafe.Add(ref destination, i * maxcolnumcount + j) = Unsafe.Add(ref source, j * rowcount + i); } } } public static double CalcLevel(double currentlevel,double level) { return Math.Pow(10, level / 20) * currentlevel; } public static float CalcLevel(float currentlevel, float level) { return MathF.Pow(10, level / 20) * currentlevel; } /// /// 解交织 /// /// /// /// /// /// public static void Deinterweaving(ref T source, ref T destination, int rowcount, int colnumcount,int maxcolnumcount) => ArrayTranspose(ref source, ref destination, rowcount, colnumcount,maxcolnumcount); public static byte[] CompressionBytes(byte[] arrays) { if (arrays == null || arrays.Length == 0) return new byte[0]; using (MemoryStream ms =new MemoryStream()) { using (System.IO.Compression.DeflateStream ds = new System.IO.Compression.DeflateStream(ms, System.IO.Compression.CompressionLevel.SmallestSize, true)) { ds.Write(arrays, 0, arrays.Length); } return ms.ToArray(); } } public static byte[] DecompressionBytes(byte[] arrays) { if (arrays == null || arrays.Length == 0) return new byte[0]; using (MemoryStream ms = new MemoryStream(arrays)) { using (System.IO.Compression.DeflateStream ds = new System.IO.Compression.DeflateStream(ms, System.IO.Compression.CompressionMode.Decompress,true)) { using (MemoryStream memoryStream = new MemoryStream()) { ds.CopyTo(memoryStream); return memoryStream.ToArray(); } } } } public static byte[] CompressionWaves(ref T f,uint count) where T : unmanaged { if(count==0)return new byte[0]; byte[] temp = new byte[Unsafe.SizeOf() * count]; Unsafe.CopyBlock(ref temp[0], ref Unsafe.As(ref f), (uint)temp.Length); return CompressionBytes(temp); } public static T[] DecompressionWaves(byte[] f) where T : unmanaged { if (f ==null || f.Length == 0) return new T[0]; byte[] temp = DecompressionBytes(f); T[] result = new T[temp.Length / Unsafe.SizeOf()]; Unsafe.CopyBlock( ref Unsafe.As(ref result[0]),ref temp[0], (uint)temp.Length); return result; } } }