Gibt es eine einzeilige Funktion, die eine Dreieckswelle erzeugt?

Lesezeit: 5 Minuten

Benutzeravatar von willc2
willc2

In ähnlicher Weise das modulo erzeugt eine Sägezahnwelle. Es muss nicht durchgehend sein.

hier ist was ich meine:

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

erzeugt eine Sequenz 0..9, dreimal, die so aussieht:

Sägezahnwellendiagramm

Beachten Sie, dass die Steigung auf der rechten Seite des Peaks nur ein grafisches Artefakt ist

Der Einzeiler ist in diesem Fall x = i++ % m


Was ich will ist folgendes:

Dreieckswellendiagramm

Wenn Sie Einzeiler für die anderen Wellenformen (Sinus, Rechteck) kennen, wäre das auch gut zu wissen.

Aktualisieren: Alle Antworten waren sehr hilfreich und ich habe eine Anschlussfrage.

Was würde der Dreieckswellenfunktion hinzugefügt werden, um die Neigung der Linien wie folgt nach innen oder außen zu krümmen:

pralle Wellenformen

Danke an alle, Ihre vielfältigen Antworten haben mir geholfen, das Problem aus einer größeren Perspektive zu sehen. Besonderer Dank geht an Noldorin für seinen Versuch, die Gleichung auf quadratische Kurven zu erweitern.

  • Warum müssen sie “Einzeiler” sein?

    anon

    2. Juli 2009 um 10:25 Uhr

  • ich denke du meinst x = x++ % m?

    – Noldorin

    2. Juli 2009 um 10:25 Uhr

  • @Neil Weil ich weiß, wie man sie mit for-Schleifen und if-Anweisungen macht. Ich möchte einen eleganteren Weg, um solche Dinge zu tun. @Noldorin Neuling lernt etwas

    – willc2

    2. Juli 2009 um 10:35 Uhr

  • @ willc2: Ich habe das jetzt in deiner Frage behoben. Ich hoffe, Sie haben nichts dagegen.

    – Noldorin

    2. Juli 2009 um 10:41 Uhr

  • (Wenn ich mir Ihren Code noch einmal ansehe, glaube ich, dass Sie tatsächlich meinen x = i++ % m.)

    – Noldorin

    2. Juli 2009 um 10:42 Uhr

Noldorins Benutzer-Avatar
Noldorin

Dreieckige Welle

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

Dies ergibt eine Dreieckswelle der Periode 6, die zwischen 3 und 0 oszilliert.

Rechteckschwingung

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

Dies ergibt eine regelmäßige Rechteckwelle der Periode 6, die zwischen 3 und 0 oszilliert.

Sinus

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

Dies ergibt eine Sinuswelle der Periode 20 pioszillierend zwischen 3 und -3.


Aktualisieren:

Kurvige dreieckige Welle

Um eine Variation der dreieckigen Welle zu erhalten, die eher Kurven als gerade Linien hat, musst du nur einen Exponenten in die Gleichung einführen, um sie quadratisch zu machen.

Konkave Kurven (zB x^2 Form):

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

Konkave Kurven (zB sqrt(x) Form):

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

Alternativ zur Verwendung der pow Funktion, könnten Sie einfach a definieren square funktionieren und verwenden die sqrt Funktion ein math.hwas die Leistung wahrscheinlich etwas verbessern würde.

Wenn Sie die Kurven steiler/flacher machen möchten, versuchen Sie einfach, die Indizes zu ändern.


In all diesen Fällen sollten Sie leicht in der Lage sein, Konstanten anzupassen und Skalierungsfaktoren an den richtigen Stellen hinzuzufügen, um Variationen der gegebenen Wellenformen (unterschiedliche Perioden, Amplituden, Asymmetrien usw.) zu erhalten.

  • Beachten Sie, dass mein x nicht Ihrem x in der Frage entspricht. Das hier verwendete x I stellt den herkömmlichen Wert entlang der x-Achse dar, und ähnlich stellt y den Wert entlang der y-Achse dar. Das x hier scheint das i in Ihrer Frage zu sein.

    – Noldorin

    2. Juli 2009 um 10:43 Uhr

  • Ich könnte diese Wellenformen hinzufügen, um auch kompliziertere zu erhalten, ja?

    – willc2

    2. Juli 2009 um 11:16 Uhr

  • Schwingt diese Dreieckswelle nicht zwischen 3 und 0?

    – Keith Smith

    2. Juli 2009 um 11:18 Uhr

  • @willc2: Ja, natürlich. 🙂 Wenn Sie sich fragen, wie Sie eine andere spezifische Wellenform erhalten, fragen Sie einfach, und ich kann Ihnen etwas vorschlagen – diese bieten jedoch gute Startblöcke.

    – Noldorin

    2. Juli 2009 um 12:01 Uhr

  • @JoanVenge: Die Subtraktion einer Konstante dient dazu, die Position der Kurve so zu versetzen, dass sie symmetrisch um die x-Achse ist. Somit ist 3 tatsächlich die Amplitude (die Hälfte des Peak-Trough-Abstands, der 6 ist). Das pow(..., 2.0) soll die quadratische Kurve bilden.

    – Noldorin

    27. Oktober 2012 um 23:33 Uhr

Benutzeravatar von Lightsider
Leichtschwester

Erweitern Sie die Antwort von Eric Bainville:

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

Wobei x eine laufende Ganzzahl und y die Dreieckswellenausgabe ist. A ist die Amplitude der Welle und P die Halbperiode. Zum Beispiel erzeugt A=5 eine Welle, die von 0 bis 5 geht; P=10 erzeugt eine Welle mit einer Periode von 20. Die Welle beginnt bei y=0 für x=0.

Beachten Sie, dass y eine Fließkommazahl ist, es sei denn, P ist ein Faktor von A. Und ja, für die mathematischen Puristen: A ist technisch gesehen doppelt so groß wie die Amplitude der Welle, aber schauen Sie sich das Bild unten an und Sie werden verstehen, was ich bedeuten.

Visualisiert:

zIovZ

  • Dies ist eine weitaus bessere Antwort, nur weil sie dokumentiert ist.

    – Tullo_x86

    25. November 2015 um 15:45 Uhr

  • Gleiche Formel mit P für Periode, nicht halb: y = (A/(P/2)) * ((P/2) – abs(x % (2*(P/2) – P/2) )

    – Tweepy

    24. November 2019 um 21:12 Uhr


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

Ich weiß, dass dies ein alter Beitrag ist, aber für alle, die nach etwas Ähnlichem suchen, empfehle ich, sich umzusehen.
http://en.wikipedia.org/wiki/Triangle_wave

Die letzte Formel y(x)=(2a/π)arcsin(sin((2π/p)*x))

oder.

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

Benutzeravatar von balpha
balpha

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

Das Ändern der Wellenlänge benötigt nur einen Faktor für x.

Bearbeiten: Was ich Amplitude nenne, ist eigentlich nicht die Amplitude, sondern der Maximalwert (dh 5, wenn die Kurve zwischen 0 und 5 oszilliert). Die Amplitude im mathematischen Sinne ist die Hälfte davon. Aber Sie verstehen, worauf es ankommt.

  • dies führt zu einer “V”-Welle; Sie müssten “y = m – y” hinzufügen, um eine Dreieckswelle zu erhalten

    – bubaker

    2. Juli 2009 um 10:58 Uhr

  • Eine Welle wird normalerweise als unendlich betrachtet, wodurch eine “V-Welle” und eine Dreieckswelle im Wesentlichen identisch sind. Aber Sie haben insofern recht, dass Sie eine Verschiebung vornehmen müssen, wenn Sie f (0) = 0 wollen.

    – balpha

    2. Juli 2009 um 11:09 Uhr

Versuche dies:

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

  • dies führt zu einer “V”-Welle; Sie müssten “y = m – y” hinzufügen, um eine Dreieckswelle zu erhalten

    – bubaker

    2. Juli 2009 um 10:58 Uhr

  • Eine Welle wird normalerweise als unendlich betrachtet, wodurch eine “V-Welle” und eine Dreieckswelle im Wesentlichen identisch sind. Aber Sie haben insofern recht, dass Sie eine Verschiebung vornehmen müssen, wenn Sie f (0) = 0 wollen.

    – balpha

    2. Juli 2009 um 11:09 Uhr

Benutzeravatar von David Gorsline
David Gorline

Hier ist eine periodische Funktion, die wie eine Annäherung an einen entfernten Sinus aussieht; Im Wesentlichen ist es ein sinuierendes Paraboloid, das X im Quadrat verwendet:

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;

}

1417250cookie-checkGibt es eine einzeilige Funktion, die eine Dreieckswelle erzeugt?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy