阀门寿命仿真

📅 2026/6/25 13:16:27
阀门寿命仿真
using System; using System.Drawing; using System.Windows.Forms; namespace 阀门轴填料测试 { // 自定义双缓冲面板消除动画闪烁 public class DoubleBufferedPanel : Panel { public DoubleBufferedPanel() { DoubleBuffered true; } } public class Form1 : Form { // 核心模拟参数 private readonly float _initialShaftDiameter 40f; // 初始轴直径 private readonly float _initialBoreDiameter 44f; // 初始轴套内径 private readonly float _shaftHeight 120f; // 轴总高度 private readonly float _moveRange 120f; // 轴芯运动行程 private float _currentShaftDiameter; private float _currentBoreDiameter; private float _minY; // 轴位置上限开到位相对中心偏移 private float _maxY; // 轴位置下限关到位刚好碰阀座 private int _cycleCount 0; // 累计完整循环次数 // 时间参数 private TimeSpan _simulatedTime; // 模拟运行时间随加速倍数加快 private const int BaseInterval 16; // 画面真实刷新间隔约60帧/秒 private double _baseCloseTime 1.0; // 基础关阀时间秒1倍速下 private double _baseOpenTime 1.0; // 基础开阀时间秒1倍速下 private double _baseHoldTime 0.5; // 基础关位间隔时间秒1倍速下 private double _speedMultiplier 1.0; // 加速倍数模拟时间流速 真实时间 × 倍数 private double _multiplierIncPerSec 0.1; // 自动增速真实时间每秒增加的倍数 private double _wearPercent 0.00001; // 单次磨损百分比 private float _failGap 20f; // 失效阈值单边间隙 // 运动状态机 private enum MotionState { Closing, Holding, Opening } private MotionState _currentState; private double _stateTimeLeft; private float _currentY; // 运行状态 private bool _isRunning false; private bool _autoIncreaseSpeed; private readonly System.Windows.Forms.Timer _animTimer; // 界面控件 private readonly Label _lblRunTimeFull; private readonly DoubleBufferedPanel _drawPanel; private readonly Label _lblCycle; private readonly Label _lblShaftSize; private readonly Label _lblBoreSize; private readonly Label _lblGap; private readonly Label _lblLifeRemain; private readonly Label _lblMultiplier; private readonly NumericUpDown _numCloseTime; private readonly NumericUpDown _numOpenTime; private readonly NumericUpDown _numHoldTime; private readonly NumericUpDown _numMultiplier; private readonly CheckBox _chkAutoSpeed; private readonly NumericUpDown _numMultiplierInc; private readonly NumericUpDown _numWear; private readonly NumericUpDown _numFailGap; private readonly Button _btnStart; private readonly Button _btnReset; public Form1() { // 窗体基础配置 Text 阀门轴套磨损寿命模拟器; Size new Size(520, 780); StartPosition FormStartPosition.CenterScreen; FormBorderStyle FormBorderStyle.FixedSingle; MaximizeBox false; DoubleBuffered true; SuspendLayout(); // 1. 完整运行时间模拟时间 _lblRunTimeFull new Label { Font new Font(Consolas, 16f, FontStyle.Bold), ForeColor Color.FromArgb(0, 100, 200), TextAlign ContentAlignment.MiddleCenter, Location new Point(10, 10), Size new Size(480, 35), Text 运行时间0年0月0天 00:00:00 }; Controls.Add(_lblRunTimeFull); // 2. 剩余寿命模拟时间 _lblLifeRemain new Label { Font new Font(Consolas, 12f, FontStyle.Bold), ForeColor Color.OrangeRed, TextAlign ContentAlignment.MiddleCenter, Location new Point(10, 45), Size new Size(480, 25), Text 剩余寿命计算中... }; Controls.Add(_lblLifeRemain); // 3. 绘图区域 _drawPanel new DoubleBufferedPanel { Location new Point(10, 80), Size new Size(480, 280), BackColor Color.White, BorderStyle BorderStyle.FixedSingle }; _drawPanel.Paint DrawPanel_Paint; Controls.Add(_drawPanel); int y 375; // 4. 第一行动作次数 当前加速倍数 Controls.Add(new Label { Text 动作次数, Location new Point(20, y), Size new Size(80, 23) }); _lblCycle new Label { Font new Font(Consolas, 10f), Location new Point(100, y), Size new Size(120, 23), Text 0 }; Controls.Add(_lblCycle); Controls.Add(new Label { Text 加速倍数, Location new Point(250, y), Size new Size(70, 23) }); _lblMultiplier new Label { Font new Font(Consolas, 10f), Location new Point(320, y), Size new Size(120, 23), ForeColor Color.DarkGreen, Text 1.00 倍 }; Controls.Add(_lblMultiplier); y 35; // 5. 第二行关阀时间 开阀时间 Controls.Add(new Label { Text 关阀时间(秒), Location new Point(20, y), Size new Size(90, 23) }); _numCloseTime new NumericUpDown { Location new Point(115, y), Size new Size(70, 23), Minimum 0.01M, Maximum 10M, DecimalPlaces 2, Value 1.0M }; _numCloseTime.ValueChanged (s, e) { if (!_isRunning) _baseCloseTime (double)_numCloseTime.Value; }; Controls.Add(_numCloseTime); Controls.Add(new Label { Text 开阀时间(秒), Location new Point(210, y), Size new Size(90, 23) }); _numOpenTime new NumericUpDown { Location new Point(305, y), Size new Size(70, 23), Minimum 0.01M, Maximum 10M, DecimalPlaces 2, Value 1.0M }; _numOpenTime.ValueChanged (s, e) { if (!_isRunning) _baseOpenTime (double)_numOpenTime.Value; }; Controls.Add(_numOpenTime); y 35; // 6. 第三行间隔时间 基础加速倍数 Controls.Add(new Label { Text 间隔时间(秒), Location new Point(20, y), Size new Size(90, 23) }); _numHoldTime new NumericUpDown { Location new Point(115, y), Size new Size(70, 23), Minimum 0M, Maximum 10M, DecimalPlaces 2, Value 0.5M }; _numHoldTime.ValueChanged (s, e) { if (!_isRunning) _baseHoldTime (double)_numHoldTime.Value; }; Controls.Add(_numHoldTime); Controls.Add(new Label { Text 基础倍数, Location new Point(210, y), Size new Size(70, 23) }); _numMultiplier new NumericUpDown { Location new Point(285, y), Size new Size(80, 23), Minimum 0.1M, Maximum 100M, DecimalPlaces 1, Value 1.0M }; _numMultiplier.ValueChanged (s, e) { if (!_isRunning) { _speedMultiplier (double)_numMultiplier.Value; _lblMultiplier.Text _speedMultiplier.ToString(F2) 倍; } }; Controls.Add(_numMultiplier); y 35; // 7. 第四行自动加速开关 增速速率 _chkAutoSpeed new CheckBox { Text 自动增加加速倍数, Location new Point(20, y 2), Size new Size(130, 20), Checked false }; _chkAutoSpeed.CheckedChanged (s, e) { _autoIncreaseSpeed _chkAutoSpeed.Checked; }; Controls.Add(_chkAutoSpeed); Controls.Add(new Label { Text 增速(倍/秒), Location new Point(170, y), Size new Size(80, 23) }); _numMultiplierInc new NumericUpDown { Location new Point(255, y), Size new Size(70, 23), Minimum 0.01M, Maximum 10M, DecimalPlaces 2, Value 0.1M }; _numMultiplierInc.ValueChanged (s, e) { _multiplierIncPerSec (double)_numMultiplierInc.Value; }; Controls.Add(_numMultiplierInc); y 35; // 8. 第五行磨损率 失效间隙 Controls.Add(new Label { Text 磨损率(%/次), Location new Point(20, y), Size new Size(90, 23) }); _numWear new NumericUpDown { Location new Point(115, y), Size new Size(100, 23), Minimum 0.000001M, Maximum 1M, DecimalPlaces 6, Value 0.00001M }; _numWear.ValueChanged (s, e) { _wearPercent (double)_numWear.Value; }; Controls.Add(_numWear); Controls.Add(new Label { Text 失效间隙(px), Location new Point(250, y), Size new Size(90, 23) }); _numFailGap new NumericUpDown { Location new Point(345, y), Size new Size(80, 23), Minimum 2M, Maximum 100M, DecimalPlaces 2, Value 20M }; _numFailGap.ValueChanged (s, e) { _failGap (float)_numFailGap.Value; }; Controls.Add(_numFailGap); y 35; // 9. 操作按钮 _btnStart new Button { Text 开始模拟, Location new Point(150, y), Size new Size(100, 30), Font new Font(微软雅黑, 10f, FontStyle.Bold) }; _btnStart.Click BtnStart_Click; Controls.Add(_btnStart); _btnReset new Button { Text 复位, Location new Point(270, y), Size new Size(100, 30), Font new Font(微软雅黑, 10f, FontStyle.Bold), BackColor Color.LightCoral, ForeColor Color.White }; _btnReset.Click BtnReset_Click; Controls.Add(_btnReset); y 50; // 10. 尺寸参数显示 Controls.Add(new Label { Text 轴直径, Location new Point(20, y), Size new Size(60, 23) }); _lblShaftSize new Label { Font new Font(Consolas, 9f), Location new Point(80, y), Size new Size(120, 23), ForeColor Color.DarkGreen }; Controls.Add(_lblShaftSize); y 25; Controls.Add(new Label { Text 轴套内径, Location new Point(20, y), Size new Size(60, 23) }); _lblBoreSize new Label { Font new Font(Consolas, 9f), Location new Point(80, y), Size new Size(120, 23), ForeColor Color.DarkRed }; Controls.Add(_lblBoreSize); y 25; Controls.Add(new Label { Text 单边间隙, Location new Point(20, y), Size new Size(60, 23) }); _lblGap new Label { Font new Font(Consolas, 9f, FontStyle.Bold), Location new Point(80, y), Size new Size(150, 23), ForeColor Color.OrangeRed }; Controls.Add(_lblGap); ResumeLayout(false); // 初始化定时器 _animTimer new System.Windows.Forms.Timer { Interval BaseInterval }; _animTimer.Tick AnimTimer_Tick; // 计算运动边界轴底刚好与阀座顶贴合 _minY -_moveRange / 2f; _maxY _moveRange / 2f 10f - _shaftHeight / 2f; // 初始化模拟数据 InitSimulation(); } /// summary /// 初始化所有模拟参数 /// /summary private void InitSimulation() { // 尺寸复位 _currentShaftDiameter _initialShaftDiameter; _currentBoreDiameter _initialBoreDiameter; _failGap (float)_numFailGap.Value; // 参数读取 _baseCloseTime (double)_numCloseTime.Value; _baseOpenTime (double)_numOpenTime.Value; _baseHoldTime (double)_numHoldTime.Value; _speedMultiplier (double)_numMultiplier.Value; // 运动状态复位初始在最上端准备关阀 _currentY _minY; _currentState MotionState.Closing; _stateTimeLeft _baseCloseTime; // 计数与时间复位 _cycleCount 0; _simulatedTime TimeSpan.Zero; UpdateDisplay(); _drawPanel.Invalidate(); } /// summary /// 开始/暂停按钮 /// /summary private void BtnStart_Click(object sender, EventArgs e) { if (!_isRunning) { _animTimer.Start(); _isRunning true; _btnStart.Text 暂停; SetInputsEnabled(false); } else { _animTimer.Stop(); _isRunning false; _btnStart.Text 继续; SetInputsEnabled(true); } } /// summary /// 复位按钮 /// /summary private void BtnReset_Click(object sender, EventArgs e) { _animTimer.Stop(); _isRunning false; _btnStart.Text 开始模拟; _btnStart.Enabled true; SetInputsEnabled(true); InitSimulation(); } /// summary /// 批量设置输入控件状态 /// /summary private void SetInputsEnabled(bool enabled) { _numCloseTime.Enabled enabled; _numOpenTime.Enabled enabled; _numHoldTime.Enabled enabled; _numMultiplier.Enabled enabled; _numMultiplierInc.Enabled enabled; _numWear.Enabled enabled; _numFailGap.Enabled enabled; _chkAutoSpeed.Enabled enabled; } /// summary /// 动画主循环 /// /summary private void AnimTimer_Tick(object sender, EventArgs e) { double realDelta BaseInterval / 1000.0; // 真实时间增量 double simDelta realDelta * _speedMultiplier; // 模拟时间增量加速后 // 1. 累加模拟时间 _simulatedTime TimeSpan.FromSeconds(simDelta); // 2. 自动加速按真实时间增长倍数 if (_autoIncreaseSpeed) { _speedMultiplier _multiplierIncPerSec * realDelta; if (_speedMultiplier 100) _speedMultiplier 100; } // 3. 状态机更新按模拟时间推进 _stateTimeLeft - simDelta; switch (_currentState) { case MotionState.Closing: if (_stateTimeLeft 0) { // 关阀到位 → 进入停留 _currentState MotionState.Holding; _stateTimeLeft _baseHoldTime; _currentY _maxY; } else { double progress 1.0 - _stateTimeLeft / _baseCloseTime; _currentY _minY (_maxY - _minY) * (float)progress; } break; case MotionState.Holding: _currentY _maxY; if (_stateTimeLeft 0) { // 停留结束 → 开阀 _currentState MotionState.Opening; _stateTimeLeft _baseOpenTime; } break; case MotionState.Opening: if (_stateTimeLeft 0) { // 开阀到位 → 完成一个周期 _cycleCount; ApplyWear(); // 直接进入下一轮关阀 _currentState MotionState.Closing; _stateTimeLeft _baseCloseTime; _currentY _minY; } else { double progress 1.0 - _stateTimeLeft / _baseOpenTime; _currentY _maxY - (_maxY - _minY) * (float)progress; } break; } // 4. 寿命耗尽检测 float currentGap (_currentBoreDiameter - _currentShaftDiameter) / 2f; if (currentGap _failGap) { _animTimer.Stop(); _isRunning false; _btnStart.Text 已失效; _btnStart.Enabled false; _lblLifeRemain.Text 剩余寿命已失效; } UpdateDisplay(); _drawPanel.Invalidate(); } /// summary /// 施加一次磨损 /// /summary private void ApplyWear() { _currentShaftDiameter * (float)(1.0 - _wearPercent / 100.0); _currentBoreDiameter * (float)(1.0 _wearPercent / 100.0); } /// summary /// 时间转年月日时分秒格式 /// /summary private string TimeToYMDHMS(TimeSpan time) { int years time.Days / 365; int months (time.Days % 365) / 30; int days (time.Days % 365) % 30; return ${years}年{months}月{days}天 {time.Hours:D2}:{time.Minutes:D2}:{time.Seconds:D2}; } /// summary /// 计算剩余寿命模拟时间 /// /summary private TimeSpan CalculateRemainingLife() { float currentGap (_currentBoreDiameter - _currentShaftDiameter) / 2f; if (currentGap _failGap) return TimeSpan.Zero; if (_speedMultiplier 0) return TimeSpan.MaxValue; // 单次循环间隙增量 double gapPerCycle (_currentShaftDiameter * _wearPercent / 100.0 _currentBoreDiameter * _wearPercent / 100.0) / 2.0; if (gapPerCycle 0) return TimeSpan.MaxValue; // 单周期基础时长1倍速下的模拟时间 double baseCycleTime _baseCloseTime _baseHoldTime _baseOpenTime; // 剩余循环次数 double remainingCycles (_failGap - currentGap) / gapPerCycle; // 剩余模拟秒数 double remainingSeconds remainingCycles * baseCycleTime; if (remainingSeconds TimeSpan.MaxValue.TotalSeconds) return TimeSpan.MaxValue; return TimeSpan.FromSeconds(remainingSeconds); } /// summary /// 更新所有界面显示 /// /summary private void UpdateDisplay() { // 运行时间显示模拟时间 _lblRunTimeFull.Text 运行时间 TimeToYMDHMS(_simulatedTime); // 剩余寿命显示模拟时间倒计时 TimeSpan remain CalculateRemainingLife(); if (remain TimeSpan.MaxValue) _lblLifeRemain.Text 剩余寿命极长; else if (remain TimeSpan.Zero) _lblLifeRemain.Text 剩余寿命已失效; else _lblLifeRemain.Text 剩余寿命 TimeToYMDHMS(remain); _lblCycle.Text _cycleCount.ToString(N0); _lblMultiplier.Text _speedMultiplier.ToString(F2) 倍; float gap (_currentBoreDiameter - _currentShaftDiameter) / 2f; _lblShaftSize.Text _currentShaftDiameter.ToString(F6) px; _lblBoreSize.Text _currentBoreDiameter.ToString(F6) px; _lblGap.Text gap.ToString(F6) px; } /// summary /// 绘制轴套、阀座、实体轴 /// /summary private void DrawPanel_Paint(object sender, PaintEventArgs e) { Graphics g e.Graphics; g.SmoothingMode System.Drawing.Drawing2D.SmoothingMode.AntiAlias; int centerX _drawPanel.Width / 2; int centerY _drawPanel.Height / 2; float boreOuter _currentBoreDiameter 20; float boreHalf _currentBoreDiameter / 2; float boreOuterHalf boreOuter / 2; // 轴套矩形 RectangleF boreRect new RectangleF( centerX - boreOuterHalf, centerY - _moveRange / 2 - 10, boreOuter, _moveRange 20 ); // 1. 绘制轴套 using (Brush brush new SolidBrush(Color.LightGray)) g.FillRectangle(brush, boreRect); using (Brush brush new SolidBrush(Color.White)) g.FillRectangle(brush, centerX - boreHalf, centerY - _moveRange / 2 - 10, _currentBoreDiameter, _moveRange 20); using (Pen pen new Pen(Color.Gray, 2)) g.DrawRectangle(pen, boreRect.X, boreRect.Y, boreRect.Width, boreRect.Height); // 2. 绘制阀座顶部与轴套底部齐平 float valveSeatTop centerY _moveRange / 2 10; float valveSeatHeight 20f; float valveSeatWidth boreOuter 30; RectangleF seatRect new RectangleF( centerX - valveSeatWidth / 2, valveSeatTop, valveSeatWidth, valveSeatHeight ); using (Brush brush new SolidBrush(Color.DarkGray)) g.FillRectangle(brush, seatRect); using (Pen pen new Pen(Color.Black, 1.5f)) g.DrawRectangle(pen, seatRect.X, seatRect.Y, seatRect.Width, seatRect.Height); g.DrawString(阀座, SystemFonts.DefaultFont, Brushes.Black, centerX valveSeatWidth / 2 5, valveSeatTop 3); // 3. 绘制实体轴 float shaftHalf _currentShaftDiameter / 2; float shaftTop centerY _currentY - _shaftHeight / 2; RectangleF shaftRect new RectangleF( centerX - shaftHalf, shaftTop, _currentShaftDiameter, _shaftHeight ); using (Brush brush new SolidBrush(Color.SteelBlue)) g.FillRectangle(brush, shaftRect); using (Pen pen new Pen(Color.DarkBlue, 1.5f)) g.DrawRectangle(pen, shaftRect.X, shaftRect.Y, shaftRect.Width, shaftRect.Height); // 4. 中心线 using (Pen pen new Pen(Color.Red, 1)) { pen.DashStyle System.Drawing.Drawing2D.DashStyle.Dash; g.DrawLine(pen, centerX, centerY - _moveRange / 2 - 30, centerX, valveSeatTop valveSeatHeight 10); } // 标注文字 g.DrawString(轴套, SystemFonts.DefaultFont, Brushes.Black, centerX boreOuterHalf 5, centerY - _moveRange / 2); g.DrawString(轴, SystemFonts.DefaultFont, Brushes.DarkBlue, centerX - 10, shaftTop - 18); } } }