Change direction of oscillation with sine wave

PerPer
edited September 2017 in Programming Questions

I got this code with oscilating ellipse in with sinewave. I want to every time Im pressing the a key the ellipse shall oscillate in another direction but I cannot get it to work. (Of course in the example below it goes only in one direction since the loc.x and loc.y are the same)

I tried a bunch of things but Im running out of ideas.

Is there any way of changing the direction or do I have to use a different technique for example by using an attractor?

Particle p;
boolean restart = false;

void settings() {
  size(1280, 720);
}

void setup() {
  p = new Particle(0, 0);
}

void draw() {
  background(255);
  p.update();
  p.display();
}


class Particle {
  PVector loc;
  int amplitude = 200;
  float inc = 0;

  Particle(int x, int y) {
    loc = new PVector(x, y);
  }

  void update() {
    float posX = sin(inc);
    //float posY = cos(inc+10);
    loc.x = amplitude * posX;
    loc.y = amplitude * posX;

    if (restart) {
      if (posX < 0.05 && posX > -0.05) {
        amplitude = 5;
        inc *= 0;
      }
    } else {
      posX = 0;
      amplitude = 200;
      restart = true;
    }

    inc += 0.04;
  }


  void display() {
    translate(width/2, height/2);
    stroke(0);
    strokeWeight(2);
    fill(127);
    ellipse(loc.x, loc.y, 20, 20);
  }
}

void keyReleased() {
  restart =! restart;  
}

Answers

  • Using lerp() below.

    Kf

    Particle p;
    
    void settings() {
      size(1280, 720);
    }
    
    void setup() {
      p = new Particle(0, 0);
    }
    
    void draw() {
      background(255);
      p.update();
      p.display();
    }
    
    
    class Particle {
      PVector loc;
      PVector initLoc;
      PVector targetLoc;
      int amplitude = 200;
      float inc = 0;
      boolean restart;
      boolean reverseDone;
    
    
    
      Particle(int x, int y) {
        loc = new PVector(x, y);
        initLoc=loc.copy();
        targetLoc=loc.copy();
        restart = false;
        reverseDone=false;
      }
    
      void setMotionPos() {
        restart=true;
        reverseDone=false;
        targetLoc.set(random(-width/2, width/2), random(-height/2, height/2));
      }
    
      void update() {
        if (PVector.dist(loc, targetLoc)>3) {   //Threshold 
    
          loc.set(lerp(loc.x, targetLoc.x, 0.05),   //How fast to approach target: 5% steps of current distance between loc and target loc
            lerp(loc.y, targetLoc.y, 0.05));
        } else {
    
          if (reverseDone==false) {
            targetLoc=initLoc.copy();
            reverseDone=true;
          } else {
            loc=targetLoc.copy();
            restart=false;
          }
        }
      }
    
    
      void display() {
        translate(width/2, height/2);
        stroke(0);
        strokeWeight(2);
        fill(127);
        ellipse(loc.x, loc.y, 20, 20);
        //fill(250, 250, 0);
        //ellipse(targetLoc.x, targetLoc.y, 20, 20);
      }
    }
    
    void keyReleased() {
    
      if (p.restart==false) {    
        p.setMotionPos();
      }
    }
    
  • Using sin() below.

    Kf

    Particle p;
    
    void settings() {
      size(1280, 720);
    }
    
    void setup() {
      p = new Particle(0, 0);
    }
    
    void draw() {
      background(255);
      p.update();
      p.display();
    }
    
    
    class Particle {
      PVector loc;
      PVector initLoc;
      PVector targetLoc;
      int amplitude = 200;
      float inc = 0;
      boolean restart;
    
      float sineFactor;
    
    
      Particle(int x, int y) {
        loc = new PVector(x, y);
        initLoc=loc.copy();
        targetLoc=loc.copy();
        restart = false;
        sineFactor=0;
      }
    
      void setMotionPos() {
        restart=true;
        sineFactor=0;
        targetLoc.set(random(-width/2, width/2), random(-height/2, height/2));
      }
    
      void update() {
        if (restart==true && sineFactor<PI) {   //Threshold 
    
          loc.set((targetLoc.x-loc.x), (targetLoc.y-loc.y));
          loc.mult(sin(sineFactor));
          sineFactor+=0.025;     //Speed factor
    
    
        } else {
          //loc=targetLoc.copy();
          restart=false;
          sineFactor=0;
        }
      }
    
    
      void display() {
        translate(width/2, height/2);
        stroke(0);
        strokeWeight(2);
        fill(127);
        ellipse(loc.x, loc.y, 20, 20);
      }
    }
    
    void keyReleased() {
    
      if (p.restart==false) {    
        p.setMotionPos();
      }
    }
    
Sign In or Register to comment.