FAQ
Cover
This is the archive Discourse for the Processing (ALPHA) software.
Please visit the new Processing forum for current information.

   Processing 1.0 _ALPHA_
   Topics & Contributions
   Beyond Categories
(Moderator: REAS)
   rotating a sine wave?
« No topic | Next topic »

Pages: 1 
   Author  Topic: rotating a sine wave?  (Read 3528 times)
lunetta

7200475272004752 WWW Email
rotating a sine wave?
« on: Apr 5th, 2005, 6:38pm »

Hello all
 
I have a geometry question that is keeping me awake;
 
how should I set the parametric equations of a sine wave in order to rotate it?
 
here's an example:
 
Code:

float a, w, T, t, x, y, scopelength, wavelength;
void setup() {
size(500,500);
background(255);
stroke(0);
 
a = 20; // a = amplitude
w = 10; // w = frequency
scopelength = sqrt(2)*width;
wavelength = scopelength/w;
}
void draw() {
 
beginShape(LINE_STRIP);
for (float i = 0; i<w*TWO_PI; i+=TWO_PI/128) {
t = i*wavelength/TWO_PI;
x = t*cos(PI/4);
y = t*sin(PI/4)+ a*sin(i);
vertex(x,y);
}
endShape();
}

 
 
As you can see, the sine wave is following the inclined path; but it's crests are aligned to a horizontal normal. What would be a simple formula to make the sine wave to follow the line normal?  
 
I can't draw the sine and apply a rotateZ command, since this is a part of a bigger code...
 
Really thanks a lot for any idea!
 
 
Quasimondo

WWW Email
Re: rotating a sine wave?
« Reply #1 on: Apr 5th, 2005, 9:16pm »

Here's something that works:
 
Code:

 
 
float cx,cy,freq,amp,phase;
 
void setup() {  
size(500,500);  
stroke(0);  
 cx=width/2;
 cy=height/2;
 freq=8;
 amp=30;
 phase=0;
}  
 
void mousePressed(){
  cx=mouseX;
  cy=mouseY;
}
 
void loop(){
 
 background(0xffffff);
 
 float x,y,a;
 float dx=mouseX-cx;
 float dy=mouseY-cy;
 float l=sqrt(dx*dx+dy*dy);
 
 phase+=0.1;
   
 dx/=l;
 dy/=l;
 
 a=atan2(dy,dx)+HALF_PI;
 float nx=amp*cos(a);
 float ny=amp*sin(a);
 
 
 beginShape(LINE_STRIP);  
 float tstep=1.0 / l;
 
 for (float t=0;t<=1.0;t+=tstep){
   a=sin(phase+TWO_PI*t*freq);
   x=cx+t*l*dx+nx*a;
   y=cy+t*l*dy+ny*a;
   vertex(x,y);  
 }  
endShape();  
}  
 

 
The simple principle is to start with a line and offset its normal at t by the amount of the sine at t.
 
If you comment out the phase+=0.1; part it will stop to animate. Higher settings for freq will increase the amounts of waves, amp controls the amplitude.
 

Mario Klingemann | Quasimondo | Incubator | côdeazur
Quasimondo

WWW Email
Re: rotating a sine wave?
« Reply #2 on: Apr 5th, 2005, 9:28pm »

Here is a slight variation where the ends of the curve will always stick to the start and end points of the chosen line (as long as the frequency is an integer):
 
Code:

float cx,cy,freq,amp,phase;
 
void setup() {  
size(500,500);  
stroke(0);  
 cx=width/2;
 cy=height/2;
 freq=8;
 amp=30;
 phase=0;
}  
 
void mousePressed(){
  cx=mouseX;
  cy=mouseY;
}
 
void loop(){
 
 background(0xffffff);
 
 float x,y,a;
 float dx=mouseX-cx;
 float dy=mouseY-cy;
 float l=sqrt(dx*dx+dy*dy);
 
 phase+=0.1;
   
 dx/=l;
 dy/=l;
 
 a=atan2(dy,dx)+HALF_PI;
 float nx=amp*cos(a);
 float ny=amp*sin(a);
 
 float ox=nx*sin(phase);
 float oy=ny*sin(phase);
 
 beginShape(LINE_STRIP);  
 float tstep=1.0 / l;
 
 for (float t=0;t<=1.0;t+=tstep){
   a=sin(phase+TWO_PI*t*freq);
   x=cx+t*l*dx+nx*a-ox;
   y=cy+t*l*dy+ny*a-oy;
   vertex(x,y);  
 }  
endShape();  
}  
 

Mario Klingemann | Quasimondo | Incubator | côdeazur
Quasimondo

WWW Email
Re: rotating a sine wave?
« Reply #3 on: Apr 5th, 2005, 9:36pm »

And one more with variable amplitude at start and end:
 
Code:

float cx,cy,freq,amp1,amp2,phase;
 
void setup() {  
size(500,500);  
stroke(0);  
 cx=width/2;
 cy=height/2;
 freq=8;
 amp1=2;
 amp2=30;
 phase=0;
}  
 
void mousePressed(){
  cx=mouseX;
  cy=mouseY;
}
 
void loop(){
 
 background(0xffffff);
 
 float x,y,a;
 float dx=mouseX-cx;
 float dy=mouseY-cy;
 float l=sqrt(dx*dx+dy*dy);
 
 phase+=0.1;
    
 dx/=l;
 dy/=l;
 
 a=atan2(dy,dx)+HALF_PI;
 float nx=amp1*cos(a);
 float ny=amp1*sin(a);
 
 float ntx=(amp2-amp1)*cos(a);
 float nty=(amp2-amp1)*sin(a);
 
 
 beginShape(LINE_STRIP);  
 float tstep=1.0 / l;
 
 for (float t=0;t<=1.0;t+=tstep){
   a=sin(phase+TWO_PI*t*freq);
   x=cx+t*l*dx+nx*a+ntx*t*a;
   y=cy+t*l*dy+ny*a+nty*t*a;
   vertex(x,y);  
 }  
endShape();  
}  
« Last Edit: Apr 5th, 2005, 9:36pm by Quasimondo »  

Mario Klingemann | Quasimondo | Incubator | côdeazur
lunetta

7200475272004752 WWW Email
Re: rotating a sine wave?
« Reply #4 on: Apr 6th, 2005, 4:49pm »

Hi Mario
 
wow, it really works.
First of all, really thanks for you taking the time to do this; the sine thing is a part of an important project for me here, and I've been struggling a bit to get it done.
 
I don't want to abuse your good will nor your patience, but I'd like to ask you something;
 
I'm not being able to understand exactly what do you get dividing the length of the right triangle by its sides; and further, what is obtained by using it as atan2 coordinate getting the angle from the source with the atan2:
 
Quote:

 dx/=l;
 dy/=l;
 
 a=atan2(dy,dx)+HALF_PI;  

 
 
I'm not sure if I compreheend what's going on there... any hint on the technique is welcome
 
again, thank you very very much for the example code.
 
Quasimondo

WWW Email
Re: rotating a sine wave?
« Reply #5 on: Apr 6th, 2005, 5:54pm »

Hi Carlos,
 
actually that was something I wanted to try anyway (part of my current interest in curves).
 
So what is it that am I doing here?
 
Code:

 float dx=mouseX-cx;  
 float dy=mouseY-cy;
 float l=sqrt(dx*dx+dy*dy);  

 
First calculate the horizontal (dx) and vertical (dy) distance between the line segment's endpoints. Then Pytagoras give us the length l of it.
 
Code:

 dx/=l;  
 dy/=l;  

 
Now I normalize the distances and thus get a unit vector of length 1 which will serve as the slope of the line.
 
Code:

 a=atan2(dy,dx)+HALF_PI;  

 
atan2 of the vector's x/y components will give me the angle in radians of that verctor. Adding HALF_PI rotates that vector by 90 degrees.
 
Code:

float nx=amp*cos(a);  
float ny=amp*sin(a);  

 
Now with this angle I calculate the normal vector or rather its x and y components. For performance reasons I already multiply it with the amplitude of the sine wave.
 
Code:

float tstep=1.0 / l;  

 
This defines the precision of the curve representation. So with 1.0/l it would draw a straight line in segments of 1 pixel length - so for a curve the single segments will be longer than 1.
 
Code:

 for (float t=0;t<=1.0;t+=tstep){  
   a=sin(phase+TWO_PI*t*freq);  
   x=cx+t*l*dx+nx*a;  
   y=cy+t*l*dy+ny*a;  
   vertex(x,y);  
 }

 
t will always go from 0 to 1. this means that as long as freq is an integer the sinwave will always make one or more complete cycles (TWO_PI*t*freq). phase is just adjusting the start of the cycle. cx is the startpoint of the line segment. From there we step towards the endpoint in the direction of our slope vector. If you only used cx+t*l*dx it would give you a straight line. But at each step we are adding the normal (which has the length of the the amplitude) multiplied by the sinewave (which comes in a range between -1 to 1) value it will give us a point that is offset perpendicular to the line.
 
Hmmm, is that somehow understandable?
 
I have a gut feeling that some of the calculations could be simplified (the normalization might not even be necessary) - but that's how I approached it for now.
 

Mario Klingemann | Quasimondo | Incubator | côdeazur
Quasimondo

WWW Email
Re: rotating a sine wave?
« Reply #6 on: Apr 6th, 2005, 6:03pm »

Oh my....
 
I knew that something was non-elegant.
 
Forget the atan2 part - we already have the angle with the slope so what I did was complete nonsense. All that is necessary is to flip the dx/dy by 90 degrees and normalize them:
 
Code:

float cx,cy,freq,amp,phase;
 
void setup() {  
size(500,500);  
stroke(0);  
 cx=width/2;
 cy=height/2;
 freq=8;
 amp=30;
 phase=0;
}  
 
void mousePressed(){
  cx=mouseX;
  cy=mouseY;
}
 
void loop(){
 
 background(0xffffff);
 
 float x,y,a;
 float dx=mouseX-cx;
 float dy=mouseY-cy;
 float l=sqrt(dx*dx+dy*dy);
 
 phase+=0.1;
  
 float nx = amp*dy/l;  
 float ny = amp*-dx/l;
 
 beginShape(LINE_STRIP);  
 float tstep=1.0 / l;
 
 for (float t=0;t<=1.0;t+=tstep){
   a=sin(phase+TWO_PI*t*freq);
   x=cx+t*dx+nx*a;
   y=cy+t*dy+ny*a;
   vertex(x,y);  
 }  
endShape();  
}  
« Last Edit: Apr 6th, 2005, 6:04pm by Quasimondo »  

Mario Klingemann | Quasimondo | Incubator | côdeazur
lunetta

7200475272004752 WWW Email
Re: rotating a sine wave?
« Reply #7 on: Apr 6th, 2005, 6:12pm »


great!
Hey, really thanks for all that. I guess I'll be able to understand now, just have to spend this night with your code. My wife is jealous, Processing is getting more attention than her lately...
 
the normalizing is the place where I got stuck before; I have this project ready, but the sine waves were not aligned to the normals... I'll try again now.
 
thanks again for the help
 
Pages: 1 

« No topic | Next topic »