有没有一行函数可以产生一个三角波?

模块以类似的方式产生锯齿波,它不一定是连续的。

我的意思是:

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

请注意,山峰右侧的斜率只是一个图形化的人工制品

本例中的一行程序是 X = i + +% m


我想要的是:

triangle wave graph

如果您知道其他波形(正弦、正方形)的一行程序,那么也应该知道。

更新 : 每个人的回答都非常有帮助,我有一个后续问题。

在三角波函数中加入什么使得曲线的斜率如下所示:

bulging waveforms

谢谢大家,你们多样化的回答帮助我从更大的角度看问题。特别感谢 Noldorin 将方程推广到二次曲线。

74579 次浏览
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之间振荡。


更新:

曲线三角波

要得到有曲线而不是直线的三角波的变化,你只需要在方程中引入一个指数,使它成为二次方程。

凹曲线(即 x^2形状) :

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

凹曲线(即 sqrt(x)形状) :

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

除了使用 pow函数之外,您还可以简单地定义一个 square函数并在 math.h中使用 sqrt函数,这可能会稍微提高性能。

此外,如果你想让曲线更陡/更浅,只要尝试改变指数。


在所有这些情况下,你应该能够很容易地调整常数和添加比例因子在正确的地方给出给定波形的变化(不同的周期,振幅,不对称等)。

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

改变波长只需要 x的一个因子。

编辑: 我所说的振幅实际上不是振幅,而是最大值(如果曲线在0和5之间振荡,则为5)。数学意义上的振幅是它的一半。但你明白我的意思。

试试这个:

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;


}

我知道这是一个老职位,但任何人正在寻找类似的东西,我建议看看。 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)))

我用一个简单的循环来测试你们根本没有回答他的问题。剪切和粘贴对人们没有帮助。难怪这么多大众媒体的恶作剧如此成功。对于一个重复别人错误的人来说,这不足为奇。人们甚至会因为这些错误的答案而给出正面的评价? !难以置信!但同样,这与我之前的评论相似。

首先我们要向大家解释一下什么是三角波。这是一个波浪,它有一个周期,由两个相等的斜坡组成。一个斜坡向上倾斜,一个斜坡与第一个斜坡相同,但是倾斜向下,这与锯齿相反,锯齿有一个向上倾斜的斜坡,或者在一个反向的斜坡之后重复一个向下倾斜的斜坡。

PS: 上一个给出“ y (x) = (2a/π) arcsin (sin ((2π/p) * x))”的例子太复杂了,我们正在寻找一个快速的 c + + 例程,所以三角学是绝对不可能的。

例行测试:

(...)

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

我已经在一个名为 KmPlot 的 Linux 程序上测试了这个公式。Linux 用户可以通过根终端输入 apt-get install kmplot 获得 kmplot,如果不行,可以尝试使用常规终端输入 sudo apt-get install kmplot,如果不行,请观看这个 youtube 视频,了解安装 Linux 程序 http://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));
}

(...)

干杯!

对埃里克•班维尔(Eric Bainville)的回答进行了扩展:

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

其中 x 是一个正在运行的整数,y 是三角形波的输出。 A 是波的振幅,P 是半周期。例如,A = 5将产生一个从0到5的波; P = 10将产生一个周期为20的波。对于 x = 0,波从 y = 0开始。

注意 y 将是一个浮点数,除非 P 是 A 的因子。 而且,是的,对于数学纯粹主义者来说: 从技术上讲,A 是波的振幅的两倍,但是看看下面的图片,你就会明白我的意思。

视觉化: