news 2026/6/25 13:31:23

阀门轴寿命仿真。

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
阀门轴寿命仿真。
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); } } }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/25 13:27:14

大模型微调前必须做的五项清醒检查

1. 这不是一篇教你怎么微调大模型的指南&#xff0c;而是一份“别急着微调”的清醒剂如果你最近正摩拳擦掌&#xff0c;准备把LLaMA-3、Qwen或DeepSeek某个开源大模型拉下来&#xff0c;配好LoRA脚本&#xff0c;开几块A100跑上几个小时&#xff0c;然后期待它在你那个小众客服…

作者头像 李华
网站建设 2026/6/25 13:25:34

C#集成国密SM3算法实战:BouncyCastle配置避坑与完整代码实现

1. 项目概述&#xff1a;为什么我们需要关注国密SM3&#xff1f;最近在做一个需要对接国内某金融机构接口的项目&#xff0c;对方明确要求所有敏感数据的哈希运算必须使用国密SM3算法。说实话&#xff0c;一开始我有点头大&#xff0c;毕竟平时MD5、SHA-256用惯了&#xff0c;对…

作者头像 李华
网站建设 2026/6/25 13:25:11

合成数据驱动的政治预测:从建模逻辑到SHAP可解释性实战

1. 项目概述&#xff1a;一场用合成数据模拟的选举预测实战复盘我做过不少机器学习项目&#xff0c;从电商推荐到工业设备故障预警&#xff0c;但真正让我反复调试、推倒重来三次的&#xff0c;是去年底做的这个“2024年美国总统大选结果预测”小实验。它不是为了真去押注谁赢&…

作者头像 李华
网站建设 2026/6/25 13:21:08

热门 AI 大模型横评:ChatGPT 搭载 GPT-4o 全功能实测,2026 开发者选型参考

前言2026 年大模型赛道竞争愈发激烈&#xff0c;海外 GPT、Claude、Gemini 与 DeepSeek、GLM、通义千问等国产模型形成分层竞争格局。不少开发者在选型时十分纠结&#xff1a;编码开发、识图解析、长文档阅读、实时语音交互该选择哪一款&#xff1f;本次测评以 ChatGPT 主力模型…

作者头像 李华
网站建设 2026/6/25 13:17:28

终极Windows风扇控制解决方案:Fan Control完全指南

终极Windows风扇控制解决方案&#xff1a;Fan Control完全指南 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gitcode.com/GitHub_Trending/fa/Fa…

作者头像 李华