我正在尝试制作物理项目的一些问题。 它基本上是一个自由落体模拟器。我设定了重力加速度和高度,程序应该模拟下降。 问题在于时间错了,不知道为什么。我正在使用秒表课来测量时间。
以下是代码:
FrmMain.cs:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Diagnostics;
namespace Physics
{
public partial class FrmMain : Form
{
public Settings config = new Settings();
public float displacement = 0f;
public Stopwatch timer = new Stopwatch();
public float timeElapsed; //in Seconds
public Thread thread;
public FrmMain()
{
InitializeComponent();
//New thread (Drawing)
thread = new Thread(new ThreadStart(Drawing));
thread.IsBackground = true;
thread.Start();
this.KeyDown +=new KeyEventHandler(FrmMain_KeyDown);
}
private void Drawing()
{
try
{
while (true)
{
if (config.objectPos.Y < config.sizeBitmap.Height)
timer.Start();
else
timer.Stop();
Bitmap screen = new Bitmap(this.pboxScreen.Width,
this.pboxScreen.Height);
SendScreen(screen);
}
}
catch (ThreadAbortException tae)
{
Console.WriteLine(tae.Message);
}
}
private void SendScreen(Bitmap Screen)
{
if (pboxScreen.InvokeRequired)
{
pboxScreen.Invoke(new MethodInvoker(delegate()
{
this.SendScreen(Screen);
}));
}
else
{ //Converting Milliseconds to Seconds
timeElapsed = timer.ElapsedMilliseconds / 1000f;
//Check if object isn't in the ground
if (config.objectPos.Y < config.sizeBitmap.Height)
{
displacement -= config.objectPos.Y;
config.objectPos.Y = config.objectPos.Y + 0.5f *
config.acceleration *
timeElapsed * timeElapsed;
displacement += config.objectPos.Y;
}
Graphics g = Graphics.FromImage(Screen);
g.Clear(Color.White);
//New rectangle
Rectangle rec = new Rectangle((int)config.objectPos.X,
(int)config.objectPos.Y, 5, 5);
g.FillRectangle((new Pen(Color.DarkRed)).Brush, rec);
g.DrawRectangle(new Pen(Color.Red, 2.0f), rec);
g.Dispose();
//Update txtbox (textbox)
txtboxX.Text = config.objectPos.X.ToString();
txtboxY.Text = config.objectPos.Y.ToString();
txtboxTempo.Text = timeElapsed.ToString();
txtboxD.Text = displacement.ToString();
pboxScreen.Image = Screen;
}
}
void FrmMain_KeyDown(object sender, KeyEventArgs e)
{
switch (e.KeyCode)
{
case Keys.Space:
if (config.objectPos.Y >= config.sizeBitmap.Height)
{
config.objectPos.Y -= 100;
timer.Reset();
}
break;
}
}
private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
{
if (thread.IsAlive) thread.Abort();
}
}
}
Settings.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
namespace Physics
{
public class Settings
{
public Size sizeBitmap; //bitmap resolution
public PointF objectPos; //Initial Position
public float acceleration;
public Settings()
{
sizeBitmap.Width = 560;
sizeBitmap.Height = 420;
objectPos.X = 560f / 2f;
objectPos.Y = 420f / 2f;
acceleration = 9.8f;
}
}
}
还有另一个问题,取决于高度,物体不会在没有中断的情况下掉落,它会保持在相同的位置几个,但是明显的毫秒。我认为这是一个线程问题,因为我有一段时间不使用它,所以我可能会遗漏一些东西。
我以米为单位测量高度,因此objectPos.Y = 420f / 2f表示高度为210米。对于这个高度,物体应该花费大约6.5秒才能击中地面,在我的程序中花费的时间不到1秒,所以我认为有时间测量问题。
我用均匀的引力场计算高度,没有空气阻力表达式:
H(T)= H0 + 0.5 * G * T 2
其中: h(t)是相对于时间的高度, h0 初始高度, g 由于重力引起的加速度< em> t 经过的时间
非常感谢任何帮助。 感谢。
答案 0 :(得分:1)
我相信您的问题可能就在
行 config.objectPos.Y = config.objectPos.Y + 0.5f *
config.acceleration *
timeElapsed * timeElapsed;
时间t = t-sub-k(config.objectPos.Y
)处的YPosition是时间t-sub-k处的高度。如果t是总经过时间,那么这等于 初始 Y位置(时间高度t = 0)+ 1/2 gt ^ 2,而不是最后 Y位置。
你正在做的是采取最后的Y位置(上次计算的高度,并在从时间t = 0到t = t-sub-k的经过时间内增加高度下降。所以它不是不知道它下降得太快了。
将初始Y位置只读属性添加到您的设置构造中,并且不要更新或修改它。
修改代码以使用它,如下所示:
config.objectPos.Y = config.InitialY + 0.5f *
config.acceleration *
timeElapsed * timeElapsed;
答案 1 :(得分:0)
我认为你的公式错了。 h0应该是初始速度(在你的情况下是0米/秒),它应该与时间相乘。
这是正确的from
所以说过,Vi * t总是0,因为你的初始速度是0.剩下的是0.5 * 9.8 * timeElapsed * timeElapsed。
config.objectPos.Y = 0 //initial velocity
+ 0.5f * config.acceleration * timeElapsed * timeElapsed;
此外,objectPost.Y应始终从0米开始,因为它从顶部开始,它将会下降。
您可以参考此控制台应用代码。运行它并查看比较的时间并将其与results in
进行比较应该是1.32秒。
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Physics_16783733
{
class Program
{
static void Main(string[] args)
{
MyClass c = new MyClass();
}
}
public class MyClass
{
public Settings config = new Settings();
public Stopwatch timer = new Stopwatch();
public float timeElapsed; //in Seconds
public Thread thread;
static ManualResetEvent control;
public MyClass()
{
control = new ManualResetEvent(false);
//New thread (Drawing)
thread = new Thread(new ThreadStart(Drawing));
thread.IsBackground = true;
thread.Start();
control.WaitOne();
}
public void Drawing()
{
try
{
while (true)
{
if (config.objectPos.Y < config.sizeBitmap.Height)
{
timer.Start();
}
else
{
timer.Stop();
control.Set();
}
//Bitmap screen = new Bitmap(this.pboxScreen.Width, this.pboxScreen.Height);
SendScreen();
}
}
catch (ThreadAbortException tae)
{
Console.WriteLine(tae.Message);
}
}
private void SendScreen()
{
timeElapsed = timer.ElapsedMilliseconds / 1000f; //Converting Milliseconds to Seconds
if (config.objectPos.Y < config.sizeBitmap.Height) //Check if object isn't in the ground
{
//formula used is in http://www.physicsclassroom.com/Class/1DKin/U1L6c.cfm
config.objectPos.Y = 0 //initial velocity
+ 0.5f * config.acceleration * timeElapsed * timeElapsed;
}
//Update txtbox (textbox)
Console.WriteLine("Object position Y: " + config.objectPos.Y.ToString());
Console.WriteLine("Time elapsed : " + timeElapsed.ToString()); //using the data from http://www.physicsclassroom.com/Class/1DKin/U1L6c.cfm, time elapsed should be 1.32 seconds
}
}
public class Settings
{
//I used data from http://www.physicsclassroom.com/Class/1DKin/U1L6c.cfm
//where the given is:
//vi = 0.0 m/s
//d = -8.52 m
//a = - 9.8 m/s2
public Size sizeBitmap; //height of the place where the object will start free falling
public PointF objectPos; //Initial Position
public float acceleration;
public Settings()
{
sizeBitmap.Height = 8.52;
objectPos.Y = 0;
acceleration = 9.8f;
}
}
public struct PointF
{
public float Y { get; set; }
}
public struct Size
{
public double Height { get; set; }
}
}