Guye Incognito
Guye Incognito

Reputation: 2844

making a sine wave steeper?

I've written a a little function that gives me out a value based on a sine wave when I put in a float between 0 and 1. I'm using it to lerp things around in a game.

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

It works fine.. But I was wondering is there a mathematical way of altering the sine wave so I can make it 'steeper' or 'shallower' in the middle? In the diagram below the blue curve is a sine wave, I'm wondering if I can make it more like the green line.

enter image description here

Upvotes: 21

Views: 13812

Answers (7)

Luca
Luca

Reputation: 41

I think I found the solution.

(0.5+sin(x*π-π/2)/2)^((2*(1-x))^k)

in the interval x = [0.0, 1.0]

with k that control the steepness.
k=0.0 for the unmodified sinus (purple)
k=1.0 (green)
k=2.0 (blue)

enter link description here https://www.desmos.com/calculator/wdtfsassev

Upvotes: 4

commonpike
commonpike

Reputation: 11185

what about

sign(sin(x))*sqrt(abs(sin(x))

https://www.desmos.com/calculator/5nn34xqkfr

enter image description here

Upvotes: 2

kanthonyjr
kanthonyjr

Reputation: 31

Graph of a steeper sine wave function

I discovered this nifty trick for a steeper sine wave (0..1).

f(x) = cos(sin(x)^3)^10

If you need (-1..1):

2 * (f(x) - 0.5)

Upvotes: 3

duesterdust
duesterdust

Reputation: 87

You can root the sine function to make it steeper (only working for positive values). The higher the root, the steeper the sine.

enter image description here

Upvotes: 3

biertje72
biertje72

Reputation: 95

I was looking for a similar function, not for the whole sine but just half the period. I bumped into the Logistic function:

f(x) = L / (1 + e^(-k(x-x0)))

where
e = the natural logarithm base (also known as Euler's number),
x0 = the x-value of the sigmoid's midpoint,
L = the curve's maximum value, and
k = the steepness of the curve.

See https://en.wikipedia.org/wiki/Logistic_function Works for me

Upvotes: 1

Motla
Motla

Reputation: 1230

You can use the y(x) = 1-(1-x)^n function when x = [0..1], as a transform function.

You will just have to replace x by the absolute value of your sinus and report the sign of sinus to the result. In that way you can tweak the sinus slope by increasing n. So what you want is this:

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

Upvotes: 9

user180247
user180247

Reputation:

What you're showing already isn't really sine - the range of sine is between -1 and +1. You're applying the linear function f(x) = (x+1)/2 to change that range. So place another function between the sine and that transform.

To change the shape, you need a non-linear function. So, here's a cubic equation you might try...

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

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

The parameter p should be given a value between 0.0 and 9.0. If it's 1.0, g(x) is the identity function (the output is the unmodified input). With values between 0.0 and 1.0, it will tend to "fatten" your sine wave (push it away from 0.0 and towards 1.0 or -1.0) which is what you seem to require.

I once "designed" this function as a way to get "fractal waveforms". Using values of p between 1.0 and 9.0 (and particularly between around 3.0 and 6.0) iterative application of this formula is chaotic. I stole the idea from the population fluctuation modelling chaotic function by R. M. May, but that's a quadratic - I wanted something symmetric, so I needed a cubic function. Not really relevant here, and a pretty aweful idea as it happens. Although you certainly get chaotic waveforms, what that really means is huge problems with aliassing - change the sample rate and you get a very different sound. Still, without the iteration, maybe this will give you what you need.

If you iterate enough times with p between 0.0 and 1.0, you end up with a square wave with slightly rounded corners.

Most likely you can just choose a value of p between 0.0 and 1.0, apply that function once, then apply your function to change the range and you'll get what you want.

By the way, there's already a comment suggesting a cheat sheet of "easing functions". "Easing" is a term from animation, and computer animation software often uses Bezier curves for that purpose - the same Bezier curves that vector graphics software often uses. Bezier curves come in quadratic and cubic variants, with cubic being the more common. So what this is doing probably isn't that different. However, cubic Bezier easing gives you more control - you can control the "ease-in" independently of the "ease-out", where my function only provides one parameter.

Upvotes: 10

Related Questions