编辑
2025-02-10
C# 应用
00
请注意,本文编写于 95 天前,最后修改于 95 天前,其中某些信息可能已经过时。

目录

等加速运动原理
基本公式
实现代码
运动参数类
运动控制类
GDI+实现示例
主窗体类
总结

等加速运动原理

等加速运动是最基础的加速模式,其特点是加速度恒定,速度随时间线性变化。。在工业自动化、游戏开发、动画制作等领域都有广泛应用。本文将详细介绍如何使用C#的GDI+来实现和可视化等加速运动。

基本公式

Markdown
- v = v0 + at (速度方程) - s = v0t + (1/2)at² (位移方程) - v² = v0² + 2as (速度-位移方程) 其中: v0: 初始速度 v: 当前速度 a: 加速度 t: 时间 s: 位移

实现代码

运动参数类

C#
public class MotionParameters { public double InitialVelocity { get; set; } // 初始速度 public double Acceleration { get; set; } // 加速度 public double MaxVelocity { get; set; } // 最大速度 public double Distance { get; set; } // 总距离 public Point StartPoint { get; set; } // 起点 public Point EndPoint { get; set; } // 终点 public MotionParameters() { InitialVelocity = 0; Acceleration = 100; // 像素/秒² MaxVelocity = 300; // 像素/秒 StartPoint = new Point(0, 0); EndPoint = new Point(0, 0); } }

运动控制类

C#
public class MotionControl { // 私有成员变量 private readonly MotionParameters _parameters; // 运动参数 private double _currentTime; // 当前运动时间 private double _currentVelocity; // 当前速度 private Point _currentPosition; // 当前位置 private bool _isAccelerating; // 是否处于加速阶段 private double _totalDistance; // 总运动距离 private double _currentDistance; // 当前已运动距离 // 添加公共属性访问 public double CurrentVelocity => _currentVelocity; public bool IsCompleted => _currentDistance >= _totalDistance; public Point StartPoint => _parameters.StartPoint; public Point EndPoint => _parameters.EndPoint; public MotionControl(MotionParameters parameters) { _parameters = parameters; Initialize(); } private void Initialize() { _currentTime = 0; _currentVelocity = _parameters.InitialVelocity; _currentPosition = _parameters.StartPoint; _isAccelerating = true; _currentDistance = 0; // 计算总距离 _totalDistance = Math.Sqrt( Math.Pow(_parameters.EndPoint.X - _parameters.StartPoint.X, 2) + Math.Pow(_parameters.EndPoint.Y - _parameters.StartPoint.Y, 2)); } public Point CalculatePosition(double deltaTime) { if (IsCompleted) return _currentPosition; _currentTime += deltaTime; // 更新速度 if (_isAccelerating) { _currentVelocity += _parameters.Acceleration * deltaTime; if (_currentVelocity >= _parameters.MaxVelocity) { _currentVelocity = _parameters.MaxVelocity; _isAccelerating = false; } } // 计算这一帧移动的距离 double frameDistance = _currentVelocity * deltaTime; _currentDistance += frameDistance; // 确保不超过总距离 if (_currentDistance >= _totalDistance) { _currentDistance = _totalDistance; _currentPosition = _parameters.EndPoint; return _currentPosition; } // 计算当前位置 double ratio = _currentDistance / _totalDistance; _currentPosition.X = (int)(_parameters.StartPoint.X + (_parameters.EndPoint.X - _parameters.StartPoint.X) * ratio); _currentPosition.Y = (int)(_parameters.StartPoint.Y + (_parameters.EndPoint.Y - _parameters.StartPoint.Y) * ratio); return _currentPosition; } public void Reset() { Initialize(); } }

GDI+实现示例

主窗体类

C#
public partial class Form1 : Form { private MotionControl _motionControl; private Timer _animationTimer; private Point _objectPosition; private bool _isMoving; private List<Point> _trajectoryPoints; public Form1() { InitializeComponent(); this.DoubleBuffered = true; _trajectoryPoints = new List<Point>(); InitializeComponents(); SetupMotionControl(); } private void InitializeComponents() { _animationTimer = new Timer(); _animationTimer.Interval = 16; // ~60fps _animationTimer.Tick += AnimationTimer_Tick; this.Paint += MotionSimulationForm_Paint; this.MouseClick += MotionSimulationForm_MouseClick; } private void SetupMotionControl() { var parameters = new MotionParameters { InitialVelocity = 0, Acceleration = 200, MaxVelocity = 400, StartPoint = new Point(100, 300), }; _motionControl = new MotionControl(parameters); _objectPosition = parameters.StartPoint; } private void MotionSimulationForm_Paint(object sender, PaintEventArgs e) { Graphics g = e.Graphics; g.SmoothingMode = SmoothingMode.AntiAlias; // 绘制轨迹 if (_trajectoryPoints.Count > 1) { using (Pen pen = new Pen(Color.LightBlue, 2)) { for (int i = 1; i < _trajectoryPoints.Count; i++) { g.DrawLine(pen, _trajectoryPoints[i - 1], _trajectoryPoints[i]); } } } // 绘制起点和终点 if (_isMoving) { using (Pen pen = new Pen(Color.Gray, 1)) { g.DrawLine(pen, _motionControl.StartPoint, _motionControl.EndPoint); } } // 绘制运动物体 using (SolidBrush brush = new SolidBrush(Color.Blue)) { g.FillEllipse(brush, _objectPosition.X - 15, _objectPosition.Y - 15, 30, 30); } // 绘制信息 using (Font font = new Font("Arial", 10)) using (SolidBrush brush = new SolidBrush(Color.Black)) { string info = $"速度: {_motionControl.CurrentVelocity:F2} 像素/秒"; g.DrawString(info, font, brush, 10, 10); } } private void AnimationTimer_Tick(object sender, EventArgs e) { if (_isMoving) { _objectPosition = _motionControl.CalculatePosition(0.016); _trajectoryPoints.Add(_objectPosition); if (_motionControl.IsCompleted) { _isMoving = false; _animationTimer.Stop(); } Invalidate(); } } private void MotionSimulationForm_MouseClick(object sender, MouseEventArgs e) { if (!_isMoving) { var parameters = new MotionParameters { InitialVelocity = 0, Acceleration = 200, MaxVelocity = 400, StartPoint = _objectPosition, EndPoint = e.Location }; _motionControl = new MotionControl(parameters); _trajectoryPoints.Clear(); _trajectoryPoints.Add(_objectPosition); _isMoving = true; _animationTimer.Start(); } } }

image.png

总结

在本文中,我们展示了如何通过使用GDI+提供的优秀绘图支持、清晰的代码结构,实现了基础的加速运动模式。这个基础实现可以作为更复杂运动控制系统的基础,使得后续的开发更加简单、稳定和流畅。

本文作者:rick

本文链接:https://www.idiosoft.com/post/182

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

评论
  • 按正序
  • 按倒序
  • 按热度
来发评论吧~
Powered by Waline v2.14.8