Esiste una funzione a una riga che genera un’onda triangular?

In modo simile, il modulo genera un’onda a dente di sega. Non deve essere continuo.

ecco cosa intendo:

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

genera una sequenza 0..9, tre volte che assomiglia a questo:

grafico dell'onda a dente di sega

nota che la pendenza sul lato destro del picco è solo un artefatto grafico

L’one-liner in questo caso è x = i ++% m


Quello che voglio è questo:

grafico ad onda triangolare

Se conosci le one-liner per le altre forms d’onda (seno, quadrato), sarebbe bene saperlo.

Aggiornamento : le risposte di tutti sono state molto utili e ho una domanda di follow-up.

Cosa si aggiungerebbe alla funzione d’onda triangular per rendere la curva delle linee curva dentro o fuori in questo modo:

forme d'onda sporgenti

Grazie a tutti , le vostre varie risposte mi hanno aiutato a vedere il problema da una prospettiva più ampia. Un ringraziamento speciale a Noldorin per la sua interpretazione di estendere l’equazione alle curve quadratiche.

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

Onda triangular

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

Questo dà un’onda triangular del periodo 6, oscillante tra 3 e 0.

Onda quadra

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

Questo dà un'onda quadra regolare del periodo 6, oscillante tra 3 e 0.

Onda sinusoidale

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

Questo dà un'onda sinusoidale di periodo 20 pi , oscillante tra 3 e -3.


Aggiornare:

Onda triangular sinuosa

Per ottenere una variazione dell'onda triangular con curve piuttosto che linee rette, è sufficiente introdurre un esponente nell'equazione per renderlo quadratico.

Curve concave (cioè forma x^2 ):

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

Curve concave (cioè forma sqrt(x) ):

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

In alternativa all'utilizzo della funzione pow , potresti semplicemente definire una funzione square e usare la funzione sqrt in math.h , che probabilmente migliorerebbe un po 'le prestazioni.

Inoltre, se vuoi rendere le curve più ripide / meno profonde, prova a cambiare gli indici.


In tutti questi casi dovresti facilmente essere in grado di regolare le costanti e aggiungere fattori di scala nei punti giusti per dare variazioni delle forms d'onda date (diversi periodi, amplessi, asimmetrie, ecc.).

Espansione sulla risposta di Eric Bainville:

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

Dove x è un numero intero in esecuzione e y l’uscita dell’onda triangular. A è l’ampiezza dell’onda e P il semiperiodo. Ad esempio, A = 5 produrrà un’onda che va da 0 a 5; P = 10 produrrà un’onda con un periodo di 20. L’onda parte da y = 0 per x = 0.

Nota che y sarà un numero in virgola mobile a meno che P non sia un fattore di A. E, sì, per i puristi matematici: A è tecnicamente il doppio dell’ampiezza dell’onda, ma guarda l’immagine qui sotto e capirai cosa significare.

visualizzati:

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

Cambiando la lunghezza d’onda serve solo un fattore per x .

Modifica: Ciò che chiamo ampiezza in realtà non è l’ampiezza, ma il valore massimo (cioè 5 se la curva oscilla tra 0 e 5). L’ampiezza in senso matematico è metà di questo. Ma hai capito il punto.

So che questo è un vecchio post ma per tutti quelli che cercano qualcosa di simile consiglio di guardare. http://en.wikipedia.org/wiki/Triangle_wave

L’ultima formula y (x) = (2a / π) arcsin (sin ((2π / p) * x))

o.

 (2 * amplitudeConstant / Math.PI) * Math.Asin(Math.Sin(2 * (Math.PI / periodConstant) * Convert.ToDouble(variableX))) 

Prova questo:

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

Ecco una funzione periodica che sembra un’estensione sinusoidale lontana; essenzialmente è un paraboloide sinuante, usando X al quadrato:

 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; } 

L’ho provato con un ciclo semplice e voi ragazzi non avete affatto risposto alla domanda dell’uomo. Tagliare e incollare non aiuterà le persone. Non c’è da meravigliarsi che così tanti falsi mass media abbiano così tanto successo. Con gente che ripete gli errori di altri che non può essere una sorpresa è. E le persone danno persino dei tassi di reputazione positivi per queste risposte sbagliate ?! Incredibile! Ma di nuovo, questo è in parallelo con la mia precedente osservazione.

Quindi per prima cosa spiegheremo alla nostra gente che cos’è un’onda TRIANGLE. Bene, è un’onda che ha un periodo composto da DUE rampe inclinate uguali. Una rampa è scesa in SU e una rampa equamente come la prima, ma è scesa in GIÙ in contrasto con un SAWTOOTH che ha una rampa in salita UP o una rampa in discesa GIÙ ripetuta dopo un talud invertito.

PS: L’ultimo che ha dato “y (x) = (2a / π) arcsin (sin ((2π / p) * x))” è troppo complicato, stiamo cercando una veloce routine c ++ quindi la trigonometria è assolutamente fuori la domanda.

Routine di prova:

(…)

 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) 

=> Ho trovato una fonte che dice esattamente quale sia la risposta in notazione matematica: http://mathworld.wolfram.com/TriangleWave.html

Ho testato la formula su un programma Linux chiamato KmPlot. Gli utenti Linux possono ottenere kmplot tramite il terminale root digitando apt-get install kmplot e se non funziona provare a utilizzare il terminale regolare e digitare sudo apt-get install kmplot e se non funziona guarda questo video di youtube per le istruzioni generali su installazione di un programma Linux http://www.youtube.com/watch?v=IkhcwxC0oUg

COSÌ UNA RISPOSTA CORRETTA alla domanda thread è un esempio di una dichiarazione di funzione triangolo simmetrico in forma c ++ mostrata di seguito:

(...)

 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!