How to implement this wave animation (link provided)

Please have a look at this animation.

Do you think it would be possible to implement it using Processing?
The text should be dynamic (keyboard input), but first I want to do the wave animation part.

I’m searching using keywords like cloth/fabric/wave simulation but without much luck, so maybe I’m missing something more obvious?

Thanks!

Hello,

The idea there is to use sin and cos functions to wrap your 2D space.

First, you need to imagine that your 2D space is a grid:

void setup() {
  size(400, 400);
  noStroke();
  fill(72, 212, 247);
}

void draw() {
  background(20);
  
  for (int x = 0; x <= 400; x+=10) {
    for (int y = 0; y <= 400; y+=10) {
      ellipse(x, y, 2, 2);
    }
  }
}

image

Now imagine drawing a cos function on top from left to right.
For example y = sin(0.05 * x)

image

What happen, if for each point, you move the y coordinate depending on the value you get from this sin wave?

void setup() {
  size(400, 400);
  noStroke();
}

void draw() {
  background(20);
  
  fill(72, 212, 247);
  for (int x = 0; x <= 400; x+=10) {
    for (int y = 0; y <= 400; y+=10) {
      float cx = x;
      float cy = y + 5 * sin(0.05 * x);
      ellipse(cx, cy, 2, 2);
    }
  }
}

image

Another improvement is that now all your rows are move the same way. But it would be nicer to have some differences here too. This time instead of changing the y value along depending of its x coordinate, we want to do it depending on the y coordinate.
We can for example take : cy = y + 5 * sin(0.05 * x) * sin(0.07 * y)

In that case we get the following result:
image

Let’s do the same for the x with different periods:
image

All left to do is to animate it. For this, we can simply use the millis() function to add the elapsed time since the begin of the program in our sin() functions.

void setup() {
  size(400, 400);
  noStroke();
}

void draw() {
  background(20);
  fill(72, 212, 247);
  
  float dt = 0.001 * millis();
  for (int x = 0; x <= 400; x+=10) {
    for (int y = 0; y <= 400; y+=10) {
      float cx = x + 5 * sin(0.033 * y + dt) * sin(0.047 * x + dt);
      float cy = y + 5 * sin(0.050 * x + dt) * sin(0.070 * y + dt);
      ellipse(cx, cy, 2, 2);
    }
  }
}

Now replace the ellipses by letters and your are good to go.

One last thing. If you run the last piece of code, you will quickly realize that it loops quite fast and that you have repetitions in the 2D space. This is because of the nature of sin() which is cyclic. To avoid that, you can lower the period of the sin so less than one period fit in your 2D space or even include some noise to randomize some places.

5 Likes

This is extremely helpful, thank you so much for taking the time to break it down and explain it so well :star_struck:

2 Likes