Loading...
Logo
Processing Forum
Hello all, 

Does anybody know how to code the movement of a sine wave through 3D space?  I'd like to have the wave move through space at any definable angle but can't think how to make this happen.

Here is where I'm at so far:

Copy code
  1. float x1 = 0;

  2. void setup() {
  3.   size(500, 500);
  4.   smooth();
  5. }

  6. void draw() {
  7.   background(255);

  8.   int pitch = 440;
  9.   for (float i = x1; i < x1+50; i += 0.1) {
  10.     point(i, height/2+sin(pitch*i)*20);
  11.   }
  12.   
  13.   x1++;
  14. }

Thanks very much,
Adam

Replies(11)

Dunno much about trigonometry. But at least I could re-factor your code to use constant values.
Much easier to change program's behavior to suit your needs anytime! 
Copy code
    final static short FPS = 0300, PITCH = 440;
    final static short AMP = 0100, LEN = 0150;
    final static float GAP = 0.1, BOLD = 1.5;
    final static color BG  = -1;
    
    // JAVA2D, P2D, P3D, OPENGL:
    final static String ENGINE = P2D;
    
    void setup() {
      size(500, 200, ENGINE);
      frameRate(FPS);
      smooth();
      strokeWeight(BOLD);
    }
    
    void draw() {
      background(BG);
    
      final float hh = height>>1, posX = frameCount % width;
    
      for (float i = posX + LEN; i > posX; i -= GAP)
        point(i, hh + sin(PITCH * i) * AMP);
    }
    
    void mousePressed() {
      if (looping)    noLoop();
      else            loop();
    }
    
    void keyPressed() {
      mousePressed();
    }
    

This is much clearer now, thank you.  Perhaps now a trigonometry hero will come to my rescue!
You could use translate and rotate for this:


Copy code
  1. float x1 = 0;

  2. void setup() {
  3.   size(500, 500, P3D);
  4.   smooth();
  5. }

  6. void draw() {
  7.   background(255);
  8.   perspective();
  9.   float rotY = map(mouseX, 0, height, 0, 180);
  10.   float rotZ = map(mouseY, 0, width, -90, 90);
  11.   translate(width/2, height/2, 100);
  12.   rotateY(radians(rotY));
  13.   rotateZ(radians(rotZ));
  14.   println(rotZ);
  15.   int pitch = 440;
  16.   for (float i = x1; i < x1+50; i += 0.1) {
  17.     point(i, sin(pitch*i)*20);
  18.   }
  19.   noFill();
  20.   box(100);
  21.   x1++;
  22. }

v.k.,  thanks for the response.  The problem I still face is that I require many sine wave objects moving in many different directions, so I think that the direction must be an attribute of the sine wave objects themselves as opposed to an attribute of the perspective (I hope that wasn't nonsense!).  Rotate and translate might work somehow still, but I think that it would work out simpler to find a trig solution instead.
Are you sure you mean 3D space your original code used a 2D renderer.
Quarks, yes I am sure.  The code I posted is in fact an isolated part of my overall project representative of my problem - I decided that it would be clearer to ask like this instead of posting my whole project and confusing the specific matter at hand. 
v.k. had part of the answer. I have modified his code and created a Wave class to simplify multiple waves with different pitch and amplitudes. The code is rough and ready but demonstrates the technique.

The key is in the draw method of the Wave class. The pushMatrix saves the current transofrmation matrix which is then rotated before drawing the sine wave. The popMatrix restores the transformation matrix back ready for the next wave.

Copy code
  1. Wave w1, w2, w3, w4;

  2. void setup() {
  3.   size(500, 500, P3D);
  4.   smooth();
  5.   w1 = new Wave(20, 40, 0, 0, 0);
  6.   w2 = new Wave(10, 20, PI/4, PI/3, PI/6);
  7.   w3 = new Wave(50, 10, 0, PI/3.5, PI);
  8.   w4 = new Wave(80, 60, PI/7, 0, PI/5);
  9.   frameRate(25);
  10. }

  11. void draw() {
  12.   background(255);
  13.   //perspective();
  14.   float rotY = map(mouseX, 0, height, 0, 180);
  15.   float rotZ = map(mouseY, 0, width, -90, 90);
  16.   translate(width/2, height/2, 100);
  17.   rotateY(radians(rotY));
  18.   rotateZ(radians(rotZ));
  19.   w1.draw();
  20.   w2.draw();
  21.   w3.draw();
  22.   w4.draw();
  23.   noFill();
  24.   box(100);
  25. }

  26. class Wave {
  27.   float amp, p;
  28.   float ax, ay, az;
  29.   float x1 = 0;
  30.   public Wave(float amplitude, float pitch, float angX, float angY, float angZ) {
  31.     amp = amplitude;
  32.     p = pitch;
  33.     ax = angX;
  34.     ay = angY;
  35.     az = angZ;
  36.   }
  37.   public void draw() {
  38.     pushMatrix();
  39.     rotateX(ax);
  40.     rotateY(ay);
  41.     rotateZ(az);
  42.     for (float i = x1; i < x1+50; i += 2/amp) {
  43.       point(i, sin(TWO_PI * i/p)*amp);
  44.     }
  45.     x1++;
  46.     popMatrix();
  47.   }
  48. }

That makes perfect sense, thank you very much for your help.
this also is easy to do ;)

Copy code
  1. float x1 = 0;

  2. void setup() {
  3.   size(500, 500, P3D);
  4.   smooth();
  5.   perspective();
  6. }

  7. void draw() {
  8.   background(255);

  9.   int pitch = 440;
  10.   for (float i = x1; i < x1+500; i += 0.1) {
  11.     point(width/2+cos(pitch*i)*20, height/2+sin(pitch*i)*20, -i+500);
  12.   }
  13.   
  14.   x1++;
  15. }


or


Copy code
  1. float x1 = 0;

  2. void setup() {
  3.   size(500, 500, P3D);
  4.   smooth();
  5.   perspective();
  6. }

  7. void draw() {
  8.   background(255);

  9.   int pitch = 440;
  10.   for (float i = x1; i < x1+50; i += 0.1) {
  11.     point(i, height/2+sin(pitch*i)*20, cos(pitch*i)*20);
  12.   }
  13.   
  14.   x1++;
  15. }

I found this at stack exchange there is two math answers. But i don't know how to try to implement any of those... :P



or a matrix, maybe this is what rotate() does behind the scene...


Hmmm, interesting stuff vk - thanks.  It looks like I've got to get my nose into some real maths after all!  
Copy code