# Animated stripes gifs from scalar fields

This tutorial explains how to obtain this kind of GIF with Processing : We’ll start from this code that generates the following simple animation ;

```int margin = 50;
int numFrames = 20;

void setup(){
size(600,600);

}

float pixel_color(float x,float y,float t){
float result = map(sin(TWO_PI*t),-1,1,0,1);
return 255*result;
}

void draw(){
background(0);

float t = 1.0*(frameCount-1)%numFrames/numFrames;

// Draws every pixel
for(int i=margin;i<width-margin;i++){
for(int j=margin;j<height-margin;j++){
stroke(pixel_color(i,j,t));
point(i,j);
}
}

// Draws a white rectangle
stroke(255);
noFill();
rect(margin,margin,width-2*margin,height-2*margin);

// Saves the frame
println(frameCount,"/",numFrames);
saveFrame("frame###.png");

// Stops when all the frames are rendered
if(frameCount == numFrames){
println("finished");
stop();
}
}
``` That code makes each pixel in a white rectangle oscillate between black and white over time. The rest will be only little variations from there so make sure you understand the basis.

Now let’s have moving stripes !
So let’s change the pixel_color function so that the color of pixels doesn’t oscillate at the same time vertically.

```float pixel_color(float x,float y,float t){
float result = map(sin(TWO_PI*(t+0.05*y)),-1,1,0,1);
return 255*result;
}
``` Now let’s make those stripes more contrasted. To achieve that we’ll use an easing function that makes values between 0 and 0.5 closer to 0 and values between 0.5 and 1 closer to 1, with a parameter g to increase the effect.

```float ease(float p, float g) {
if (p < 0.5)
return 0.5 * pow(2*p, g);
else
return 1 - 0.5 * pow(2*(1 - p), g);
}
```

Let’s use it on our oscillating color :

```float pixel_color(float x,float y,float t){
float result = ease(map(sin(TWO_PI*(t+0.05*y)),-1,1,0,1),3.0);
return 255*result;
}
```

This is the result : Now let’s make a general function that controls the offset in the oscilation :
(a scalar field is just a function that gives a real value for each position of the plane in our case)

```float scalar_field_offset(float x,float y){
return 0.05*x+0.05*y;
}

float pixel_color(float x,float y,float t){
float result = ease(map(sin(TWO_PI*(t+scalar_field_offset(x,y))),-1,1,0,1),3.0);
return 255*result;
}
```

Result (there is now horzontal change due to 0.05*x) : Now to obtain different results we just have to change the scalar field. Let’s use the distance to the center.

```float scalar_field_offset(float x,float y){
float distance = dist(x,y,width/2,height/2);
return 0.05*distance;
}
``` Perlin noise (a very nice function given by Processing, I won’t make a tutorial about it here) :

```float scalar_field_offset(float x,float y){
float scale = 0.003;
float result = 40*noise(scale*x,scale*y);
return result;
}
``` Stripes and perlin noise gradually vertically :

```float scalar_field_offset(float x,float y){
float perlin_noise_intensity = pow(constrain(map(y,0.1*height,height,0,1),0,1),2);

float scale = 0.006;
float result = -0.05*y + 20*(noise(scale*x,scale*y)-0.5)*perlin_noise_intensity;
return result;
}
``` :

Perlin noise in the center :

```float scalar_field_offset(float x,float y){
float distance = dist(x,y,width/2,height/2);
float perlin_noise_intensity = ease(constrain(map(distance,0,0.3*height,1,0),0,1),2);

float scale = 0.002;
float result = -0.05*y -0.05*x + 60*(noise(scale*x,scale*y)-0.5)*perlin_noise_intensity;
return result;
}
``` Using distance differently :

```float scalar_field_offset(float x,float y){
float distance = dist(x,y,0.5*width,0.5*height);

float result = 300/(25+distance);
return result;
}
``` By adding the effect of many centers you can get something like this : And with many centers and using an effect only near them : Here is a complete code to generate one in case you missed anything :

```int margin = 50;
int numFrames = 20;

void setup(){
size(600,600);

}

float ease(float p, float g) {
if (p < 0.5)
return 0.5 * pow(2*p, g);
else
return 1 - 0.5 * pow(2*(1 - p), g);
}

float scalar_field_offset(float x,float y){
float distance = dist(x,y,0.5*width,0.5*height);

float result = 300/(25+distance);
return result;
}

float pixel_color(float x,float y,float t){
float result = ease(map(sin(TWO_PI*(t+scalar_field_offset(x,y))),-1,1,0,1),3.0);
return 255*result;
}

void draw(){
background(0);

float t = 1.0*(frameCount-1)%numFrames/numFrames;

// Draws every pixel
for(int i=margin;i<width-margin;i++){
for(int j=margin;j<height-margin;j++){
stroke(pixel_color(i,j,t));
point(i,j);
}
}

// Draws a white rectangle
stroke(255);
noFill();
rect(margin,margin,width-2*margin,height-2*margin);

// Saves the frame
println(frameCount,"/",numFrames);
saveFrame("frame###.png");

// Stops when all the frames are rendered
if(frameCount == numFrames){
println("finished");
stop();
}
}
```

I hope this was helpful and that you will be creative and come up with better stuff than me !

Bonus : if you know glsl, it would be a better idea to code this in glsl to have much faster rendering.

Advertisements

## One thought on “Animated stripes gifs from scalar fields”

1. mrutan says:

Thanks for sharing these sketches and tutorial!.This is what makes the Processing community great!

Liked by 1 person