阀门轴寿命仿真。

📅 2026/6/25 13:31:30
阀门轴寿命仿真。
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 float _currentShaftDiameter; private float _currentBoreDiameter; private float _initialGap; // 初始单边间隙 private readonly float _moveRange 120f; // 轴上下移动总行程 private float _currentY; // 轴当前Y方向偏移中心为原点 private float _moveSpeed; // 轴运动速度像素/帧正负代表方向 private int _cycleCount 0; // 累计完整循环次数 // 时间与频率 private DateTime _startTime; private TimeSpan _elapsedTime; private const int BaseInterval 16; // 刷新率约60帧/秒 private double _currentFreq 1.0; // 当前动作频率 Hz private double _freqIncreasePerSecond 0.1; // 自动增速每秒增加的Hz数 private double _wearPercent 0.00001; // 单次磨损百分比 private float _failGap 20f; // 失效阈值单边间隙达到此值寿命耗尽 // 运行状态 private bool _isRunning false; private bool _autoIncreaseFreq; 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 NumericUpDown _numWear; private readonly NumericUpDown _numFailGap; private readonly NumericUpDown _numFreq; private readonly CheckBox _chkAutoFreq; private readonly NumericUpDown _numFreqInc; private readonly Label _lblCurrentFreq; private readonly Button _btnStart; private readonly Button _btnReset; // 复位按钮 public Form1() { // 窗体基础配置 Text 阀门轴套磨损寿命模拟器; Size new Size(520, 750); 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) }); _lblCurrentFreq new Label { Font new Font(Consolas, 10f), Location new Point(320, y), Size new Size(120, 23), ForeColor Color.DarkGreen, Text 1.0 Hz }; Controls.Add(_lblCurrentFreq); y 35; // 5. 第二行基础频率 自动增速开关 Controls.Add(new Label { Text 基础频率(Hz), Location new Point(20, y), Size new Size(90, 23) }); _numFreq new NumericUpDown { Location new Point(115, y), Size new Size(80, 23), Minimum 0.1M, Maximum 200M, DecimalPlaces 1, Value 1.0M }; _numFreq.ValueChanged (s, e) { if (!_isRunning) { _currentFreq (double)_numFreq.Value; UpdateSpeedFromFreq(); } }; Controls.Add(_numFreq); _chkAutoFreq new CheckBox { Text 自动增加频率, Location new Point(220, y 2), Size new Size(110, 20), Checked false }; _chkAutoFreq.CheckedChanged (s, e) { _autoIncreaseFreq _chkAutoFreq.Checked; }; Controls.Add(_chkAutoFreq); y 35; // 6. 第三行增速速率 磨损率 Controls.Add(new Label { Text 增速(Hz/秒), Location new Point(20, y), Size new Size(90, 23) }); _numFreqInc new NumericUpDown { Location new Point(115, y), Size new Size(80, 23), Minimum 0.01M, Maximum 20M, DecimalPlaces 2, Value 0.1M }; _numFreqInc.ValueChanged (s, e) { _freqIncreasePerSecond (double)_numFreqInc.Value; }; Controls.Add(_numFreqInc); Controls.Add(new Label { Text 磨损率(%/次), Location new Point(250, y), Size new Size(90, 23) }); _numWear new NumericUpDown { Location new Point(345, 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); y 35; // 7. 第四行失效间隙 操作按钮 Controls.Add(new Label { Text 失效间隙(px), Location new Point(20, y), Size new Size(90, 23) }); _numFailGap new NumericUpDown { Location new Point(115, 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); _btnStart new Button { Text 开始模拟, Location new Point(230, 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(345, 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; // 8. 尺寸参数显示 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; // 初始化模拟数据 InitSimulation(); } /// summary /// 根据频率计算运动速度 /// /summary private void UpdateSpeedFromFreq() { // 一个完整往返行程 2倍总行程 double totalDistancePerSecond _moveRange * 2 * _currentFreq; double framesPerSecond 1000.0 / BaseInterval; _moveSpeed (float)(totalDistancePerSecond / framesPerSecond); } /// summary /// 初始化所有模拟参数复位核心逻辑 /// /summary private void InitSimulation() { _currentShaftDiameter _initialShaftDiameter; _currentBoreDiameter _initialBoreDiameter; _initialGap (_initialBoreDiameter - _initialShaftDiameter) / 2f; _failGap (float)_numFailGap.Value; _currentY -_moveRange / 2f; // 初始在最上端 _cycleCount 0; _elapsedTime TimeSpan.Zero; _currentFreq (double)_numFreq.Value; UpdateSpeedFromFreq(); UpdateDisplay(); _drawPanel.Invalidate(); } /// summary /// 开始/暂停按钮 /// /summary private void BtnStart_Click(object sender, EventArgs e) { if (!_isRunning) { _startTime DateTime.Now.Subtract(_elapsedTime); _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) { _numFreq.Enabled enabled; _numWear.Enabled enabled; _numFreqInc.Enabled enabled; _numFailGap.Enabled enabled; _chkAutoFreq.Enabled enabled; } /// summary /// 动画主循环60帧 /// /summary private void AnimTimer_Tick(object sender, EventArgs e) { double deltaSeconds BaseInterval / 1000.0; _elapsedTime DateTime.Now - _startTime; // 1. 自动增速逻辑 if (_autoIncreaseFreq) { _currentFreq _freqIncreasePerSecond * deltaSeconds; if (_currentFreq 200) _currentFreq 200; UpdateSpeedFromFreq(); } // 2. 更新位置匀速运动 _currentY _moveSpeed; // 3. 碰撞检测 换向硬碰撞撞到立即反向 float bottomLimit _moveRange / 2f; // 最下端碰阀座 float topLimit -_moveRange / 2f; // 最上端 // 向下撞到阀座 if (_currentY bottomLimit) { _currentY bottomLimit; _moveSpeed -Math.Abs(_moveSpeed); // 反向向上 _cycleCount; ApplyWear(); } // 向上回到顶端 else if (_currentY topLimit) { _currentY topLimit; _moveSpeed Math.Abs(_moveSpeed); // 反向向下 } // 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 (_currentFreq 0) return TimeSpan.MaxValue; // 单次循环间隙增加量 double gapPerCycle (_currentShaftDiameter * _wearPercent / 100.0 _currentBoreDiameter * _wearPercent / 100.0) / 2.0; if (gapPerCycle 0) return TimeSpan.MaxValue; double remainingCycles (_failGap - currentGap) / gapPerCycle; double remainingSeconds remainingCycles / _currentFreq; if (remainingSeconds TimeSpan.MaxValue.TotalSeconds) return TimeSpan.MaxValue; return TimeSpan.FromSeconds(remainingSeconds); } /// summary /// 更新所有界面显示 /// /summary private void UpdateDisplay() { _lblRunTimeFull.Text 运行时间 TimeToYMDHMS(_elapsedTime); 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); _lblCurrentFreq.Text _currentFreq.ToString(F2) Hz; 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 shaftHeight 120f; int ghostCount Math.Min(12, (int)(_currentFreq / 8) 1); // 从远到近绘制残影透明度递增 for (int i ghostCount; i 1; i--) { float alpha 30 (180 / ghostCount) * (ghostCount - i); Color ghostColor Color.FromArgb((int)alpha, Color.SteelBlue); float ghostY _currentY - _moveSpeed * i * 1.2f; float ghostTop centerY ghostY - shaftHeight / 2; RectangleF ghostRect new RectangleF( centerX - shaftHalf, ghostTop, _currentShaftDiameter, shaftHeight ); using (Brush brush new SolidBrush(ghostColor)) g.FillRectangle(brush, ghostRect); } // 4. 绘制实体轴 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); // 5. 中心线 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); } } }