我需要实现以均匀圆周运动移动的球的简单动画。我已经尝试了几个公式,下面的版本似乎是迄今为止最好的。但是,仍然有2个问题,我真的不知道有什么问题。 首先,在节目开始后的几秒钟内,球不稳定地移动。我认为theta(以弧度表示的角度)的值不能正确计算,但我不知道为什么。其次,运动在一段时间后变得更加均匀,但似乎随着时间的推移而减少。 “速度”的值表示完成一整圈所花费的秒数。 我想要的是一个统一的,正确的圆形运动(根据速度的值),并且一开始就没有急动。C#均匀圆周运动
到目前为止我的代码:
public partial class ServerForm : Form
{
Stopwatch watch;
//Angular velocity
float angularVelocity;
//Angle
float theta = 20;
//Speed - time to complete a full revolution, in seconds
private float speed = 3;
//Circle center
private int centerX = 250;
private int centerY = 200;
//Circle radius
private float R = 120;
//Current position
private LocationData currentLocation;
public ServerForm()
{
InitializeComponent();
}
public void UpdateUI()
{
currentLocation.CoordX = (float)(centerX + Math.Cos(theta) * R);
currentLocation.CoordY = (float)(centerY + Math.Sin(theta) * R);
currentLocation.Speed = speed;
try
{
this.Invoke(new Action(() => { this.Invalidate(); }));
}
catch (Exception ex)
{
watch.Stop();
Application.Exit();
}
theta += (float)((angularVelocity * 1000/watch.ElapsedMilliseconds));
//Console.Out.WriteLine("elapsed miliseconds: " + watch.ElapsedMilliseconds + " theta = " + theta);
}
protected override void OnPaint(PaintEventArgs e)
{
Graphics g = e.Graphics;
Brush color = new SolidBrush(Color.BlueViolet);
g.FillEllipse(color, currentLocation.CoordX, currentLocation.CoordY, 30, 30);
//Draw circle & center
g.DrawEllipse(new Pen(color), centerX, centerY, 5, 5);
float x = centerX - R;
float y = centerY - R;
float width = 2 * R;
float height = 2 * R;
g.DrawEllipse(new Pen(color), x, y, width, height);
base.OnPaint(e);
}
private void button1_Click(object sender, EventArgs e)
{
if (!String.IsNullOrEmpty(textSpeed.Text))
{
ResetValues(float.Parse(textSpeed.Text));
}
}
private void ResetValues(float newSpeed)
{
speed = newSpeed;
angularVelocity = (float)(2 * Math.PI/speed); // radians/sec
//Start at the top
currentLocation.CoordX = centerX;
currentLocation.CoordY = centerY - R;
theta = 90;
watch.Restart();
}
private void ServerForm_Load(object sender, EventArgs e)
{
watch = new Stopwatch();
timer1.Enabled = true;
timer1.Interval = 100;
timer1.Tick += timer1_Tick;
currentLocation = new LocationData();
ResetValues(speed);
}
void timer1_Tick(object sender, EventArgs e)
{
UpdateUI();
}
}
LocationData是只是抱着坐标&当前速度的一类。 时间单位&角速度(和转换为使用毫秒)是否正确?
更新:更改BackgroundWorker到定时器,但我仍然得到这种不稳定的运动,一段时间后运动减慢。
它可以使事情顺利使用基于时间的动画,而不是基于帧的动画。时间自上次生成帧以来的时间,并将其用于时间相关的动画。它会比假设每次的时间量相同更准确很多(即使您在'Thread.Sleep()'中指定了等待时间)。 –
你需要处理你在'OnPaint'函数中创建的'Brush'。 (不是问题的根源,但它可能导致其他与GDI +相关的问题) –
我丢弃了BackgroundWorker并使用了一个Timer(间隔100毫秒),但它仍然表现相同。如果我考虑弧度,θ达到> 100的值,不应该在[0,2 * PI]中? – joanna