Вопрос по c – Есть ли однострочная функция, которая генерирует треугольную волну?

58

Аналогичным образом, чтоmodulo генерирует пилообразную волну Он не должен быть непрерывным.

вот что я имею в виду:

int m = 10;
int x = 0;
int i = 0;
while (i < m*3) {
    printf("%d ", x);
    x++;
    x = x % m;
    i++;
}

генерирует последовательность 0..9, три раза, которая выглядит так:

sawtooth wave graph

note that the slope on the right side of the peak is just a graphing artifact

Однострочник в этом случаеx = i++ % m

Что я хочу это:

triangle wave graph

Если вы знаете однострочники для других волновых форм (синусоидальной, квадратной), это также было бы полезно знать.

UpdateВсе ответы были очень полезны, и у меня есть дополнительный вопрос.

Что бы добавить к волновой функции треугольника, чтобы наклон или изгиб линий был таким:

bulging waveforms

Thanks everyoneВаши разнообразные ответы помогли мне увидеть проблему в более широкой перспективе. Отдельное спасибо Нолдорину за то, что он расширил уравнение до квадратичных кривых.

@ willc2: я исправил это в вашем вопросе. Надеюсь, вы не возражаете. Noldorin
почему они должны быть "однострочными"? anon
Я думаю ты имеешь ввидуx = x++ % m? Noldorin
(Глядя на ваш код еще раз, я думаю, что вы на самом деле имеете в видуx = i++ % m.) Noldorin
@Neil Потому что я знаю, как их использовать, используя циклы for и if. Я хочу более элегантный способ делать такие вещи. @ Noldorin Новичок чему-то учится willc2

Ваш Ответ

8   ответов
0

Вот периодическая функция, которая выглядит как отдаленное синусоидальное приближение; по существу, это Sinuating paraboloid с использованием X в квадрате:

function  xs ( xx : float ): float{

    var xd =Mathf.Abs((Mathf.Abs(xx) % 2.4) - 1.2);

    if (  Mathf.Abs(Mathf.Abs(xx) % 4.8)  > 2.4){ 
        xd=(-xd*xd)+2.88;
    }else{
        xd = xd*xd;
    }

    return xd;

}
28

Расширяя ответ Эрика Бейнвилла:

y = (A/P) * (P - abs(x % (2*P) - P) )

Где х - бегущее целое число, а у - выход треугольной волны. А - амплитуда волны, а Р - полупериод. Например, A = 5 создаст волну от 0 до 5; P = 10 создаст волну с периодом 20. Волна начинается при y = 0 для x = 0.

Обратите внимание, что у будет число с плавающей точкой, если P не является фактором А. И, да, для математических пуристов: А технически вдвое больше амплитуды волны, но посмотрите на рисунок ниже, и вы поймете, что я имею в виду.

Визуализация:

Error: User Rate Limit Exceeded
86

Triangular Wave

y = abs((x++ % 6) - 3);

Это дает треугольную волну периода 6, колеблющуюся между 3 и 0.

Square Wave

y = (x++ % 6) < 3 ? 3 : 0;

Это дает правильную прямоугольную волну периода 6, колеблющуюся между 3 и 0.

Sine Wave

y = 3 * sin((float)x / 10);

Это дает синусоиду периода20 piколеблется между 3 и -3.


Update:

Curvy Triangular Wave

Чтобы получить вариацию треугольной волны, которая имеет кривые, а не прямые линии, вам просто нужно ввести показатель степени в уравнение, чтобы сделать его квадратичным.

Вогнутые кривые (т.е.x^2 форма):

y = pow(abs((x++ % 6) - 3), 2.0);

Вогнутые кривые (т.е.sqrt(x) форма):

y = pow(abs((x++ % 6) - 3), 0.5);

В качестве альтернативы использованиюpow функция, вы можете просто определитьsquare функционировать и использоватьsqrt функция вmath.h, что, вероятно, немного улучшит производительность.

Кроме того, если вы хотите сделать кривые круче / мельче, просто попробуйте изменить индексы.


Во всех этих случаях вы должны легко иметь возможность регулировать константы и добавлять коэффициенты масштабирования в нужных местах, чтобы дать вариации заданных форм сигнала (разные периоды, амплитуды, асимметрии и т. Д.).

Error: User Rate Limit Exceededpow(..., 2.0)Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded willc2
Error: User Rate Limit Exceeded0?
Error: User Rate Limit Exceeded
0

Попробуй это:

x = m - abs(m - 2*(i++ % m))
22

x = m - abs(i % (2*m) - m)
5

y = abs( amplitude - x % (2*amplitude) )

Изменение длины волны просто нуждается в коэффициенте дляx.

Редактировать: То, что я называю амплитудой, на самом деле является не амплитудой, а максимальным значением (т. Е. 5, если кривая колеблется между 0 и 5). Амплитуда в математическом смысле составляет половину от этого. Но вы поняли.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
5

Я знаю, что это старый пост, но всем, кто ищет что-то похожее, рекомендую посмотреть. http://en.wikipedia.org/wiki/Triangle_wave

Последняя формула y (x) = (2a / & # x3C0;) arcsin (sin ((2 & # x3C0; / p) * x))

или же.

(2 * amplitudeConstant / Math.PI) * Math.Asin(Math.Sin(2 * (Math.PI / periodConstant) * Convert.ToDouble(variableX)))
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
-2

Я проверил его с помощью простой петли, и вы, ребята, вообще не ответили на вопрос этого человека. Вырезание и вставка не помогут людям. Неудивительно, что так много мистификаций в СМИ имеют такой большой успех. С людьми, которые повторяют ошибки других, и это не может быть сюрпризом. И люди даже дают положительные оценки репутации за эти неправильные ответы ?! Невероятно! Но опять же, это соответствует моему предыдущему замечанию.

Итак, сначала мы собираемся объяснить нашим людям, что такое волна ТРЕУГОЛЬНИК. Ну, это волна, которая имеет период, состоящий из двух одинаковых наклонных скатов. Пандус с наклоном вверх и пандус, равный первому, но наклонному ВНИЗ, в отличие от SAWTOOTH, у которого наклон наклонен вверх или наклон наклонен вниз, повторенный после перевернутого талада.

PS: последний, кто дал «y (x) = (2a / & xxC0;) arcsin (sin ((2 & # x3C0; / p) * x))" слишком сложно, мы ищем быструю подпрограмму на С ++, поэтому о тригонометрии не может быть и речи.

Тестовая процедура:

(...)

for (byte V=0; V<255; V++)
{
unsigned int x = evenramp(V);
plotRGB(0,0,x,x,x);
delay(100); // make sure you have your own delay function declared of course

/* use your own graphic function !!! plotRGB(row,column,R,G,B) */
/* the light intensity will give you the change of value V in time */
/* all functions suggested as answer give SAWTOOTH and NOT TRIANGLE */
/* it is a TRIANGLE the man wants */
}

float triangleattempt(unsigned int x) // place any answered formula after '255 *' behind return.
{
return 255 * (255 - abs(255 - 2*(x % 255))); // this will show a SAWTOOTH
}

//All given answers up to now excluding "function  xs ( xx : float ): float" (this is not the requested one-liner, sorry) that are not a symmetrical triangle wave

// m - abs(i % (2*m) - m); (this is still a SAWTOOTH wave and not a TRIANGLE wave)
// abs((x++ % 6) - 3); (this is still a SAWTOOTH wave and not a TRIANGLE wave)
// abs(amplitude - x % (2*amplitude)); (this is still a SAWTOOTH wave and not a TRIANGLE wave)

= & GT; Я нашел источник, который точно говорит, что ответ в математической записи:http://mathworld.wolfram.com/TriangleWave.html

Я проверил формулу в программе для Linux под названием KmPlot. Пользователи Linux могут получить kmplot через корневой терминал, набрав apt-get install kmplot, и, если это не работает, попробуйте использовать обычный терминал и введите sudo apt-get install kmplot, а если это не работает, посмотрите это видео на YouTube для получения общих инструкций по установка программы для Linuxhttp://www.youtube.com/watch?v=IkhcwxC0oUg

ТАК ПРАВИЛЬНЫЙ ОТВЕТ на вопрос потока является примером объявления функции симметричного треугольника в форме c ++, показанной ниже:

(...)

int symetrictriangle(float x)
{
unsigned int period = 30; // number of increases of x before a new cycle begins
unsigned int amplitude = 100; // top to bottom value while the bottom value is always zero
return amplitude * 2 * abs(round(x/period)-(x/period));
}

(...)

Cheerz!

Error: User Rate Limit Exceeded

Похожие вопросы