secret formula for the "sin" wave with variable rising/falling edge

1.5k Views Asked by At

My math is pretty much forgotten. I was wondering if someone can take a look at this and share what's the formula for creating something like this.

https://drive.google.com/file/d/0BxEDZ5UtsbsxMmswMENDcGJXdUU/view

The first slider controls the "rising" speed. the second one controls the "falling" speed. The small circle in the middle is not taken into account. There is also this article in Chinese.


Solution in Java:

  private float sine(float t, float rising_time) {
        return (float) (1 + Math.sin(Math.PI * t / rising_time));
    }

    private float secret_wave(double t, float a, float b) {

        float r = (float) ((t + (a / 2)) % (a + b));
        float t_prime = r - (a / 2);

        if (r <= a) {
            return sine(t_prime, a);
        } else {
            return sine(t_prime - ((a - b) / 2), b);
        }
    }

It can be used like this:

 float xsamples[] = new float[5000];
        int counter = 0;
        for (double i = 0; i < 500; i = i + 0.1) {
            xsamples[counter] = secret_wave(i, slider_1_value, slider_2_value);
            counter = counter + 1;
        }
2

There are 2 best solutions below

0
On BEST ANSWER

This looks like a periodic repetition of a wave formed by pasting together two sine waves: one that "rises" in $a$ seconds and one that "falls" in $b$ seconds.

A formula for a sine wave which falls or rises in $T$ seconds is $\sin\left(\frac{\pi x}{T}\right).$ Let's call this function $\sin_T$, like so: $$\sin_T(x) = \sin\left(\frac{\pi x}{T}\right).$$

TL, DR

One possible definition of the secret wave function in terms of the $\sin_T(x)$ function just defined and rising and falling times $a$ and $b$ is given at the bottom of the answer .

Detailed explanation

Indeed, $\sin\left(\frac{\pi x}T\right)$ achieves its peaks when $\frac{\pi x}T$ equals $\frac \pi2, \frac \pi2 + 2\pi, \frac \pi2 + 4\pi, \dots$ etc. Solving for $x$ we get

\begin{align} \frac{\pi x}{T} &= \frac \pi2 + k\cdot2\pi \\ \implies x&= \frac T2 + k\cdot2T, \end{align} which tells us that the period is $2T$ ($T$ for rising and $T$ for falling).

A good way to construct the asymmetrical wave of your animation is to define it first in an interval containing the origin and then repeating it in a periodic fashion.

Let's start with $\sin_a(x)$. We know that its value at $x=0$ is $0$, and that we want a single "rise". From the equations above, its closest peak happens at $x=\frac a2. $ By the sine's symmetry, we can infer that its closest minimum happens at $x=-\frac a2$.

According to this, the secret formula can be defined as $\sin_a(x)$ for $x\in\left[-\frac a2,\frac a2\right]$.

Now we must paste the falling side of $\sin_b$ to the right of $\sin_a$ in continuous way. We can achieve this by shifting the former so that it has a peak at $x=\frac a2$.

A peak of $\sin_b$ occurs at $x=\frac b2$. We define a translated version of it, $\sin_b(x-\tau)$, that achieves a peak at $x=\frac a2$ by the condition $$\frac a2-\tau = \frac b2 \implies \tau = \frac {a-b}2.$$

Starting from $x=\frac a2$ it should fall for $b$ seconds, so the secret formula can be defined as $\sin_b\left(x-\frac{a-b}{2}\right)$ for $x\in \left(\frac a2,\frac a2 + b\right)$.

Now that we defined the function in the interval $I = \left[-\frac a2, -\frac a2 + (a+b)\right)$ we can complete the definition for all $x$. One way to do it is using the modulo operator "%", like so:

Definition

$$\text{secretWave}(x) = \begin{cases} \sin_a\left(r- \frac a2\right), & \text{if } r = \left( x+\frac a2\right) \bmod (a+b) \text{ and }r\le a \\ \sin_b\left(r-\frac a2 - \frac{a-b}2\right) & \text{if } r = \left( x+\frac a2\right) \bmod (a+b) \text{ and }r> a. \end{cases}$$

Edit

Here is a plot of a Python implementation of the final version with $a=4, b=1$ using matplotlib.

secretWave

2
On

Edit

Assuming the the two values at the bottom of the video represent time from the trough to a peak (time up) on the left, and the time from a peak to a trough (time down) on the right, then this could be a piecewise function. Essentially, sewing together two sine (or cosine) functions so that the period of the "upstroke" portion is (possibly) different than the period of the "downstoke" portion.

If the two values are the same, one can easily accomplish this with a function like: $f(x)=A\sin(Bx)$ where $B=\frac{\pi}{T}$ where $T$ is the length of time for the upstroke (also the length of time for the downstroke).

If the two values are not the same, say $T_u$ and $T_d$ (for the time to go up and the time to go down). Then one can create a piecewise function as follows:

$$f(x) = \begin{cases} A\cos\left(\frac{\pi}{T_{d}}x\right) & \text{if }x\in [0, T_d) \\ A\cos\left(\frac{\pi}{T_{u}}x-\pi\left(\frac{T_d}{T_u}-1\right) \right) & \text{if } x\in [T_d, T_d+T_u)\end{cases}$$

Then, to make the function periodic, you just take the $x$-value modulo $T_d+T_u$ (i.e. scale it the same way one would to ensure that $x\in [0, 2\pi)$).

The choices of $\frac{\pi}{T_{u}}$ and $\frac{\pi}{T_{d}}$ are chosen to ensure that half the period of the function is either $T_{u}$ or $T_{d}$ at the right point in time. The shift is chosen so that at time $T_{d}$ the two functions match up at a trough.