Constructing a "blip" noise function

304 Views Asked by At

(Pardon me if my terminology is too botched up, corrections are welcome.)

For my animation code I'm looking for a peculiar 1D noise function $f(t)$.

The function should produce "random" "blips":

enter image description here

A "blip" is a "peak", consisting of an "upward slope" ($f(t) \in 0..1$), a "plateau" ($f(t) = 1$) and a "downward slope" ($f(t) \in 1..0$). Between blips $f(t) = 0$. Both slopes are linear (or close to that, e.g. $max(0, min(1.5 * sin(x), 1))$ will do), peak is symmetrical.

Distance between blips should appear to be "random" to a human being. (In the same sense as the Perlin noise appears to be random. Note that I can not use system random generator here, "randomness" should be built in the function itself.)

I should be able to adjust minimal and maximal distance between peaks, and blip parameters: slope width (it should be symmetrical) and plateau width. All blips should be identical (or very similar). I should also be able to control the "seed" of blip "randomness" (but I guess that adding a constant to $t$ should do it).

The function should not be unreasonably computationally expensive.

Any clues on how to construct such a function?

3

There are 3 best solutions below

1
On

You can most likely achieve 'random-looking' blips with a function. You cannot achieve random blips, because a function does not produce randomness: functions are deterministic.

So how do you 'space' the blips so they look random? Well, you could use a piecewise function for $f(x)$ that always returns $0$, but returns $1$ in particular cases --- the particular case can simply be a case that is so complex and abstruse that it seems random to an onlooker.

I would suggest something like $$f(x) = \begin{cases} 1 \quad\text{if } \text{round}(\sin{x^3}) \mod 17 = 16 \\ 0 \quad \text{else} \end{cases}$$ On a manual inspection for integer values in $[0,200]$, that looks pretty unpredictably random. Adjust for a continuous variable by seeing Ross Millikan's answer.

7
On

You have a nice piecewise linear function there, which is very quick to compute. If your slope is $s$ and the time at the top is $r$ you have $$f(t)=\begin {cases} st&0 \lt t \lt \frac 1s\\ 1& \frac 1s \lt t \lt \frac 1s+r\\1-s(t-\frac 1s-r)&\frac 1s+r \lt t \lt \frac 2s+r \end {cases}$$ When you finish one blip, throw a random number for the time of the start of the next blip and offset the times accordingly.

3
On

You could try something like this... Set the location of the $n$th blip to be $$\tau(n) = n+A_1\sin(2\pi (f_1n + u_1))+A_2\sin(2\pi(f_2n + u_2))$$ where $f_1$ and $f_2$ are irrational numbers, $u_1$ and $u_2$ are random seeds in $[0,1)$, and $A_1$ and $A_2$ control the minimal and maximal distance between peaks via some trigonometry that you can work out. On short scales, this should look random to a human. Then, for any $t$, round $t$ to the nearest integer to find the location of the nearest blip, $\tau([t])$, and evaluate $$f(t)=g(t-\tau([t]))$$ where $g$ defines the shape of the blip. (For this procedure to work, the support of $g$ should be narrower than the minimal distance between peaks.)

Edit to respond to questions...

The function $g(x)$ should describe a single blip centered at $x=0$. For example, we could use a parabola $g(x)=\max\{0, 1-(x/r)^2\}$, where $r$ is another tunable parameter: the radius of the blip. You would want $r$ to be small, on the order of $0.1$, to get something like your diagram. Or you can set $g$ to be a piecewise linear function, if you want a wide plateau. There's a lot of flexibility. Mathematically, we are convolving $g$ with a pulse train. (I think this sort of noise is generally called "sparse convolution noise", but don't take my word for it.)

The frequencies $f_1$ and $f_2$ should probably be irrational because you don't want there to be obvious, regular patterns. For example, if $f_1=1/2$, then that term moves every other peak to the right or the left, by the same distance. I don't think that would "look" random, but it's an artistic decision. You could try it and make your own judgement. By the way, ordinary floating-point numbers can't exactly represent irrational numbers like $\sqrt2$, but they can come close. When I say that $f_n$ should be irrational, I really mean that it shouldn't be too close to a rational number with a small denominator.

If $A_1=A_2=0$, then each interval between peaks is exactly $1$. Otherwise, if $A_1$ and $A_2$ are both positive, then each interval is somewhere between $1-A_1-A_2$ and $1+A_1+A_2$. Note that the previous sentence is not a tight bound on the intervals between peaks. If you need tight bounds, you'll have to work through some trig to calculate $\tau(n+1)-\tau(n)$, which I haven't done myself, but it shouldn't be too hard.