I wrote to my old maths teacher on the internet, and posted a video of the LED VEST running the plasma algorithm. I noted that I had made it out of the Sin Cos and Tan mathematics he taught me 22 to years ago! He was rather exstatic.

So how do we make visual plasma using an algorithm?

You start by entering a value as x into a SIN(x) calculation. What you get back is a value between -1 and 1.

If we take the X value as being the pixel number accross X, and ignore the Y co-ordinate of each pixel for a moment….then chart out this returned value, normalized to be zero and 1, where zero is black and 1 is white with the shades of grey in between, we get an image like this:

SIN(x);

If we modify the algorithm a little, adding a Y coordinate, we can get a lean in the sine wave!

SIN((x + y) / 8.0);

If you were to combine two outputs together, summing them, you could get a mix of the two patterns:

sin(x) + sin(x+y);

If you then use the values between 0 and 1 to not represent brightness, rather represent HUE, the output looks like this:

If you take each X and Y pixel co-ordinate you can use this calculation to find the disstance to the centre pixel.

distance = sqrt((x – w / 2) * (x – w / 2) + (y – h / 2) * (y – h / 2));

and if you SIN the result you can make circles.

SIN(distance);

Cobine the circles with the horizontal and leaning results, then hue the result you get this:

But how do we make it move?

Simple….we add a TIME component to each of the VERTICAL, LEANING and CIRCLE equations!

- SIN(x+time)
- SIN((x + y + time) / 8.0);
- SIN( sqrt((x – w / 2) * (x – w / 2) + (y – h / 2) * (y – h / 2)) + time);

Add them all together, normalize to between 0 and 1, get the hue value, and generate the frame.

Repeat 25 times a second, ADVANCING THE TIME VALUE each frame.

You can ie for the C# plasma generator i used for the vest is here: https://github.com/finominal/LedVestPlasmaGenerator

I first did this in PROCESSING, and the code is quite simple.

*You can copy and past this into PROCESSING to see it in action.*

float movement = random(0,20); int brightness = 255; float size = 40; float maxReturnVal = 0; float speed = 0.07; void setup() { size(300, 300); background(0); loadPixels(); } void draw() { Plasma(); //Renders one frame of plasma. Animated through movement variable. } void Plasma() { int r = 0; int g = 0; int b = 0; float shade = 0; for(int h = 0; h < height; h++) { for(int w = 0; w < width; w++) { shade = SinVerticle(w,h,size) + SinRotating(w,h,size) + SinCircle(w,h, size)/3; r = (int)map( sin(shade*PI), -1, 1, 0, 255); g = (int)map( sin(shade*PI+2*PI/3), -1, 1, 0, 255); b = (int)map( sin(shade*PI+4), -1, 1, 0, 255); pixels[w+h*width] = color(r,g,b); } } movement+=speed;; updatePixels(); //if(maxReturnVal < shade) maxReturnVal = shade; } float SinVerticle(float x, float y, float size) { return sin(x / size + movement); } float SinRotating(float x, float y, float size) { return sin( (x * sin(movement/3 ) + y * cos(movement/4)) /(size) ) ; } float SinCircle(float x, float y, float size) { float cx = width * sin(movement/10); float cy = height * cos(movement/10); float dist = sqrt(sq(cy-y) + sq(cx-x)); return sin((dist/size ) + movement ); }