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