Not the final product, but almost…
I put something a bit much but hopefully you can see my approach to arrive to the final product.
First I experiment with the frequency of the wave. For this I generate three waves at three different levels in my screen that spans along the full width of the screen.
Then I draw a circle.
Last I mix the frequency of interest in the first part with my green circle. The end result is the purplish circle.
The key here is that after I am able to create a sine wave along the width of the screen, then I want to map the x values to the full revolution of my circle:
x : range(0..width)     =>  range(0..TWO_PI)
So for every x in the wavy line, I take its amplitude and I mix it with the circle’s point at an angle theta. Notice that x and theta are now connected bc of my prev line. The mixing happens with cx0, cy0, dx0, dy0.
Kf
//REFERENCE: https://forum.processing.org/two/discussion/26716/how-can-i-code-this-animation-in-processing  
//REFERENCE: htps://processing.org/examples/sinewave.html
int xspacing = 9;   // How far apart should each horizontal location be spaced
int w;              // Width of entire wave
float theta = 0.0;  // Start angle at 0
float amplitude = 15.0;  // Height of wave
float period = 500.0;  // How many pixels before the wave repeats
float dx;  // Value for incrementing X, a function of period and xspacing
float[] yvalues;  // Using an array to store height values for the wave
float[] yvalueslow;
float[] yvaluesmed;
float[] yvalueshigh;
void setup() {
  size(640, 360);
  w = width+16;
  dx = (TWO_PI / period) * xspacing;
  yvalues = new float[w/xspacing];
  yvalueslow = new float[w/xspacing];
  yvaluesmed = new float[w/xspacing];
  yvalueshigh = new float[w/xspacing];
}
void draw() {
  background(0);
  calcWave();
  renderWave();
}
void calcWave() {
  // Increment theta (try different values for 'angular velocity' here
  theta += 0.02;
  // For every x value, calculate a y value with sine function
  float x = theta;
  for (int i = 0; i < yvalues.length; i++) {
    yvalues[i] = sin(x)*amplitude;
    float xx=map(x, 0, yvalues.length, 0, TWO_PI);
    yvalueslow[i] = sin(xx*100)*amplitude;
    yvaluesmed[i] = sin(xx*50)*amplitude;
    yvalueshigh[i] = sin(xx*20)*amplitude;
    x+=dx;
  }
}
void renderWave() {
  noStroke();
  // A simple way to draw the wave with an ellipse at each location
  for (int x = 0; x < yvalues.length; x++) {
    float xval=x*xspacing;
    //Draw three lines with different frequency spanning the 
    //  width of the screen, at three different heights
    fill(120);
    ellipse(xval, height*0.25+yvalueslow[x], 10, 10);
    fill(190);
    ellipse(xval, height*0.5+yvaluesmed[x], 12, 12);
    fill(240);
    ellipse(xval, height*0.75+yvalueshigh[x], 16, 16);
    //draw a static green circle
    fill(0, 255, 0);
    float ca=map(x, 0, yvalues.length, 0, TWO_PI);
    float cx=10*amplitude*cos(ca);
    float cy=10*amplitude*sin(ca);
    ellipse(cx+width/2, cy+height/2, 5, 5);
    //draw a wavy purpulish circle
    fill(220, 0, 200);
    float ca0=map(x, 0, yvalues.length, 0, TWO_PI);
    float cx0=10*amplitude*cos(ca);
    float cy0=10*amplitude*sin(ca);
    float dx0=yvalueslow[x]*cos(ca);
    float dy0=yvalueslow[x]*sin(ca);
    ellipse(cx0+dx0+width/2, cy0+dy0+height/2, 5, 5);
  }
}
Keyword: kf_keyword wavy_circle wave_effect frequency