c-是否有生成三角波的单线函数?

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

这是我的意思:

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将方程式扩展为二次曲线的方法。

willc2 asked 2019-10-08T23:45:56Z
8个解决方案
87 votes

三角波

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

这给出了周期为6的三角波,在3至0之间振荡。

方波

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

这给出了周期为6的规则方波,在3至0之间振荡。

正弦波

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

这给出了周期为pow的正弦波,在3到-3之间振荡。


更新:

弯曲的三角波

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

凹曲线(即pow形状):

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

凹曲线(即pow形状):

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

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

另外,如果要使曲线更陡峭/更浅,只需尝试更改索引。


在所有这些情况下,您都应该能够轻松地调整常数并在正确的位置添加缩放因子,以给出给定波形的变化(不同的周期,振幅,不对称性等)。

Noldorin answered 2019-10-08T23:47:40Z
29 votes

扩展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开始。

请注意,除非P是A的因数,否则y将是浮点数。而且,是的,对于数学纯粹主义者:A在技术上是波幅的两倍,但是看看下面的图片,您就会明白我的意思。

可视化:

Lightsider answered 2019-10-08T23:48:24Z
22 votes
x = m - abs(i % (2*m) - m)
Eric Bainville answered 2019-10-08T23:46:00Z
5 votes
y = abs( amplitude - x % (2*amplitude) )

更改波长仅需要x的一个因素。

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

balpha answered 2019-10-08T23:48:56Z
5 votes

我知道这是一篇旧文章,但对于任何正在寻找类似内容的人,我建议您关注一下。[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)))
Morgan answered 2019-10-08T23:49:34Z
0 votes

试试这个:

x = m - abs(m - 2*(i++ % m))
bubaker answered 2019-10-08T23:49:53Z
0 votes

这是一个看起来像遥远的正弦近似值的周期函数; 本质上是使用X平方的Sinuating抛物面:

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;

}
com.prehensible answered 2019-10-08T23:50:18Z
-2 votes

我已经用一个简单的循环测试了它,你们根本还没有回答这个人的问题。 剪切和粘贴不会帮助人们。 难怪如此众多的大众媒体骗局取得了如此巨大的成功。 与一个重复别人的错误的人一起,这不足为奇。 人们甚至为这些错误答案给出正面的声誉率? 难以置信的! 但是,这再次与我先前的言论相吻合。

因此,首先,我们将向我们的人们解释三角波是什么。 好吧,它是一个波,其周期由两个相等的倾斜斜坡组成。 与SAWTOOTH相反,斜面向上倾斜并且斜面与第一斜面相同,但是斜面向下倾斜,与SAWTOOTH相反。

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用户可以通过root终端输入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));
}

(......)

Cheerz!

user232365 answered 2019-10-08T23:51:31Z
translate from https://stackoverflow.com:/questions/1073606/is-there-a-one-line-function-that-generates-a-triangle-wave