09. Metaballs - The Virtual Lava Lamp

09. Metaballs - The Virtual Lava Lamp

ยท

3 min read

The concept of a metaball is quite simple. A spherical structure behaves like the blobs floating inside a lava lamp. According to Wikipedia, metaballs are n-dimensional isosurfaces, characterised by their ability to meld together in close proximity to create single, contiguous objects. These can create intricate shapes on the screen.

We'll first start with the global variables. The variables we need are to store all the blobs, the hue of the screen and the direction in which the colour should shift.

Blob[] blobs = new Blob[5]; // Array to hold each blob
float colour = 0.0; // Colour of each blob
float direction = 0.1; // Direction at which the colour should shift (0.1 or -0.1)

We will discuss the Blob class later, however, this will help us store the blobs as entities. The colour will be a float that stores the hue of the screen. Direction is also a float and will be either 0.1 or -0.1 depending on which direction we're moving on the colour spectrum.

The setup is also straightforward. We simply create the canvas, change the colour mode to HSB and create random blobs at random places on the screen and put them into the blobs array.

The magic happens within the void loop(). First we start by clearing the screen. Then for each pixel, we calculate a brightness value. This brightness value is calculated by summing up the inverse of the distance from the point to each blob. Then we set the brightness value to the brightness of that pixel and the hue to the value on colour variable.

for (int x = 0; x < width; x++) {
    for (int y = 0; y < height; y++) {
        float sum = 0;

        for (Blob b: blobs) {
            float d = dist(x, y, b.pos.x, b.pos.y);
            sum += 1500 * b.r / d;
        }

        pixels[x + y * width] = color(colour, 100, sum);
    }
}

Then we must update the location of each blob.

for (int i = 0; i < blobs.length; i++) {
    blobs[i].update();
}

In order to show the colours switching, we will add the direction to colour. if the colour has reached 0 or 255, we multiply the direction by -1. This reverses the direction to increment the colour which gives a smooth colour transition over and over again.

colour += direction;
if ((colour < 0) || (colour > 255)) {
    direction *= -1;
}

Finally we need a class called Blob. A blob needs a position, velocity and radius. The position will come at the creation, velocity and radius will be created at random. Finally, an update function will update the position by multiplying it by velocity. We will also have checks to make sure that the blobs don't leave the screen.

class Blob {
    PVector pos;
    PVector vel;
    float r;

    Blob(float x, float y) {
        pos = new PVector(x, y);
        vel = PVector.random2D();
        vel.mult(random(0, 2));
        r = random(2, 12);
    }

    void update() {
        pos.add(vel);

        if (pos.x > width || pos.x < 0) {
            vel.x *= -1;
        }
        if (pos.y > height || pos.y < 0) {
            vel.y *= -1;
        }
    }
}

With this, we have a complete animation of blobs.

Metaballs

External Links:

ย