Drawing Waves on Lattice with Processing

processing_logo

Introduction

About a week ago, giving a quick look at Google+, I found at a very attractive animated GIF. It showed a number of black balls orbiting around the points of a lattice. These balls were rotating all together, each with an angle slightly offset with respect to the nearby. The whole appeared as a wave that flows through a surface.

This animation impressed me so much that this morning I decided to make a similar copy by writing code with Processing.

Unfortunately I missed the references to that image. So I have no idea what it was, about what, or who was the author. However, if you have information about it, please, could you add a comment to the end of the article?

This is about the image as I remember….(actually this has been created by me with Processing)

WaveOnLatticeHead

Let’s implement the code with Processing

Developing the code to generate an animation as described above could be quite complex using some programming languages, but using Processing you find out that this work could be really easy. Indeed Processing is a language (actually it is based on Java) created specifically for developing graphics applications and especially animation.

If you are not familiar with Processing I recommend to read the article A short introduction to Processing.

processing_wave_on_lattice

Once you open the IDE, create a new Processing sketch and write the following code.

//Waves_on_Lattice animation written by F.Nelli (26-Mar-2014)

int w = 700;
int h = 400;
int r = 10; // r>4
int n_h,n_w;
int k = 0;

void setup(){
  size(w,h);
  background(255);
  n_h = h/(2*r);
  n_w = w/(2*r);
}

void draw(){
  background(255);
  for (int i=0; i < n_w; i++)
    for(int j=0; j < n_h; j++) {
      int cx = (2*i+1)*r;
      int cy = (2*j+1)*r;
      ellipse(cx,cy,2*r-4,2*r-4);
      fill(0);
      int dx = (int)((r-2)*sin(radians((i+j+k)*12)));
      int dy = (int)((r-2)*cos(radians((i+j+k)*12)));
      ellipse(cx+dx,cy+dy,4,4);
      fill(255);
    }
    k++;
}

Incredible! This code does not exceed 30 rows of code! This is because Processing allows us to focus only on what we want to draw. The graphic management, the call to objects, classes, streams, etc., are implicitly handled. If you choose to work with Processing, you must think only to implement the geometric shapes and the algorithm that uses them.

Now, execute the code. Here is the result:

Wave On Lattice

Let’s take a quick look at the code.

int w = 700;
int h = 400;
int r = 10; // r>4
int n_h,n_w;
int k = 0;

In these rows of code we define the parameters w and h, which are respectively the width and height of the window (drawing area). With r we define the distance between the lattice points (the centers of the circles), while n_h and n_w are variables that serve to store the numbers of lattice points needed to fill the drawing area horizontally and vertically. Finally, k is the counter variable for the animation.

void setup(){
  size(w,h);
  background(255);
  n_h = h/(2*r);
  n_w = w/(2*r);
}

Within the  setup( ) function we define the code to initialize the application. With the size( ) function we draw the window and with the background( ) function we set the background color to white (255). Then we need to calculate how many points will fill the drawing area both horizontally and vertically.

void draw(){
  background(255);
  for (int i=0; i < n_w; i++)
    for(int j=0; j < n_h; j++) {
      int cx = (2*i+1)*r;
      int cy = (2*j+1)*r;
      ellipse(cx,cy,2*r-4,2*r-4);
      fill(0);
      int dx = (int)((r-2)*sin(radians((i+j+k)*12)));
      int dy = (int)((r-2)*cos(radians((i+j+k)*12)));
      ellipse(cx+dx,cy+dy,4,4);
      fill(255);
    }
    k++;
}

Finally withinn the draw( ) function you define the code related to animation. If you are new to Processing, the draw( ) function is repeatedly executed as if it were inside an infinite “while” loop. We have already seen that k is the counter that starts from 0 ( as defined in setup( ) ) and increases its value of a unit for every cycle ( k++ ). As you have seen in the figure above, the lattice that we want to develope, is nothing more than a circle with a black dot on it, repeated both horizontally and vertically. To implement this lattice then you have to use two nested for() loops. In this double-loop, you calculate the coordinates of the center of each circle, cx and cy . Then you draw these circles using the ellipse( ) function. Once you so defined the circles, we need to calculate the coordinates of the black dot orbiting around the center. We can do this calculating the orbit around that center, but taking into account the phase shift of each point ( with i and j ) and of the movement to perform frame by frame in order to get an animation ( with ). Finally we draw them with the ellipse( ) function.

Modifying the equations of the orbit of the dots you can get lots of effects. For example, trying these equations the animation will show a “flag effect“.

int dx = (int)((r-2)*sin(i*radians(10+j+k)));
int dy = (int)((r-2)*cos(i*radians(10+j+k)));



Leave a Reply