# Wave displaced circle

Hi guys,

I’m trying to replicate this animation in processing :

But I can’t figure out how to do it, this is my code :

``````Circle c1,c2;

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

c1 = new Circle(0,0,200,0);
c2 = new Circle(0,0,200,HALF_PI);
}

void draw() {
background(0);
translate(width/2,height/2);

c1.display();
c2.display();

c1.update();
c2.update();
}

class Circle{
float angle, angle_sin;

Circle(int xx, int yy, int rad, float angle_start){
x = xx;
y = yy;
angle = 0;
angle_sin = angle_start;
}

void display(){
noFill();
stroke(255);
strokeWeight(3);

beginShape();

for(float a = 0; a<TWO_PI;a+=0.01){
float val = map(abs(a-angle),0,HALF_PI,50,0);
}
endShape(CLOSE);
}

void update(){
angle += 0.01;
angle_sin += 0.02;
}
}
``````

I have a variable `angle` that controls the rotation of the circle and a `angle_sin` variable that controls the variation of the sin wave.

Thanks

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

1 Like

Thanks for you answer, this is what I did :

But there’s a bug and it doesn’t work quite well.
Another problem is closing the curveVertex shape.

The code :

``````Circle c1,c2;

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

c1 = new Circle(0,0,200,0);
c2 = new Circle(0,0,200,PI);
}

void draw() {
background(0);
translate(width/2,height/2);

c1.display();
c2.display();

c1.update();
c2.update();
}

class Circle{
float angle, angle_sin;

Circle(int xx, int yy, int rad, float angle_start){
x = xx;
y = yy;
angle = 0;
angle_sin = angle_start;
}

void display(){
noFill();
stroke(255);
strokeWeight(3);

beginShape();

for(float a = 0; a<=TWO_PI;a+=0.01){
float val = map(abs(a-angle),0,TWO_PI,40,0);
angle_sin += 0.02;
}
endShape(CLOSE);
}

void update(){
angle += 0.01;
if(angle>TWO_PI){
angle = 0;
}
}
}
``````
1 Like

Here’s my take on it

``````
WaveCircle circ1, circ2;

void setup() {
size(400, 400, P3D);
circ1 = new WaveCircle();
circ2 = new WaveCircle();
}

float radDist(float t1, float t2) {
while (t1>=TWO_PI) t1-= TWO_PI;
while (t1<0) t1 += TWO_PI;

while (t2>=TWO_PI) t2-= TWO_PI;
while (t2<0) t2 += TWO_PI;

float d = abs(t1-t2);
if (d>=PI) {
d = PI-(d-PI);
}
return d;
}

float inc = 0.01;
float circSize = 100;
float distortSize = 1.0;
int freq = 20;

float z =0;
float s = 0;
void draw() {

inc = 0.01;
circSize = 100;
distortSize = 1.0;
freq = 10;

strokeWeight(2);
s += 0.003;
//if (s >= TWO_PI) s -= TWO_PI;

float speed = 0.05;

z += speed;
if (z >= TWO_PI) z-= TWO_PI;

clear();
circ1.draw(z, 1);
circ2.draw(z+0.0, -1);

saveFrame("gif/####.png");
}

class WaveCircle {

WaveCircle() {
}

void draw(float z, float q) {
pushMatrix();
noFill();
stroke(255);
beginShape();

translate(2*circSize, 2*circSize);
for (float i = 0; i <= TWO_PI; i+=inc) {
float dist  = pow(radDist(i, z), 2.0);
}
endShape();
popMatrix();
}
}

``````

1 Like

Good job !

I was stuck on this part :

``````float radDist(float t1, float t2) {
while (t1>=TWO_PI) t1-= TWO_PI;
while (t1<0) t1 += TWO_PI;

while (t2>=TWO_PI) t2-= TWO_PI;
while (t2<0) t2 += TWO_PI;

float d = abs(t1-t2);
if (d>=PI) {
d = PI-(d-PI);
}
return d;
}
``````

Thanks @lmccandless @kfrajer