We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpPrograms › Constant Velocity
Page Index Toggle Pages: 1
Constant Velocity (Read 983 times)
Constant Velocity
Feb 9th, 2007, 6:21pm
 
I'm giving my Boid a heading to follow and I want it to fly at a constant speed in that direction. How can I turn the code in the block if(mousepressed){} into a, "engines at half impulse towards the mouse pointer"?

This is given that I want to write accleration into it later.
Code:

Boid boid = new Boid(50, 50);
void setup(){
size(400, 400);
smooth();
frameRate(24);
}
void draw(){
background(250);
boid.tick();
if(mousePressed){
boid.t = boid.theta(mouseX, mouseY);
}
boid.draw();
}
class Boid{
float x, y, xV, yV, xA, yA, t;
Boid(float x, float y){
this.x = x;
this.y = y;
xV = 0.0f;
yV = 0.0f;
xA = 0.0f;
yA = 0.0f;
t = random(TWO_PI);
}
void tick(){
xV += xA;
yV += yA;
x += xV;
y += yV;
t = theta(yV, xV);
}
void draw(){
ellipse(x, y, 20, 20);
float xt = x + cos(t) * 30;
float yt = y + sin(t) * 30;
line(x, y, xt, yt);
}
float theta(float x, float y){
return atan2(y - this. y, x - this.x);
}
}
Re: Constant Velocity
Reply #1 - Feb 9th, 2007, 11:59pm
 
st33d wrote on Feb 9th, 2007, 6:21pm:
I'm giving my Boid a heading to follow and I want it to fly at a constant speed in that direction. How can I turn the code in the block if(mousepressed){} into a, "engines at half impulse towards the mouse pointer"


Try thinking in vector terms instead of trig terms.

Your "heading", defined at mouseX-this.x,mouseY-this.y is a vector.  Problem is, it isn't normalized (that is, it's not on the unit circle).  To normalize, divide by its magnitude (that is, its length).

In rough off top of head psuedocode:

vx = mouseX - this.x;
vy = mouseY - this.y;
mag = sqrt(vx*vx+vy*vy);
vx /= mag;
vy /= mag;

At that point, you'll have a unit velocity vector in the desired direction.  To move at a given speed, say 4 units per frame, simply multiply your vector by desired speed and add to position:

speed = 4;
x += vx * speed;
y += vy * speed;

Alternatively, if you NEED to work in trig terms, continue calculating theta with atan2() and just use sin/cos on theta to reconstruct vx/vy whenever needed:

x += cos(theta) * speed; // cos(theta) == vx normalized
y += sin(theta) * speed; // sin(theta) == vy normalized

The methods are equivalent, but the vector method has performance advantages (a lot less trig calls).
Re: Constant Velocity
Reply #2 - Feb 11th, 2007, 4:20pm
 
Thanks for that. I always wondered what normalising vectors did. I only need the trig because of turning the boid whilst in mid flight. This is because of the obstacle avoidance that the boid needs to learn.

Code:

Boid boid = new Boid(50, 50);
void setup(){
size(400, 400);
smooth();
frameRate(24);
}
void draw(){
//background(250);
boid.tick();
if(mousePressed){
boid.heading(mouseX, mouseY, 5.0);
println(boid.xV + " " + boid.yV);
}
if(keyPressed){
switch(key){
case 'a':
boid.turn(-0.1);
break;
case 'd':
boid.turn(0.1);
break;
}
}
boid.draw();
}
class Boid{
float x, y, xV, yV, xA, yA, t, s;
Boid(float x, float y){
this.x = x;
this.y = y;
xV = 0.0f;
yV = 0.0f;
xA = 0.0f;
yA = 0.0f;
t = random(TWO_PI);
s = 0;
}
void tick(){
xV += xA;
yV += yA;
x += xV;
y += yV;
}
void setV(float x, float y){
xV = x;
yV = y;
}
void turn(float r){
t += r;
if(s != 0.0){
xV = cos(t) * s;
yV = sin(t) * s;
}
}
void heading(float x, float y, float speed){
float xD = x - this.x;
float yD = y - this.y;
float vL = sqrt((xD * xD) + (yD * yD));
s = speed;
xV = (xD / vL) * s;
yV = (yD / vL) * s;
t = theta(x, y);
}
void draw(){
ellipse(x, y, 20, 20);
float xt = x + cos(t) * 30;
float yt = y + sin(t) * 30;
line(x, y, xt, yt);
}
float theta(float x, float y){
return atan2(y - this.y, x - this.x);
}
}


I gave trig vs vector a quick speed test. Vector wins (x4 speed), but unfortunately I'm needing to do a little bit of trig in the heading to calculate the rotation of the bot. But where a graphic of the rotation isn't necessary it's going to be a lot faster.
Page Index Toggle Pages: 1