Change moving angle by changing the moving directions/speeds

void turn(float angle) {
   // need to change xSpeed and ySpeed so that object will move
   // with that changed angle
}

My problem is that I need to change the direction of the moving object counterclockwise with the angle parameter. The method has to change the xSpeed and ySpeed values which are getting added to the position x and y respectively in the move method.

for an example:

let’s say current xSpeed = 10, ySpeed = -10. the combined vector would be the square root of 200, 45 degrees clockwise from the y axis. So when I pass 45 to this method angle parameter the xSpeed should change to be 0, and ySpeed should be -10 (no change in this case). because when I move the previously combined vector (square root of 200) counterclockwise to 45 degrees, now the object should be moving directly UP with that same combined vector. If that makes sense.

I think this has something to do with trigonometrical ratios, I’m looking for a solution. I really appreciate if someone can help me with this.

Thanks!

see Trigonometry Primer \ Processing.org

you can add seed to your player

let seed;

function setup() {
  createCanvas(1000,1000);
  angleMode(DEGREES); // Change the mode to DEGREES
  
  seed = createVector(0, 0);
}

function draw() {
  background(51);
  
  let angle=185; 
  seed.x=cos(angle) * 30 + width/2;
  seed.y=sin(angle) * 30 + height/2; 
  
  line(width/2,height/2,seed.x,seed.y);

}

1 Like

Thanks for your response. however this seems like not the solution to my particular problem. In fact, I don’t have any idea why that formula multiplied by a constant 30. :confused:

I am not sure, but maby what you are looking for is this:
PVector.fromAngle(radians(ANGLE));

here is a processing example

you can steer the ball with left and right cursor

The functions turnRight and turnLeft receive the angle and xSpeed and ySpeed gets changed accordingly.


float ax=300, ay=330; 
float xSpeed=1, ySpeed=1;
float prevAngle; 

void setup() {
  size(1300, 800);
  frameRate(23);
}

void draw() {
  // background(51);

  ax+=xSpeed;
  ay+=ySpeed;

  fill(255);
  ellipse(ax, ay, 17, 17);

  //if (frameCount % 3 == 0)
  //  turnLeft(10);

  if (keyPressed) {
    if (keyCode==LEFT)
      turnLeft(10); 
    else if (keyCode==RIGHT)
      turnRight(10);
  }
}

//-----------------------------------------------------------------------

void turnRight(float angle) {
  // receives angle in degree 
  // turn right 
  // need to change xSpeed and ySpeed so that object will move
  // with that changed angle

  float angle2=radians(angle)+prevAngle;
  prevAngle=angle2;
  xSpeed=cos(angle2) * 3 ;
  ySpeed=sin(angle2) * 3 ;
}

void turnLeft(float angle) {
  // receives angle in degree 
  // turn right 
  // need to change xSpeed and ySpeed so that object will move
  // with that changed angle

  float angle2=prevAngle-radians(angle);
  prevAngle=angle2;
  xSpeed=cos(angle2) * 3 ;
  ySpeed=sin(angle2) * 3 ;
}

new version


float ax=300, ay=330; 
float xSpeed=0, ySpeed=0;
float prevAngle; 

void setup() {
  size(1300, 800);
  background(210);
  frameRate(23);
  turnRight(0);
}

void draw() {
  // background(51);

  ax+=xSpeed;
  ay+=ySpeed;

  fill(255);
  ellipse(ax, ay, 17, 17);

  //if (frameCount % 3 == 0)
  //  turnLeft(10);

  if (keyPressed) {
    if (keyCode==LEFT)
      turnLeft(10); 
    else if (keyCode==RIGHT)
      turnRight(10);
    else if (key=='c')
      background(210);
  }
}

//-----------------------------------------------------------------------

void turnRight(float angle) {
  // receives angle in degree 
  // turn right 
  // need to change xSpeed and ySpeed so that object will move
  // with that changed angle

  float angle2=radians(angle)+prevAngle;
  prevAngle=angle2;
  xSpeed=cos(angle2) * 3 ;
  ySpeed=sin(angle2) * 3 ;
}

void turnLeft(float angle) {
  // receives angle in degree 
  // turn right 
  // need to change xSpeed and ySpeed so that object will move
  // with that changed angle

  float angle2=prevAngle-radians(angle);
  prevAngle=angle2;
  xSpeed=cos(angle2) * 3 ;
  ySpeed=sin(angle2) * 3 ;
}

1 Like

Thank you, this is really what I’m looking for. but this code has a bug. Just change the parameter values to 45 degrees and see. It does total nonsense. If this piece of code works as how it’s intended to work, this is exactly what I’m looking for.

image

I’m not sure how I can do anything about it. if you can do a snippet for me, that’d be really awesome. Thanks for your response anyways.

I am not at the computer right now

I can’t see any errors in the code

Or maybe you have another expectation than I.

You sure there’s an error?

Can you please show your entire code?

1 Like

There’s no error, but there is a bug. code executes perfectly. here is my whole code:

Cow.pde

public class Cow { 
  float x, y, dx, dy, radius;
  color c;
  boolean colliding = false;
  boolean selected = true;
  float prevAngle = 0;

  Cow(float rad, float x, float y, float dx, float dy) {
    radius = rad;
    this.x = x;
    this.y = y;
    this.dx = 5;//(int)(dx*100)/100.0;
    this.dy = -5;//(int)(dy*100)/100.0;
    c = color(random(255), random(255), random(255));
  }

  Cow() {
    this(20+(int)(Math.random()*30), width/2, height/2, random(6)-3, random(6)-3);
  }

  void move() {
    int mult = 1;
    if (selected && colliding) {
      mult = 2;
    } 

    x += dx * mult;
    y += dy * mult;

    if (x + radius > width || x - radius < 0) dx *= -1;
    if (y + radius > height || y - radius < 0) dy *= -1;
  }

  void display() {
    noStroke();

    if (colliding) {
      fill(255, 0, 0, 100);
    } else {
      fill(c);
    }

    ellipse(x, y, radius*2, radius*2);

    if (selected) {
      fill(255);
      ellipse(x-10, y, 5, 5);
      ellipse(x+10, y, 5, 5);
    }
  }

  void click() {
    if (dist(mouseX, mouseY, this.x, this.y) <= radius) {
      selected = !selected;
    }
  }

  void collide(ArrayList<Cow> others) {
    int counter = 0;
    for (Cow oc : others) {
      if (oc != this && dist(oc.x, oc.y, this.x, this.y) <= (oc.radius + this.radius)) {
        counter ++;
      }
    }
    if (counter > 0) colliding = true;
    else colliding = false;
  }

  void turn(float angle) {
    float newAngle = prevAngle-radians(angle);
    prevAngle = newAngle;
    dx = cos(newAngle)*5;
    dy = sin(newAngle)*5;
  }

  void changeSpeed(float dv) {
    this.dx += dv;
    this.dy += dv;
  }
}

CowDemo.pde

ArrayList<Cow> cows;

void setup() {
  frameRate(30);
  size(1000, 800);
  //size(300, 300);
  cows = new ArrayList<Cow>();
  for (int i = 0; i < 1; i++) {
    cows.add(new Cow());
  }
}

void draw() {
  background(200);

  int showPos = 1;
  for (Cow c : cows) {
    c.collide(cows);
    c.move();
    c.display();

    if (c.selected) {
      fill(0);
      text("Dx: "+c.dx+" Dy: "+c.dy, width-200, 20*showPos);
      showPos++;
    }
  }

  fill(0);
  textSize(20);
  text("FPS: "+frameRate+"Cows: "+cows.size(), 0, 20);
}

void mousePressed() {
  if (mouseButton == RIGHT) {
    cows.add(new Cow(20+(int)(Math.random()*30), mouseX, mouseY, random(6)-3, random(6)-3));
  }

  for (Cow c : cows) {
    c.turn(90);
  }  
}

void keyPressed() {
  if (keyCode == 32) {
    cows.clear();
  }
}

In this configuration, All seems working fine, except the first turn becomes wrong. I’ve set the angle to 90. but when i execute turn first time it does 45 degree angle. and then onwards it does 90 degree as intended.

After adding a new cow (or in the constructor of the class), can you please say turn(0);

Besides, angle of 0 is east not north in processing

1 Like

If I do so, it doesn’t work as intended. because the initial angle is generated randomly and if after constructor if I say turn(0) it starts to go in a single direction. so that doesn’t work. again that constant 5 in the turn method doesn’t make any sense in this context.

we already know currently changing x and y size. so basically what we need to calculate is the x, y result when the combined vector of current speedX, speedY changed by the given angle. so theoretically there shouldn’t be any constant used.



ArrayList<Cow> cows;

void setup() {
  frameRate(30);
  size(1000, 800);
  //size(300, 300);
  cows = new ArrayList<Cow>();
  for (int i = 0; i < 1; i++) {
    cows.add(new Cow());
  }
}

void draw() {
  background(200);

  int showPos = 1;
  for (Cow c : cows) {
    c.collide(cows);
    c.move();
    c.display();

    if (c.selected) {
      fill(0);
      text("Dx: "+c.dx+" Dy: "+c.dy, width-200, 20*showPos);
      showPos++;
    }
  }

  fill(0);
  textSize(20);
  text("FPS: "
    +nfs(int(frameRate), 0)
    +" Cows: "
    +cows.size(), 
    0, 20);
}

// ---------------------------------------------------------------------------------

void mousePressed() {
  if (mouseButton == RIGHT) {
    cows.add(new Cow(20+(int)(Math.random()*30), mouseX, mouseY, random(6)-3, random(6)-3));
  } else {
    for (Cow c : cows) {
      c.turn(90);
    }
  }
}

void keyPressed() {
  if (keyCode == 32) {
    cows.clear();
  }
}

// =======================

public class Cow { 
  float x, y, dx, dy, radius;
  color c;
  boolean colliding = false;
  boolean selected = true;
  float prevAngle = 0;

  Cow(float rad, float x, float y, float dx, float dy) {
    radius = rad;
    this.x = x;
    this.y = y;
    this.dx = 0;//(int)(dx*100)/100.0;
    this.dy = 0;//(int)(dy*100)/100.0;
    turn(45);
    c = color(random(255), random(255), random(255));
  }

  Cow() {
    this(20+(int)(Math.random()*30), width/2, height/2, random(6)-3, random(6)-3);
  }

  void move() {
    int mult = 1;
    if (selected && colliding) {
      mult = 2;
    } 

    x += dx * mult;
    y += dy * mult;

    if (x + radius > width || x - radius < 0)
      dx *= -1;
    if (y + radius > height || y - radius < 0) 
      dy *= -1;
  }

  void display() {
    noStroke();

    if (colliding) {
      fill(255, 0, 0, 100);
    } else {
      fill(c);
    }

    ellipse(x, y, radius*2, radius*2);

    if (selected) {
      fill(255);
      ellipse(x-10, y, 5, 5);
      ellipse(x+10, y, 5, 5);
    }
  }

  void click() {
    if (dist(mouseX, mouseY, this.x, this.y) <= radius) {
      selected = !selected;
    }
  }

  void collide(ArrayList<Cow> others) {
    int counter = 0;
    for (Cow oc : others) {
      if (oc != this && dist(oc.x, oc.y, this.x, this.y) <= (oc.radius + this.radius)) {
        counter ++;
      }
    }
    if (counter > 0) colliding = true;
    else colliding = false;
  }

  void turn(float angle) {
    float newAngle = prevAngle-radians(angle);
    prevAngle = newAngle;
    dx = cos(newAngle)*5;
    dy = sin(newAngle)*5;
  }

  void changeSpeed(float dv) {
    this.dx += dv;
    this.dy += dv;
  }
}