Sine and Cosine
Intro
This is the first of many planned articles on the topic of demoscene programming.
Demos are self contained artistic presentations that are sometimes punctuated by extremely efficient and small code.
Demoscene developers were typically restricted to extremely limited hardware and storage mediums. While this is
hardly the case today, I find it prudent to still approach experimentation and learning with this in mind,
especially when your average, basic node project contains thousands of packages. Yes, I'm a hater, but there's
something special there.
Join me as I explore the core concepts of demoscene development from the context of a
modern developer interested in learning what it means to get back to basics and develop such incredible works.
I just want to highlight: demos were mind-blowing, and the computers they were made on/for could essentially trade blows with an NES, and were just barely 1980's technology. Check out the video here for examples.
Enough talk
A sinusoidal (sin) wave is what you get plot the 360° circumference of a circle as distance from the resting plane over time.
Sine and cosine functions relate to the expression of the phase of a sine wave either in forward or backwards direction respectively.
As such, sine and cosine functions (as we enjoy them from math libraries) produce a number between -1 and 1 given an input angle.
They're used heavily across animations to produce repeating angular values. Take this example of a ball following the circumference of a circle:
const pX = Math.cos(timestamp / timeCoefficient) * rad const pY = Math.sin(timestamp / timeCoefficient) * rad
Combinations of different mathematical functions can create cool effects, such as this one where the output "particle" follows in a radial fashion around an orbiting point on our circle.
In the example here, the orbit on our primary circle is represented by the blue dot.
Our satellite is represented by the orange dot, which is added as an offset to the blue dot's coordinates. Note that it's circling the blue dot 8 times per rotation of the larger circle at half the larger circle's radius.
const particlePX = Math.cos(timestamp / timeCoefficient * 8) * (rad / 2) const particlePY = Math.sin(timestamp / timeCoefficient * 8) * (rad / 2)
When combined with text, sine can easily create a bouncing letter effect:
const vOffset = Math.sin((timestamp + (key * 360)) / timeCoefficient) * 25
And with some color and size function?! It's actually a lot simpler than it appears. We're spoiled with easy HSL color functions that weren't present in the C64 days with which we can leverage browser native radial color calculation features.
for (const key in inputStr) { const vOffset = Math.sin((timestamp + (key * 360)) / timeCoefficient) * 36 ctx.font = `${32 + Math.cos((timestamp + (key * 360)) / timeCoefficient) * 16}px monospace`; ctx.fillStyle = `hsl(${Math.cos((timestamp + (key * 360)) / timeCoefficient) * 180} ,50%, 50%)` ctx.strokeStyle = ctx.fillStyle ctx.lineWidth = '8px' ctx.fillText(inputStr[key], key * 25 + 15, (canvasDims.height / 2) + vOffset); }
Thanks!
That's it for sine and cosine. I'll be doing more of a deep dive no doubt in using these in more advanced ways, so please do join me next time :)