2014-02-27 15 views
12

Ich habe eine kleine Funktion geschrieben, die mir einen Wert basierend auf einer Sinuswelle ausgibt, wenn ich einen Gleitkomma zwischen 0 und 1 setze. Ich verwende es zu lerp Dinge in einem Spiel herum.eine Sinuswelle steiler machen?

public static class Utilities 
{ 
    public static float SineMe(float prop) 
    { 
     float output = (prop*180f)-90f; 

     output = Mathf.Sin(output*Mathf.Deg2Rad); 

     output = (output+1f)/2f; 

     return output; 
    } 
} 

Es funktioniert gut .. Aber ich frage mich, ist es eine mathematische Möglichkeit, die Sinuswelle zu verändern, so kann ich es steiler "machen oder‚flache‘in der Mitte? In dem Diagramm unten ist die blaue Kurve eine Sinuswelle, ich frage mich, ob ich es mehr wie die grüne Linie machen kann.

enter image description here

+1

Wollen Sie damit sagen Sie etwas mehr wollen wie 'y = ((2 * sin (x))^2)/4' als 'y = sin (x)'? –

+4

Sie könnten sich für den [Beschleunigungs-Spickzettel] (http://easings.net/) interessieren, der Ihnen helfen kann, eine Kurve mit zufriedenstellender Steilheit zu finden. Dann können Sie die Quelle für diese Kurve [hier] (http://www.robertpenner.com/easing/) nachschlagen. – Kevin

+0

Jeder Tangente/Tangens würde tun. – moonwave99

Antwort

6

Was Sie zeigt schon nicht wirklich Sinus - der Bereich der Sinus zwischen -1 und +1. Sie wenden die lineare Funktion f(x) = (x+1)/2 an, um diesen Bereich zu ändern. Setzen Sie also eine andere Funktion zwischen den Sinus und das transformieren.

Um die Form zu ändern, benötigen Sie eine nichtlineare Funktion. So, hier ist eine kubische Gleichung Sie könnten versuchen, ...

g(x) = Ax^3 + Bx^2 + Cx + D 

D = 0 
C = p 
B = 3 - 3C 
A = 1 - (B + C) 

Der Parameter p einen Wert zwischen 0,0 und 9,0 gegeben werden soll. Wenn es 1,0 ist, ist g (x) die Identitätsfunktion (die Ausgabe ist die unmodifizierte Eingabe). Mit Werten zwischen 0.0 und 1.0 wird es dazu neigen, Ihre Sinuswelle zu "mästen" (schieben Sie sie von 0.0 weg und auf 1.0 oder -1.0), was Sie zu benötigen scheinen.

Ich einmal "entworfen" diese Funktion als eine Möglichkeit, "fraktale Wellenformen" zu bekommen. Unter Verwendung von Werten von zwischen 1,0 und 9,0 (und insbesondere zwischen etwa 3,0 und 6,0) ist die iterative Anwendung dieser Formel chaotisch. Ich habe die Idee aus der chaotischen Funktion der Schwankung der Bevölkerungsfluktuation von R. M. May gestohlen, aber das ist eine quadratische - ich wollte etwas symmetrisches, also brauchte ich eine kubische Funktion. Nicht wirklich relevant hier, und eine ziemlich schlimme Idee, wie es passiert. Obwohl Sie sicherlich chaotische Wellenformen bekommen, was das wirklich bedeutet, sind riesige Probleme mit Aliasing - Ändern Sie die Samplerate und Sie erhalten einen ganz anderen Sound. Aber ohne die Iteration wird dir das vielleicht das geben, was du brauchst.

Wenn Sie häufig genug mit p zwischen 0,0 und 1,0 iterieren, erhalten Sie eine Rechteckwelle mit leicht abgerundeten Ecken.

Wahrscheinlich können Sie nur einen Wert von p zwischen 0,0 und 1,0 wählen, wenden Sie diese Funktion einmal an, dann wenden Sie Ihre Funktion an, um den Bereich zu ändern, und Sie werden bekommen, was Sie wollen.

Übrigens gibt es bereits einen Kommentar, der einen Spickzettel von "Beschleunigungsfunktionen" vorschlägt. "Easing" ist ein Begriff aus der Animation, und Computeranimationssoftware verwendet zu diesem Zweck oft Bezier-Kurven - die gleichen Bezier-Kurven, die Vektorgrafiken oft verwenden. Bezier-Kurven kommen in quadratischen und kubischen Varianten vor, wobei kubische Varianten häufiger sind. Was das macht ist wahrscheinlich nicht so anders. Kubisches Bezier-Easing gibt Ihnen jedoch mehr Kontrolle - Sie können das "Ease-In" unabhängig vom "Ease-Out" steuern, wobei meine Funktion nur einen Parameter bereitstellt.

4

Sie können die y(x) = 1-(1-x)^n-Funktion als x = [0..1] als Transformationsfunktion verwenden.

Sie müssen nur x durch den absoluten Wert Ihrer sinus ersetzen und melden Sie das Zeichen sinus zu dem Ergebnis. Auf diese Weise können Sie die Sinusflanke verändern, indem Sie n erhöhen.Also, was Sie wollen, ist dies:

float sinus = Mathf.Sin(output*Mathf.Deg2Rad); 
int sign = (sinus >= 0 ? 1 : -1); 

int n = 4; // slope parameter 

float waveform = sign * (1-Mathf.Pow(1-Mathf.Abs(sinus), n));