C#中的物理项目:线程和测量时间的问题
我在做一个物理项目时遇到了一些问题。 它基本上是一个自由落体模拟器。我设置了重力加速度和高度,程序应该模拟坠落。 问题是时间错了,不知道为什么。我用秒表课来计时 代码如下: FrmMain.cs:C#中的物理项目:线程和测量时间的问题,c#,.net,multithreading,timer,stopwatch,C#,.net,Multithreading,Timer,Stopwatch,我在做一个物理项目时遇到了一些问题。 它基本上是一个自由落体模拟器。我设置了重力加速度和高度,程序应该模拟坠落。 问题是时间错了,不知道为什么。我用秒表课来计时 代码如下: FrmMain.cs: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.T
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();
}
}
}
还有另一个问题,取决于物体的高度,物体不会不间断地下落,它会在同一位置停留几毫秒,但很明显。我认为这是一个线程问题,因为我已经有一段时间没有使用它了,所以我可能遗漏了一些东西
我测量的高度单位是米,因此objectPos.Y=420f/2f表示210米的高度。对于这个高度,物体撞击地面大约需要6.5秒,在我的程序中不到1秒,所以我假设存在时间测量问题
我用均匀重力场计算高度,没有空气阻力表达式:
h(t)=h0+0.5*g*t²
式中:h(t)是相对于时间的高度,h0是初始高度,g是重力加速度,t是经过的时间
非常感谢您的帮助。
谢谢。我相信你的问题可能已经到了紧要关头
config.objectPos.Y = config.objectPos.Y + 0.5f *
config.acceleration *
timeElapsed * timeElapsed;
t=t-sub-k时的Y位置(config.objectPos.Y
)是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;
我相信你的问题可能在这条线上
config.objectPos.Y = config.objectPos.Y + 0.5f *
config.acceleration *
timeElapsed * timeElapsed;
时间t=t-sub-k时的Y位置(config.objectPos.Y
)是时间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;
我认为你的公式是错误的。 h0应为初始速度(在您的情况下为0 m/s),并应乘以时间 这是正确的 话虽如此,Vi*t始终是0,因为初始速度是0,剩下的是0.5*9.8*timepassed*timepassed
config.objectPos.Y = 0 //initial velocity
+ 0.5f * config.acceleration * timeElapsed * timeElapsed;
另外,objectPost.Y应该始终从0米开始,因为它是从顶部开始的,并且会下降
您可以参考此控制台应用程序代码。运行它,查看经过的时间,并将其与
应该是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; }
}
}
使用系统;
使用System.Collections.Generic;
使用系统诊断;
使用System.Linq;
使用系统文本;
使用系统线程;
使用System.Threading.Tasks;
名称空间物理(U 16783733)
{
班级计划
{
静态void Main(字符串[]参数)
{
MyClass c=新的MyClass();
}
}
公共类MyClass
{
公共设置配置=新设置();
公共秒表计时器=新秒表();
公共浮点时间已过;//以秒为单位
公共线程;
静态事件控制;
公共MyClass()
{
控制=新手动复位事件(错误);
//新螺纹(图纸)
螺纹=新螺纹(新螺纹起点(图纸));
thread.IsBackground=true;
thread.Start();
控件WaitOne();
}
公共图纸()
{
尝试
{
while(true)
{
if(config.objectPos.Y