add waypoints code
This commit is contained in:
parent
6bf5b1c544
commit
fff97d36b5
324
Boid.pde
324
Boid.pde
|
@ -6,171 +6,191 @@ class Crumb
|
||||||
PVector position;
|
PVector position;
|
||||||
Crumb(PVector position)
|
Crumb(PVector position)
|
||||||
{
|
{
|
||||||
this.position = position;
|
this.position = position;
|
||||||
}
|
}
|
||||||
void draw()
|
void draw()
|
||||||
{
|
{
|
||||||
fill(255);
|
fill(255);
|
||||||
noStroke();
|
noStroke();
|
||||||
circle(this.position.x, this.position.y, CRUMB_SIZE);
|
circle(this.position.x, this.position.y, CRUMB_SIZE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Boid
|
class Boid
|
||||||
{
|
{
|
||||||
Crumb[] crumbs = {};
|
Crumb[] crumbs = {};
|
||||||
int last_crumb;
|
int last_crumb;
|
||||||
float acceleration;
|
float acceleration;
|
||||||
float rotational_acceleration;
|
float rotational_acceleration;
|
||||||
KinematicMovement kinematic;
|
KinematicMovement kinematic;
|
||||||
PVector target;
|
PVector target;
|
||||||
|
|
||||||
Boid(PVector position, float heading, float max_speed, float max_rotational_speed, float acceleration, float rotational_acceleration)
|
Boid(PVector position, float heading, float max_speed, float max_rotational_speed, float acceleration, float rotational_acceleration)
|
||||||
{
|
{
|
||||||
this.kinematic = new KinematicMovement(position, heading, max_speed, max_rotational_speed);
|
this.kinematic = new KinematicMovement(position, heading, max_speed, max_rotational_speed);
|
||||||
this.last_crumb = millis();
|
this.last_crumb = millis();
|
||||||
this.acceleration = acceleration;
|
this.acceleration = acceleration;
|
||||||
this.rotational_acceleration = rotational_acceleration;
|
this.rotational_acceleration = rotational_acceleration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void update(float dt)
|
||||||
|
{
|
||||||
|
if (target != null)
|
||||||
|
{
|
||||||
|
// TODO: Implement seek here
|
||||||
|
|
||||||
|
|
||||||
|
//This makes a vector with the direction our boid needs to go to
|
||||||
|
PVector direction = PVector.sub(target, kinematic.position);
|
||||||
|
|
||||||
|
//atan2(direction.y, direction.x) will return the direction we need to go in radians
|
||||||
|
|
||||||
|
//print direction we need to go and the direction we are facing right now
|
||||||
|
//println(atan2(direction.y, direction.x) + " " + normalize_angle_left_right(kinematic.getHeading()));
|
||||||
|
|
||||||
|
float directionalThreshold = .1;
|
||||||
|
float angleToTarget = normalize_angle_left_right(atan2(direction.y, direction.x) - normalize_angle_left_right(kinematic.getHeading()));
|
||||||
|
float arrivalThreshold = 60.0;
|
||||||
|
|
||||||
|
//This just draws a circle for visual debugging purposes
|
||||||
|
circle(target.x, target.y, 3);
|
||||||
|
|
||||||
|
//prints the angle to the target
|
||||||
|
//println(angleToTarget);
|
||||||
|
|
||||||
|
//if the angle is larger than the threshold in the positive direction, rotate counterclockwise
|
||||||
|
if (angleToTarget >= .1) {
|
||||||
|
println("positive angle");
|
||||||
|
kinematic.increaseSpeed(0.0, 2);
|
||||||
|
|
||||||
void update(float dt)
|
|
||||||
{
|
|
||||||
if (target != null)
|
|
||||||
{
|
|
||||||
// TODO: Implement seek here
|
|
||||||
|
|
||||||
|
|
||||||
//This makes a vector with the direction our boid needs to go to
|
|
||||||
PVector direction = PVector.sub(target, kinematic.position);
|
|
||||||
|
|
||||||
//atan2(direction.y, direction.x) will return the direction we need to go in radians
|
|
||||||
|
|
||||||
//print direction we need to go and the direction we are facing right now
|
|
||||||
//println(atan2(direction.y, direction.x) + " " + normalize_angle_left_right(kinematic.getHeading()));
|
|
||||||
|
|
||||||
float directionalThreshold = .1;
|
|
||||||
float angleToTarget = atan2(direction.y, direction.x) - normalize_angle_left_right(kinematic.getHeading());
|
|
||||||
float arrivalThreshold = 60.0;
|
|
||||||
|
|
||||||
//This just draws a circle for visual debugging purposes
|
|
||||||
circle(target.x, target.y, 3);
|
|
||||||
|
|
||||||
//prints the angle to the target
|
|
||||||
//println(angleToTarget);
|
|
||||||
|
|
||||||
//if the angle is larger than the threshold in the positive direction, rotate counterclockwise
|
|
||||||
if (angleToTarget > directionalThreshold) {
|
|
||||||
kinematic.increaseSpeed(0.0, +1);
|
|
||||||
|
|
||||||
//if the angle is smaller than the threshold in the negative direction, rotate clockwise
|
//if the angle is smaller than the threshold in the negative direction, rotate clockwise
|
||||||
} else if (angleToTarget < -directionalThreshold) {
|
} else if (angleToTarget < -.1) {
|
||||||
kinematic.increaseSpeed(0.0, -1);
|
kinematic.increaseSpeed(0.0, -1);
|
||||||
|
|
||||||
//if the angle is within our threshold, stop our rotational velocity by rotating opposite
|
//if the angle is within our threshold, stop our rotational velocity by rotating opposite
|
||||||
} else if (directionalThreshold > angleToTarget) {
|
} else if (directionalThreshold > angleToTarget) {
|
||||||
|
|
||||||
if (kinematic.getRotationalVelocity() > 0) {
|
if (kinematic.getRotationalVelocity() > 0) {
|
||||||
kinematic.increaseSpeed(0.0, -1);
|
kinematic.increaseSpeed(0.0, -1);
|
||||||
}
|
} else if (kinematic.getRotationalVelocity() < 0) {
|
||||||
else if (kinematic.getRotationalVelocity() < 0) {
|
kinematic.increaseSpeed(0.0, 1);
|
||||||
kinematic.increaseSpeed(0.0, 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//Sometimes our Boid just goes and does weird things and I don't know why
|
|
||||||
|
//Sometimes our Boid just goes and does weird things and I don't know why
|
||||||
//if the target is outside its arrival threshold, accelerate.
|
|
||||||
//if the target is inside its arrival threshold, accelerate backwards until the speed is 0.
|
//if the target is outside its arrival threshold, accelerate.
|
||||||
if (direction.mag() > arrivalThreshold) {
|
//if the target is inside its arrival threshold, accelerate backwards until the speed is 0.
|
||||||
kinematic.increaseSpeed(1,0);
|
if (direction.mag() > arrivalThreshold) {
|
||||||
} else if (direction.mag() < arrivalThreshold) {
|
//println("main if");
|
||||||
//Need more specific code here to handle arrivals correctly
|
kinematic.increaseSpeed(.5, 0);
|
||||||
|
} else if (direction.mag() < arrivalThreshold) {
|
||||||
if (kinematic.getSpeed() < 40 && direction.mag() > 30) {
|
//Need more specific code here to handle arrivals correctly
|
||||||
kinematic.increaseSpeed(1,0);
|
|
||||||
} else if (kinematic.getSpeed() < 20 && direction.mag() > 15) {
|
if (kinematic.getSpeed() < 40 && direction.mag() > 30) {
|
||||||
kinematic.increaseSpeed(.75,0);
|
//println("if 1");
|
||||||
} else if (kinematic.getSpeed() < 10 && direction.mag() > 5) {
|
kinematic.increaseSpeed(1, 0);
|
||||||
kinematic.increaseSpeed(.5,0);
|
} else if (kinematic.getSpeed() < 20 && direction.mag() > 15) {
|
||||||
} else if (kinematic.getSpeed() < 5 && direction.mag() < 5) {
|
//println("if .75");
|
||||||
//This should ensure that the boid's speed can be dropped to exactly 0 so we don't have stuttering
|
kinematic.increaseSpeed(.75, 0);
|
||||||
kinematic.increaseSpeed(-kinematic.getSpeed(),0);
|
} else if (kinematic.getSpeed() < 10 && direction.mag() > 5) {
|
||||||
} else {
|
//println("if .5");
|
||||||
kinematic.increaseSpeed(-1,0);
|
kinematic.increaseSpeed(.5, 0);
|
||||||
}
|
} else if (kinematic.getSpeed() < 5 && direction.mag() < 5) {
|
||||||
|
//println("if -kin");
|
||||||
|
//This should ensure that the boid's speed can be dropped to exactly 0 so we don't have stuttering
|
||||||
|
|
||||||
|
kinematic.increaseSpeed(-kinematic.getSpeed(), 0);
|
||||||
|
} else {
|
||||||
|
println("else");
|
||||||
|
kinematic.increaseSpeed(-1, 0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//drawing a line for testing purposes
|
|
||||||
//line(kinematic.position.x, kinematic.position.y, kinematic.position.x + direction.x, kinematic.position.y + direction.y);
|
//drawing a line for testing purposes
|
||||||
|
//line(kinematic.position.x, kinematic.position.y, kinematic.position.x + direction.x, kinematic.position.y + direction.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
// place crumbs, do not change
|
||||||
|
if (LEAVE_CRUMBS && (millis() - this.last_crumb > CRUMB_INTERVAL))
|
||||||
|
{
|
||||||
|
this.last_crumb = millis();
|
||||||
|
this.crumbs = (Crumb[])append(this.crumbs, new Crumb(this.kinematic.position));
|
||||||
|
if (this.crumbs.length > MAX_CRUMBS)
|
||||||
}
|
this.crumbs = (Crumb[])subset(this.crumbs, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// do not change
|
||||||
|
this.kinematic.update(dt);
|
||||||
|
|
||||||
|
draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw()
|
||||||
|
{
|
||||||
|
for (Crumb c : this.crumbs)
|
||||||
|
{
|
||||||
|
c.draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
fill(255);
|
||||||
|
noStroke();
|
||||||
|
float x = kinematic.position.x;
|
||||||
|
float y = kinematic.position.y;
|
||||||
|
float r = kinematic.heading;
|
||||||
|
circle(x, y, BOID_SIZE);
|
||||||
|
// front
|
||||||
|
float xp = x + BOID_SIZE*cos(r);
|
||||||
|
float yp = y + BOID_SIZE*sin(r);
|
||||||
|
|
||||||
|
// left
|
||||||
|
float x1p = x - (BOID_SIZE/2)*sin(r);
|
||||||
|
float y1p = y + (BOID_SIZE/2)*cos(r);
|
||||||
|
|
||||||
|
// right
|
||||||
|
float x2p = x + (BOID_SIZE/2)*sin(r);
|
||||||
|
float y2p = y - (BOID_SIZE/2)*cos(r);
|
||||||
|
triangle(xp, yp, x1p, y1p, x2p, y2p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void seek(PVector target)
|
||||||
|
{
|
||||||
|
this.target = target;
|
||||||
|
}
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
//void follow(ArrayList<PVector> waypoints)
|
||||||
|
//{
|
||||||
|
|
||||||
// place crumbs, do not change
|
// //println("func count " + count);
|
||||||
if (LEAVE_CRUMBS && (millis() - this.last_crumb > CRUMB_INTERVAL))
|
// if(count > waypoints.size() - 1){
|
||||||
{
|
// this.target = waypoints.get(0);
|
||||||
this.last_crumb = millis();
|
// return;
|
||||||
this.crumbs = (Crumb[])append(this.crumbs, new Crumb(this.kinematic.position));
|
// }
|
||||||
if (this.crumbs.length > MAX_CRUMBS)
|
// else {
|
||||||
this.crumbs = (Crumb[])subset(this.crumbs, 1);
|
// // TODO: change to follow *all* waypoints
|
||||||
}
|
// println("count " + count);
|
||||||
|
// this.target = waypoints.get(count);
|
||||||
|
// PVector temp = waypoints.remove(count);
|
||||||
|
// count++;
|
||||||
|
// //count--;
|
||||||
|
|
||||||
|
// follow(waypoints);
|
||||||
|
// }
|
||||||
|
|
||||||
|
//}
|
||||||
|
void follow(ArrayList<PVector> waypoints)
|
||||||
|
{
|
||||||
|
this.target = waypoints.get(0);
|
||||||
|
|
||||||
// do not change
|
for (int i = 1; i < waypoints.size(); i++){
|
||||||
this.kinematic.update(dt);
|
if(PVector.sub(this.target,this.kinematic.position).mag() = 0)
|
||||||
|
this.target = waypoints.get(i);
|
||||||
draw();
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
void draw()
|
|
||||||
{
|
|
||||||
for (Crumb c : this.crumbs)
|
|
||||||
{
|
|
||||||
c.draw();
|
|
||||||
}
|
|
||||||
|
|
||||||
fill(255);
|
|
||||||
noStroke();
|
|
||||||
float x = kinematic.position.x;
|
|
||||||
float y = kinematic.position.y;
|
|
||||||
float r = kinematic.heading;
|
|
||||||
circle(x, y, BOID_SIZE);
|
|
||||||
// front
|
|
||||||
float xp = x + BOID_SIZE*cos(r);
|
|
||||||
float yp = y + BOID_SIZE*sin(r);
|
|
||||||
|
|
||||||
// left
|
|
||||||
float x1p = x - (BOID_SIZE/2)*sin(r);
|
|
||||||
float y1p = y + (BOID_SIZE/2)*cos(r);
|
|
||||||
|
|
||||||
// right
|
|
||||||
float x2p = x + (BOID_SIZE/2)*sin(r);
|
|
||||||
float y2p = y - (BOID_SIZE/2)*cos(r);
|
|
||||||
triangle(xp, yp, x1p, y1p, x2p, y2p);
|
|
||||||
}
|
|
||||||
|
|
||||||
void seek(PVector target)
|
|
||||||
{
|
|
||||||
this.target = target;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void follow(ArrayList<PVector> waypoints)
|
|
||||||
{
|
|
||||||
// TODO: change to follow *all* waypoints
|
|
||||||
this.target = waypoints.get(0);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
17
Flocking.pde
17
Flocking.pde
|
@ -1,7 +1,24 @@
|
||||||
|
|
||||||
/// called when "f" is pressed; should instantiate additional boids and start flocking
|
/// called when "f" is pressed; should instantiate additional boids and start flocking
|
||||||
|
Boid[] billies = new Boid[8];
|
||||||
void flock()
|
void flock()
|
||||||
{
|
{
|
||||||
|
int lasttr = 0;
|
||||||
|
println("flock called");
|
||||||
|
float dt = (millis() - lasttr)/1000.0;
|
||||||
|
lasttr = millis();
|
||||||
|
PVector target = new PVector(mouseX, mouseY);
|
||||||
|
|
||||||
|
for(int i = 0; i < 7; i++)
|
||||||
|
{
|
||||||
|
billies[i] = new Boid(new PVector(100 + i*100, 500), BILLY_START_HEADING, BILLY_MAX_SPEED, BILLY_MAX_ROTATIONAL_SPEED, BILLY_MAX_ACCELERATION, BILLY_MAX_ROTATIONAL_ACCELERATION);
|
||||||
|
println("billy " + billies[i].toString());
|
||||||
|
|
||||||
|
billies[i].update(dt);
|
||||||
|
billies[i].seek(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// called when "f" is pressed again; should remove the flock
|
/// called when "f" is pressed again; should remove the flock
|
||||||
|
|
Loading…
Reference in New Issue