How to make this wave movement?


#1

Hello!

I have found this Gif very interesting (credits to @beesandbombs).

wave

I am able to make the still version of the Gif in Processing, but I have no idea how to make it move like that? I don’t really know how can I use translate and perhaps rotate to make this animation.

Any suggestions are appreciated.


#2

I’d recommend trying to break it down by describing what’s going on in your own words in as much detail as possible. Don’t worry about the code yet, just describe it in English. What are the lines doing? What is each section doing? What is the center of each “scale” doing?

My guess is that each scale is a circle whose center is rotating around another (invisible) circle with some offset based on position.


#3

@Murky ====
beautiful gif!
i have tried (not time enough to be perfect!) with P5.
Guideline:
you create the black rect
you create a class for the circles (not sure that they are really circles…)
each object of this class has an X, an Y, width, height, a value for the radius of the circle on which it moves and an angle for the rotation
you create these objects with 2 loops
they need to be more than needed if they were “static” and aside
you add them to An arrayList
in the class you create a method for displaying your objects
with this method you use trigo, cos && sin for putting them where they have to be and change the angle of rotation
in the main class you call this method from your arrayList
finally you add 4 white rects in order to mask the circles when they are outside of the black rect.
And it works…though i have said the result is not absolutely perfect.
I could put the code but i think that it is better to try …


#5

@Murky
This is what you are looking for:
This is my origional work, please feel free to use what you like, credit me if you are showing it around. :wink:

float r1 = 1;
float r2 = 25;
float rdelta = 0.5;

int spacing  = 25;
int spacing1 = 20;
int spacing2 = 21;
int spacing3 = 11;
int spacing4 = 15;
int spacing5 = 20;
int spacing6 = 9;

float time  =  0;
float time1  =  0;
float time2  =  0;
float time3  =  0;
float time4  =  0;
float time5  =  4;
float time6  = 0.09;
float time7 = 0;

void setup() {
 size(800,800);
 frameRate(60);
 smooth();
 colorMode(HSB);
 noStroke();
}
void draw_ellipse2(float x6, float y6, float radius, float r2) {
  
  translate(x6,y6);
  rotate(r2+radius);
  float col = 255 * noise(x6/500, y6/500, time6);
  strokeWeight(4);
  stroke(col,x6-y6);
  fill(r2+time6, random(y6), 255);
  ellipse(0, 0, radius, radius);
  resetMatrix();
}

void draw_rect3(float x5, float y5, float radius, float r1) {
  r1 = r1 + time;
  translate(x5,y5);
  rotate(r1);
  float col = 255 * noise(x5/width/3, y5/height/3, time5);
  fill(x5, y5, 255, col);
  rect(0, 0, radius, radius);
  resetMatrix();
  
}
void draw_ellipse(float x, float y, float radius, float r) {
  r = r + time1;
  translate(x,y);
  rotate(10*sin(time1));
  float col = 255 * noise(x*width/3, y*height/3, time1);
  fill(random(x), random(y), 255, col);
  ellipse(0, 0, radius, radius);
  resetMatrix();
}
void draw_rect(float x, float y, float radius, float r) {
  r = r + time;
  translate(x,y);
  rotate(r);
  float col = 255 * noise(x/width/3, y/height/3, time);
  fill(x, y, 255, col);
  rect(0, 0, radius, radius);
  col = col + time;
  resetMatrix();
  
}
void draw_rect1(float x, float y, float radius, float r) {
  r = r + time2;
  translate(x,y);
  rotate(r);
  float col = 255 * noise(x/width/3, y/height/3, time2);
  fill(random(x), y, 255, col);
  rect(0, 0, radius, radius);
  col = col + time2;
  resetMatrix();
  }
  
void draw_ellipse1(float x, float y, float radius, float r) {
  r = r + time4;
  translate(x,y);
  rotate(r);
  float col = 255 * noise(x*width/3, y*height/3, time4);
  fill(x, random(y), 255, col);
  ellipse(0, 0, radius, radius);
  resetMatrix();
}

void draw_rect2(float x, float y, float radius, float r) {
  r = r + time2;
  translate(x,y);
  rotate(r);
  float col = 255 * noise(x/width/3, y/height/3, time2);
  fill(x, y, 255, col);
  rect(0, 0, radius, radius);
  col = col + time2;
  resetMatrix();
  }
  
void draw() {
  //background(0);
  fill(0,40);
  rect(0,0,width,height);
  
   if (mouseX < 266 && mouseY < 266) {
     float  x = 0;
    while( x < width/3) {
    float  y = 0;
    while( y < height/3 ) {
    draw_rect( x ,  y , 20, 20+x);
       y = y + spacing;
    }     
       x = x + spacing;
    }
      if (mousePressed) {
      time += 0.2;
      }
   } 
   if (mouseX > 266 & mouseX < 532 & mouseY < 266 & mouseY < 532) {
      float  x1 = 0;
    while( x1 < width/3) {
    float  y1 = 0;
    while( y1 < height/3 ) {
      ellipseMode(CORNER);
    draw_ellipse( 266 + x1 ,  y1 , 20,time1+x1 +y1);
       y1 = y1 + spacing1;
    }     
       x1 = x1 + spacing1;
    }
      if (mousePressed) {
      time1 += 0.2;
      }
    }
    if (mouseX < 266  & mouseX < 532 & mouseY > 266 & mouseY < 532) {
     float  x2 = 0;
    while(  x2 < width/3) {
     float  y2 = 0;
    while( y2 < height/3 ) {
      float col = 255 * noise(x2*width/3, y2*height/3, 20 -x2+y2 );
       draw_rect1( x2 , 266 + y2 , 10, col+x2+y2);
       y2 = y2 + spacing2;
    }     
       x2 = x2 + spacing2;
    }
      if (mousePressed) {
      time2 += 0.2;
      }
    }
     if (mouseX > 266 & mouseX < 532 & mouseY > 266 & mouseY < 532) {  
    float  x3 = 0;
    while( x3 < width/3) {
    float  y3 = 0;
    while( y3 < height/3 ) {
     ellipseMode(CORNER);
    draw_ellipse1( 266 +x3 *1 , 266+y3*1, 10, time3 +x3+y3);
       y3 = y3 + spacing;
    }     
       x3 = x3 + spacing3;
    }
      if (mousePressed) {
      time3 += 0.2;
      }
   } 
    if (mouseX > 532 & mouseX < 800 & mouseY > 532 & mouseY < 800) {
     float  x4 = 0;
    while(  x4 < width/3) {
     float  y4 = 0;
    while( y4 < height/3 ) {
      float col = 255 * noise(x4*width/3, y4*height/3, time1);
       draw_rect2( 532+x4 , 532 + y4 , 15, time4+y4);
       y4 = y4 + spacing4;
    }     
       x4 = x4 + spacing4;
    }
      if (mousePressed) {
      time4 += 0.15;
      }}
      
      if (mouseX > 532 & mouseX < 800 & mouseY > 0 & mouseY < 266) {
     float  x5 = 0;
    while(  x5 < width/3) {
     float  y5 = 0;
    while( y5 <  height/3+100 ) {
    draw_rect3( 532 +x5,  y5 * noise(x5/266), 10*noise(y5/255), time5+x5);
       y5 = y5 + spacing5;
    }     
       x5 = x5 + spacing5;
    }
      if (mousePressed) {
      time5 = time5 + 0.2;
      }}
      
       if (mouseX > 532 & mouseX < 800 & mouseY > 266 & mouseY < 532) {  
    float  x6 = 0;
    while( x6 < width/3) {
    float  y6 = 0;
    while( y6 < height/3 ) {
     ellipseMode(CORNER);
    draw_ellipse1( 532 +x6+time6, 266+ y6+(spacing6), 10, r2+x6+y6);
       y6 = y6 + spacing6;
    }     
       x6 = x6 + spacing6;
    }
      if (mousePressed) {
      time6 += 4;
      }    
   } 
   if (mouseX > 0 & mouseX < 266 & mouseY > 532 & mouseY < 800) {  
    float  x7 = 0;
    while( x7 < 266) {
    float  y7 = 532;
    while( y7 < 800 ) {
    float co= 255 * noise(x7/100, y7/100, time7); 
    co=co+time7;
    fill(y7+50+time, x7 ,255,co);
    draw_rect(x7 ,450+ y7*noise(x7/100,(time7)) , 20,0.2);
     y7 = y7 + spacing6; 
    }
     x7 = x7 + spacing6;
    }
    if (mousePressed) {
     time7 = time7 + 0.2; 

    }}
    if (mouseX > 266 & mouseX < 532 & mouseY > 532 & mouseY < 800) { 
      float x = 266;
  float y = height;
  while( x < 532) {
    float co= 255 * noise(x/80, y/55, time); 
    strokeWeight(2);
    stroke(60+co,100+y+time,x,co);
    fill(y,x*sin(time),co,time);
    line(266 +50 +x *noise(y/500*sin(co),time), 300 + 50 +y *noise(x/532,time), x,y);
    y = y +1;
    x = x +1;
  }
  if( mousePressed) {
  time += 0.02;
  }
  }
   
   
   
   
   
   
   
   
   
   
   
   
   
 textSize(20);
 fill(125);
 text("Move mouse over the screen",width/2-150,height/2+50);
 text("press and hold mouse button over the sections to make",width/2-260,height/2+75);
 text("objects in section move",width/2-120,height/2+100);
 }

#6

@Murky=== sorry, i dont understand: what i can see running your code is not at all like the gif you put…


#7

It IS the same thing. It just needs modification to make it precise.
If you’d like I will write and post the exact code. Then you can understand better?


#8

@artisan===
if you are happy i have nothing to add; except that i cannot see in what sense the result is like the model. And btw i have not asked for nothing and made quite the same thing than the GIF the first day you posted. Perhaps i change my mind when i see the final code? - If you posted it post only the part about the first ellipses and make them as similar as possible (black, white, stroke…) to the GIF.


#9

@Murky

@Kevin is giving good advice to break it down. There are several simple sketches that would lead you to a solution by combining them. @akenaton gave one approach – a class-based solution. Here is a another description of a series of sketches that build towards your example:

  1. draw a circle
  2. draw a line of circles – use a for loop
  3. now make them not a line, but a small wave – in your loop, adjust each height with a sin() or cos() based on the position.
  4. add an outer for loop to draw multiple rows. make the rows overlap, vertically, like scales
  5. make the rows are offset by half a diameter – every other row, bump it over, e.g. float rowoffset = rownum%2 * diam/2.0;
  6. making the screen contents roll around in circular path, e.g.
  float theta = frameCount * TWO_PI / framesPerRotation;
  float pathX = pathRadius * cos(theta);
  float pathY = pathRadius * sin(theta);
  translate(pathX, pathY);

Okay, now instead of everything following one circular path, you need each individual circle to follow a slightly different circular path. How are these paths different from each other? This is the final key to the rolling effect.