Как смоделировать гармонический генератор, управляемый данным сигналом (не управляемый синусоидой) - PullRequest
4 голосов
/ 28 августа 2010

У меня есть таблица значений, показывающая, как уровень сигнала изменяется со временем, и я хочу смоделировать гармонический генератор, управляемый этим сигналом. Неважно, если симуляция не на 100% точна. Я знаю частоту генератора. Я нашел много формул, но все они используют синусоидальную волну в качестве драйвера.

Ответы [ 3 ]

3 голосов
/ 28 августа 2010

Полагаю, вы хотите выполнить некоторое дискретное по времени моделирование.Хорошо известные формулы требуют аналитического ввода (см. Функцию Грина).Если у вас есть таблица сил в какой-то момент времени, типичные аналитические формулы вам не сильно помогут.

Идея такова: для каждого момента времени t0 осциллятор имеет некоторое заданное ускорение,скорость и т. д. Теперь на нее действует сила - согласно таблице, которую вы дали - которая изменит ее ускорение (F = m * a).Для следующего шага времени t1 мы предполагаем, что ускорение останется на этой константе, поэтому мы можем применить простые ньютоновские уравнения (v = a * dt) с dt = (t1-t0) для этого временного интервала.Повторяйте до тех пор, пока не будет смоделирован желаемый диапазон во времени.

Наиболее важным параметром этого моделирования является dt, то есть насколько детализирован расчет.Например, вам может потребоваться 10 шагов в секунду, но это полностью зависит от ваших входных параметров.То, что мы здесь делаем, по сути, это Эйлерова интеграция уравнений.

Это, конечно, не все, что есть - такие симуляции могут быть довольно сложными, особенно,в случаях с не очень хорошим поведением, когда экстремальные ускорения и т. д. В этих случаях необходимо выполнять числовые проверки вменяемости в кадре, потому что что-то «экстремальное» происходит в одном кадре.Также может потребоваться некоторое численное интегрирование, например, алгоритм Рунге-Кутта .Я полагаю, что на этом этапе это далеко.

РЕДАКТИРОВАТЬ: Сразу после того, как я опубликовал это, кто-то оставил комментарий к первоначальному вопросу, указывающему на « алгоритм Verlet », которыйв основном реализация того, что я описал выше.

0 голосов
/ 28 августа 2010

Хорошо, я наконец-то понял это и написал приложение с графическим интерфейсом для тестирования, пока оно не заработало. Но мой компьютер не очень счастлив делать это 1000 * 44100 раз в секунду, даже без графического интерфейса ^^

Что бы там ни было: вот мой тестовый код (который работал довольно хорошо):

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^^  
}
0 голосов
...