Some time ago I came across a gif of a torus which was made of a bunch of waves. In the gif non empty space corresponded to larger amplitudes and frequencies, and it had a really cool overall effect. Unfortunately I cannot find the original image, but I was really inspired to try and figure out a way to construct something similar.
After experimenting for a couple of days, I came up with a system to encode an n by m bitmap – represented by a 2d array of numbers in the range 0 to 1 – and use that to draw a series of discrete waves that correspond to some ‘pixel’ in that bitmap.
The basic setup is to draw one wave per pixel row in the bitmap, extending from 0 to the width of the canvas. The wave has then as many samples as columns in the bitmap. Though not the exact code, the height of a given point on the wave is calculated pretty much like:
// Calculate wave height
const waveHeightAtPoint = bitmap[y][i] * sin(time+i+y) * maximumHeight
So when the bitmap ‘pixel’ has a value of 0, the height is a normal, unchanged line, but a non zero value will cause the wave to get some height, which could be either positive or negative sin has a range of [-1, 1].
To add interest to the image a few other modulations are introduced, such as varying the thickness of each line, the maximum amplitude (height), introducing random noise, upsampling and downsampling the arrays, blurring by taking averages of lines above and below, etc. The end result is pretty cool and can be found here.
Lastly I built a tiny little grid editor to build the bitmaps which outs an array to the console. That can be found here.