Найти начальную точку (время) каждого цикла в синусоиде

Я пытаюсь достичь синусоиды, постепенно меняющейся от8Hz в2Hz над5 секунды:

Эта форма волны была создана вCool Edit, Я дал ему стартовую частоту8Hzконечная частота2Hz и продолжительность5 секунд. Синусоидальная волна постепенно изменяется от одной частоты к другой в течение заданного времени.

У меня вопрос, как я могу точно найти время начала каждого цикла (выделено красной точкой), используя цикл FOR?

Псевдокод:

time   = 5 //Duration
freq1  = 8 //Start frequency
freq2  = 2 //End frequency

cycles = ( (freq1 + freq2) / 2 ) * time //Total number of cycles

for(i = 0; i < cycles; i++) {
    /* Formula to find start time of each cycle */
}
 Spektre02 июн. 2016 г., 07:57
Смена знака @DavidTansey обнаружит все пересечения нуля, и только половина из нихphase=0 но я думаю, что проблема состоит в том, чтобы генерировать такой сигнал, чтобы не найти пересечения нуля. Это была просто попытка новичка подойти к этому путем создания отдельных волн греха, что неправильно для этого.

Ответы на вопрос(1)

Решение Вопроса

Это обратное мышление для этой проблемы, которая приводит к безумию в программе. Не говоря уже о том, что отдельные волны не будут синусоидальными, потому что частота меняется (они будут слегка искажены), чего вы не достигнете с вашим генератором, а также очень мала вероятность того, что сигнал окончания остановится на нуле через 5 секунд. Вместо этого сделайте непрерывную волну греха с переменной частотой:

Сначала вычислите фактическую частоту

Подойдет линейная интерполяция (если вам не нужны другие изменения)

f=f0+(f1-f0)*t/T

где:

f0=8 [Hz] start frequency
f1=2 [Hz] stop frequency
T =5 [s]  change time
t =<0,T> is actual time in [s]

вычислить данные синусоидальной волны

for (t=0.0,angle=0.0;t<=T;t+=dt)
 {
 f=f0+((f1-f0)*t/T); // actual frequency
 signal=Amplitude*sin(angle); // your signal put it in a array or output somewhere ...
 angle+=6.283185307179586476925286766559*dt*f; // update phase
 while (angle>6.283185307179586476925286766559) // cut just to avoid floating rounding problems
  angle-=6.283185307179586476925286766559;
 }

кудаdt [s] это временной шаг, с которым вы хотите сэмплировать ваш сигнал. Если вы генерируете это вВ реальном времени и вывод нанастоящий HW Вы можете использоватьtimer или измерить время напрямую (с помощьюperformance counters наWindows илиRDTSC или что у вас есть в распоряжении)

Если вы получили заранее определенное количество образцовn для этого тогда

dt=T/double(n-1);

Вот пример вывода (n=image width):

Если вам также нужно количество периодов, добавьте приращение счетчика внутриangle резатьwhile loop И также есть ваша нулевая точка (но если частота выборки слишком мала или вам нужна высокая точность, вам нужно интерполировать реальную нулевую позицию).

 pJay02 июн. 2016 г., 17:04
Удивительно подробный ответ и абсолютно точный (не каламбур). Brilliant!

Ваш ответ на вопрос