using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Collections.ObjectModel; using System.ComponentModel; namespace FLY.Simulation.HeaderAndTailer { public class CurveCollection : ICurveService, Misc.ISaveToXml { #region 数据文件需要保存的数据项 CurveCorrectWay correctWay = CurveCorrectWay.OnePointIsScale; /// <summary> /// AD曲线校正方式 /// </summary> public CurveCorrectWay CorrectWay { get { return correctWay; } set { if (correctWay != value) { correctWay = value; NotifyPropertyChanged("CorrectWay"); } } } private CurveType flag; public CurveType Flag { get { return flag; } set { if (flag != value) { flag = value; NotifyPropertyChanged("Flag"); } } } /// <summary> /// 输入的曲线, 排列顺序,Value 从 小到大 /// </summary> private ObservableCollection<CurveCell> mCurves = new ObservableCollection<CurveCell>(); public ObservableCollection<CurveCell> Curves { get { return mCurves; } } #endregion public event ActiveEventHandler ActiveEvent; public class ExChange : Misc.ISaveToXml { static ExChange() { Misc.SaveToXmlHepler.Regist(typeof(ExChange)); } public int OrgAD { get; set; } public int CurrAD { get; set; } public string[] GetSavePropertyNames() { return new string[]{ "OrgAD", "CurrAD"}; } } /// <summary> /// 真实样品校正点 /// </summary> private ObservableCollection<ExChange> mRevisingCurves = new ObservableCollection<ExChange>(); public ObservableCollection<ExChange> RevisingCurves { get { return mRevisingCurves; } } private string param_path = "curve.xml"; public CurveCollection() { SetDefault(); ReviseCurve(); } public CurveCollection(string param_path) { if (!string.IsNullOrEmpty(param_path)) this.param_path = param_path; SetDefault(); Load(); ReviseCurve(); } void SetDefault() { CorrectWay = CurveCorrectWay.OnePointIsScale; Flag = CurveType.E; Curves.Add(new CurveCell() { AD = 57564, Value = 0 }); Curves.Add(new CurveCell() { AD = 30850, Value = 8800 }); Curves.Add(new CurveCell() { AD = 19000, Value = 17600 }); Curves.Add(new CurveCell() { AD = 12528, Value = 26400 }); Curves.Add(new CurveCell() { AD = 8409, Value = 35200 }); Curves.Add(new CurveCell() { AD = 5650, Value = 44000 }); Curves.Add(new CurveCell() { AD = 3779, Value = 52800 }); Curves.Add(new CurveCell() { AD = 2513, Value = 61600 }); Curves.Add(new CurveCell() { AD = 1660, Value = 70400 }); } public void Apply() { ClearExChange(); ReviseCurve(); if (ActiveEvent != null) ActiveEvent(this); Save(); } public void Clear() { Curves.Clear(); ClearExChange(); } #region ExChange public void ModifyExChange(List<ExChange> list) { RevisingCurves.Clear(); for (int i = 0; i < list.Count(); i++) { //检测RevisingCurves 正确性,避免 /0 溢出 if ((list[i].OrgAD <= 10) || (list[i].CurrAD <= 10)) { //异常 continue; } var v = from rc in RevisingCurves where rc.OrgAD == list[i].OrgAD select rc; if (v.Count() > 0) { //异常,重复了 continue; } RevisingCurves.Add(list[i]); } RevisingCurves.OrderByDescending(c => c.OrgAD); } public void ClearExChange() { RevisingCurves.Clear(); } #endregion public static bool CheckRevisingPointValid(int ad) { if (ad < 3) { return false; } else { return true; } } /// <summary> /// 根据样品值,修正曲线,只支持2个样品 /// </summary> /// <returns></returns> public bool ReviseCurve() { if (RevisingCurves.Count < 1)//没数据 { foreach (CurveCell c in Curves) { c.RevisedAD = c.AD; } return false; } if (RevisingCurves.Count == 1)//只有一个校正点 { switch (CorrectWay) { case CurveCorrectWay.OnePointIsScale: { double ux = ((double)RevisingCurves[0].CurrAD) / RevisingCurves[0].OrgAD; foreach (CurveCell c in Curves) { c.RevisedAD = (int)(c.AD * ux); } } break; default: //case CurveCorrectWay.OnePointIsOffset: { int x = RevisingCurves[0].CurrAD - RevisingCurves[0].OrgAD; foreach (CurveCell c in Curves) { c.RevisedAD = c.AD + x; } } break; } return true; } else { int adh = RevisingCurves[0].OrgAD; int adl = RevisingCurves[1].OrgAD; double uh = ((double)RevisingCurves[0].CurrAD) / adh; double ul = ((double)RevisingCurves[1].CurrAD) / adl; for (int i = 0, j = 1; i < Curves.Count; i++) { double ux = uh - (adh - Curves[i].AD) * (uh - ul) / (adh - adl); Curves[i].RevisedAD = (int)(Curves[i].AD * ux); } return true; } } #region E int AD2Value_E(int ad, AD2ValueFlag flag) { int i; int thick; if (Curves.Count < 1) return -1; if (ad < 0) return -1; if (ad == 0) ad = 1; if (flag == AD2ValueFlag.NoRevised) { for (i = 0; i < Curves.Count; i++) { if (ad < Curves[i].AD) continue; else break; } } else { for (i = 0; i < Curves.Count; i++) { if (ad < Curves[i].RevisedAD) continue; else break; } } if (i >= Curves.Count) i = Curves.Count - 1; if (i == 0) i = 1; if (flag == AD2ValueFlag.NoRevised) { double u; u = Math.Log((double)Curves[i - 1].AD / Curves[i].AD, Math.E) * 100 / (Curves[i].Value - Curves[i - 1].Value); thick = (int)(Math.Log((double)Curves[i - 1].AD / ad, Math.E) * 100 / u + Curves[i - 1].Value); } else { double u; u = Math.Log((double)Curves[i - 1].RevisedAD / Curves[i].RevisedAD, Math.E) * 100 / (Curves[i].Value - Curves[i - 1].Value); thick = (int)(Math.Log((double)Curves[i - 1].RevisedAD / ad, Math.E) * 100 / u + Curves[i - 1].Value); } //if (thick < 0) // return 0; return thick; } int Value2AD_E(int value) { int i; int ad; if (Curves.Count < 1) return -1; if (value < 0) return -1; for (i = 0; i < Curves.Count; i++) { if (value > Curves[i].Value) continue; else break; } if (i >= Curves.Count) i = Curves.Count - 1; if (i == 0) i = 1; double u; u = (Math.Log(Curves[i - 1].AD) - Math.Log(Curves[i].AD)) / (Curves[i - 1].Value - Curves[i].Value); ad = (int)Math.Exp((value - Curves[i - 1].Value) * u + Math.Log(Curves[i - 1].AD)); return ad; } #endregion #region 线性 int AD2Value_Line(int ad, AD2ValueFlag flag) { int i; int thick; if (Curves.Count < 2) return -1; if (ad < 0) return -1; if (ad == 0) ad = 1; bool isDescending = true;//降序排列 if (Curves[0].AD < Curves[1].AD) isDescending = false; //找 ad0<ad<adi if (flag == AD2ValueFlag.NoRevised) { if (isDescending)//降序排列 { for (i = 0; i < Curves.Count; i++) { if (ad < Curves[i].AD) continue; else break; } } else { for (i = 0; i < Curves.Count; i++) { if (ad > Curves[i].AD) continue; else break; } } if (i >= Curves.Count) i = Curves.Count - 1; if (i == 0) i = 1; double adi_ad0 = Curves[i].AD - Curves[i - 1].AD; double vi_v0 = Curves[i].Value - Curves[i - 1].Value; double a = vi_v0 / adi_ad0; double b = Curves[i - 1].Value - Curves[i - 1].AD * a; thick = (int)(ad * a + b); return thick; } else { if (isDescending)//降序排列 { for (i = 0; i < Curves.Count; i++) { if (ad < Curves[i].RevisedAD) continue; else break; } } else { for (i = 0; i < Curves.Count; i++) { if (ad > Curves[i].RevisedAD) continue; else break; } } if (i >= Curves.Count) i = Curves.Count - 1; if (i == 0) i = 1; double adi_ad0 = Curves[i].RevisedAD - Curves[i - 1].RevisedAD; double vi_v0 = Curves[i].Value - Curves[i - 1].Value; double a = vi_v0 / adi_ad0; double b = Curves[i - 1].Value - Curves[i - 1].RevisedAD * a; thick = (int)(ad * a + b); return thick; } } int Value2AD_Line(int thick) { int i; int ad; if (Curves.Count < 2) return -1; bool isDescending = true;//降序排列 if (Curves[0].Value < Curves[1].Value) isDescending = false; //找 value0<thick<value1 if (isDescending)//降序排列 { for (i = 0; i < Curves.Count; i++) { if (thick < Curves[i].Value) continue; else break; } } else { for (i = 0; i < Curves.Count; i++) { if (thick > Curves[i].Value) continue; else break; } } if (i >= Curves.Count) i = Curves.Count - 1; if (i == 0) i = 1; double vi_v0 = Curves[i].Value - Curves[i - 1].Value; double adi_ad0 = Curves[i].AD - Curves[i - 1].AD; double a = vi_v0 / adi_ad0; double b = Curves[i - 1].Value - Curves[i - 1].AD * a; ad = (int)((thick - b)/a); return ad; } #endregion public int AD2Value(int ad, AD2ValueFlag flag) { switch (Flag) { case CurveType.Line: return AD2Value_Line(ad, flag); default: return AD2Value_E(ad, flag); } } public int ValueAD(int value) { switch (Flag) { case CurveType.Line: return Value2AD_Line(value); default: return Value2AD_E(value); } } #region ITDParam 成员 public bool Load() { bool ret = Misc.SaveToXmlHepler.Load("curve.xml", this); RevisingCurves.Clear(); Curves.OrderBy(c => c.Value); return ret; } public void Save() { Misc.SaveToXmlHepler.Save("curve.xml", this); } #endregion #region ISaveToXml 成员 public string[] GetSavePropertyNames() { return new string[]{ "CorrectWay", "Flag", "Curves"}; } #endregion #region INotifyPropertyChanged 成员 public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; protected void NotifyPropertyChanged(string propertyname) { if (PropertyChanged != null) { PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyname)); } } #endregion } }