我需要實現以均勻圓周運動移動的球的簡單動畫。我已經嘗試了幾個公式,下面的版本似乎是迄今爲止最好的。但是,仍然有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