如何模拟由给定信号驱动的谐振子(不是由正弦波驱动)

时间:2010-08-28 13:27:46

标签: c# math simulation physics

我有一个值表,告诉我信号电平如何随时间变化,我想模拟由此信号驱动的谐波振荡器。如果模拟不是100%准确则无关紧要。 我知道振荡器的频率。 我找到了很多公式,但他们都使用正弦波作为驱动程序。

3 个答案:

答案 0 :(得分:3)

我想你想要进行一些时间离散模拟。众所周知的公式需要分析输入(参见格林函数)。如果你在某个时间点有一张力表,那么典型的分析公式对你来说就无济于事了。

这个想法是这样的:对于每个时间点t0,振荡器有一些给定的加速度,速度等。现在一个力作用于它 - 根据你给出的表 - 这将改变它的加速度(F = m) * 一个)。对于下一个时间步骤t1,我们假设加速度保持在该常数,因此我们可以对该时间帧应用具有dt =(t1-t0)的简单Newtonian equations(v = a * dt)。迭代直到模拟所需的时间范围。

此模拟的最重要参数是dt,即计算的细粒度。例如,您可能希望每秒有10个步骤,但这完全取决于您的输入参数。我们在这里所做的实质上是方程的Eulerian integration

当然,这并不是全部 - 这种模拟可能非常复杂,尤其是在极端加速等情况下表现不佳的情况下。在这些情况下,您需要在一个帧内执行数字健全性检查,因为在一个帧中发生“极端”的事情。还需要一些数值积分,例如, Runge-Kutta algorithm。不过,我想这在这一点上会走得很远。

编辑:就在我发布这个之后,有人发表评论指向“Verlet Algorithm”的原始问题,这基本上是我上面描述的实现。

答案 1 :(得分:0)

答案 2 :(得分:0)

好吧,我终于想通了,并写了一个gui应用程序来测试它,直到它工作。但我的电脑不满意每秒1000 * 44100次,即使没有gui ^^

无论如何:这是我的测试代码(效果很好):

double lastTime;  
const double deltaT = 1 / 44100.0;//length of a frame in seconds  
double rFreq;  
private void InitPendulum()  
{  
double freq = 2;//frequency in herz  
rFreq = FToRSpeed(freq);  
damp = Math.Pow(0.8, freq * deltaT);  
}  

private static double FToRSpeed(double p)  
{  
p *= 2;  
p = Math.PI * p;  
return p * p;  
}  
double damp;  
double bHeight;  
double bSpeed;  
double lastchange;  
private void timer1_Tick(object sender, EventArgs e)  
{  
  double now=sw.ElapsedTicks/(double)Stopwatch.Frequency;  
  while (lastTime+deltaT <= now)  
  {  
    bHeight += bSpeed * deltaT;  
    double prevSpeed=bSpeed;  
    bSpeed += (mouseY - bHeight) * (rFreq*deltaT);  
    bSpeed *= damp;  
    if ((bSpeed > 0) != (prevSpeed > 0))  
    {  
      Console.WriteLine(lastTime - lastchange);  
      lastchange = lastTime;  
    }  
    lastTime += deltaT;  
  }  
  Invalidate();//No, i am not using gdi^^  
}