Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#中的物理项目:线程和测量时间的问题_C#_.net_Multithreading_Timer_Stopwatch - Fatal编程技术网

C#中的物理项目:线程和测量时间的问题

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

我在做一个物理项目时遇到了一些问题。 它基本上是一个自由落体模拟器。我设置了重力加速度和高度,程序应该模拟坠落。 问题是时间错了,不知道为什么。我用秒表课来计时

代码如下:

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();
        }
    }
}
还有另一个问题,取决于物体的高度,物体不会不间断地下落,它会在同一位置停留几毫秒,但很明显。我认为这是一个线程问题,因为我已经有一段时间没有使用它了,所以我可能遗漏了一些东西

我测量的高度单位是米,因此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