Ответ 1
x = m - abs(i % (2*m) - m)
Аналогично, что по модулю генерирует пилообразную волну. Он не должен быть непрерывным.
вот что я имею в виду:
int m = 10;
int x = 0;
int i = 0;
while (i < m*3) {
printf("%d ", x);
x++;
x = x % m;
i++;
}
генерирует последовательность 0..9, три раза, которая выглядит так:
обратите внимание, что наклон справа от пика представляет собой только артефакт графического отображения
Однострочный в этом случае x = я ++% m
Я хочу это:
Если вы знаете однострочные символы для других форм волны (синус, квадрат), это также хорошо знать.
Обновить: все ответы были очень полезными, и у меня есть следующий вопрос.
Что будет добавлено к волновой функции треугольника, чтобы сделать наклон линий кривой так или иначе:
Спасибо всем, ваши разнообразные ответы помогли мне увидеть проблему с большей точки зрения. Особая благодарность Нольдорину за то, что он получил распространение на квадратичные кривые.
x = m - abs(i % (2*m) - m)
y = abs((x++ % 6) - 3);
Это дает треугольную волну периода 6, колеблющуюся между 3 и 0.
y = (x++ % 6) < 3 ? 3 : 0;
Это дает регулярную прямоугольную волну периода 6, колеблющуюся между 3 и 0.
y = 3 * sin((float)x / 10);
Это дает синусоидальную волну периода 20 pi
, колеблющуюся между 3 и -3.
Update:
Чтобы получить вариацию треугольной волны, которая имеет кривые, а не прямые, вам просто нужно ввести показатель в уравнение, чтобы сделать его квадратичным.
Вогнутые кривые (т.е. форма 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
, что, вероятно, немного улучшит производительность.
Кроме того, если вы хотите сделать кривые более крутыми/более мелкие, просто попробуйте изменить индексы.
Во всех этих случаях вы должны легко настраивать константы и добавлять коэффициенты масштабирования в нужные места, чтобы давать вариации данных осциллограмм (разные периоды, амплитуды, асимметрии и т.д.).
Развернувшись на Эрика Бэйнвиля, ответьте:
y = (A/P) * (P - abs(x % (2*P) - P) )
Где x - бегущее целое число, а y - выход треугольной волны. А - амплитуда волны, а Р - полупериод. Например, A = 5 будет производить волну, которая идет от 0 до 5; P = 10 будет генерировать волну с периодом 20. Волна начинается при y = 0 при x = 0.
Обратите внимание, что y будет числом с плавающей запятой, если P не является коэффициентом A. И, да, для математических пуристов: A технически в два раза больше амплитуды волны, но посмотрите на картинку ниже, и вы поймете, что я имею в виду.
Визуализация:
y = abs( amplitude - x % (2*amplitude) )
Изменение длины волны просто требует фактора для x
.
Изменить: то, что я называю амплитудой, на самом деле не является амплитудой, а максимальным значением (т.е. 5, если кривая осциллирует между 0 и 5). Амплитуда в математическом смысле составляет половину этого. Но вы понимаете.
Я знаю, что это старый пост, но для тех, кто ищет что-то подобное, которое я рекомендую посмотреть. http://en.wikipedia.org/wiki/Triangle_wave
Последняя формула y (x) = (2a/π) arcsin (sin ((2π/p) * x))
или.
(2 * amplitudeConstant / Math.PI) * Math.Asin(Math.Sin(2 * (Math.PI / periodConstant) * Convert.ToDouble(variableX)))
Попробуйте следующее:
x = m - abs(m - 2*(i++ % m))
Вот периодическая функция, которая выглядит как далекое синусоидальное приближение; по существу, это синующий параболоид, используя квадрат 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;
}
Я тестировал его с помощью простого цикла, и вы, ребята, вообще не ответили на вопрос о человеке. Вырезание и склеивание не помогут людям. Неудивительно, что так много мистификаций в средствах массовой информации имеют такой успех. С людьми, которые повторяют ошибки других, которые не могут быть неожиданными. И люди даже дают положительную репутацию за эти неправильные ответы?! Невероятно! Но опять же, это совпадает с моим предыдущим замечанием.
Итак, во-первых, мы собираемся объяснить нашим людям, что такое волна TRIANGLE. Ну, это волна, которая имеет период, состоящий из двух одинаковых наклонных рамп. Рампа наклонена вверх и рампой, равно как и первая, но наклонная вниз, в отличие от SAWTOOTH, у которой наклонный скошенный наклон или крутизна наклонена вниз, после повторного талуда.
PS: Последний, который дал "y (x) = (2a/π) arcsin (sin ((2π/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)
= > Я нашел источник, который точно определяет, что ответ в математической нотации: http://mathworld.wolfram.com/TriangleWave.html
Я тестировал формулу в программе Linux под названием KmPlot. Пользователи Linux могут получить kmplot через корневой терминал, набрав apt-get install kmplot, и если это не сработает, попробуйте использовать обычный терминал и введите sudo apt-get install kmplot, и если это не сработает, смотрите это видео YouTube для общих инструкций по установка программы Linux http://www.youtube.com/watch?v=IkhcwxC0oUg
SO A CORRECT ANSWER к вопросу о потоке является примером объявления симметричной треугольной функции в форме С++, показанной ниже:
(...)
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!