This commit is contained in:
Priyatham Sai Chand 2022-10-31 13:00:04 -07:00
commit 677492eb09
5 changed files with 49 additions and 697 deletions

View File

@ -133,7 +133,7 @@ class Boid
dotProductOfTargets = (dotProductOfTargets + 1) / 2;
//use an ideal speed for our boid, to tell it to either speed up or slow down whether it's going faster than this or not
float idealSpeed = dotProductOfTargets * 20 + 10;
float idealSpeed = dotProductOfTargets * 80 + 10;
if (kinematic.getSpeed() < idealSpeed) {
kinematic.increaseSpeed(1,0);
@ -141,36 +141,35 @@ class Boid
kinematic.increaseSpeed(-1,0);
}
/*
if (kinematic.getSpeed() < 40 && direction.mag() > 30) {
kinematic.increaseSpeed(1,0);
} else if (kinematic.getSpeed() < 20 && direction.mag() > 15) {
kinematic.increaseSpeed(.75,0);
} else if (kinematic.getSpeed() < 10 && direction.mag() > 5) {
kinematic.increaseSpeed(.5,0);
} else if (kinematic.getSpeed() < 5 && direction.mag() < 5) {
//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 {
kinematic.increaseSpeed(-1,0);
}
*/
} else {
//if no more targets to check, do the normal calculation
if (kinematic.getSpeed() < 40 && direction.mag() > 30) {
//kinematic.getSpeed() is how fast we're moving, direction.mag() is how far are we from target
//Ideal speed here should be 80 at dist 85, and reduce linearly from there, hitting 0 at 5 units?
//This can be changed later if it isn't good
float idealSpeed = (1 * direction.mag() - 5);
//if idealSpeed is "negative" we should just set it to 0
if (idealSpeed < 0) {
idealSpeed = 0;
}
//use this to know how off the target speed we are, and slow down accordingly
//This will be positive if the ideal speed is higher than current speed, negative if ideal speed is lower.
float speedOffset = (idealSpeed - kinematic.getSpeed());
if (abs(speedOffset) < 1) {
kinematic.increaseSpeed(speedOffset, 0);
} else if (idealSpeed < speedOffset) {
kinematic.increaseSpeed(1,0);
} else if (kinematic.getSpeed() < 20 && direction.mag() > 15) {
kinematic.increaseSpeed(.75,0);
} else if (kinematic.getSpeed() < 10 && direction.mag() > 5) {
kinematic.increaseSpeed(.5,0);
} else if (kinematic.getSpeed() < 5 && direction.mag() < 5) {
//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 {
} else if (idealSpeed > speedOffset) {
kinematic.increaseSpeed(-1,0);
}
}
@ -178,19 +177,33 @@ class Boid
//if waypoints is null, do normal things
println("waypoints is null");
//This code should trigger if there's only one target left
if (kinematic.getSpeed() < 40 && direction.mag() > 30) {
kinematic.increaseSpeed(1,0);
} else if (kinematic.getSpeed() < 20 && direction.mag() > 15) {
kinematic.increaseSpeed(.75,0);
} else if (kinematic.getSpeed() < 10 && direction.mag() > 5) {
kinematic.increaseSpeed(.5,0);
} else if (kinematic.getSpeed() < 5 && direction.mag() < 5) {
//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 {
kinematic.increaseSpeed(-1,0);
}
//kinematic.getSpeed() is how fast we're moving, direction.mag() is how far are we from target
//Ideal speed here should be 80 at dist 85, and reduce linearly from there, hitting 0 at 5 units?
//This can be changed later if it isn't good
float idealSpeed = 1 * direction.mag() - 5;
//if idealSpeed is "negative" we should just set it to 0
if (idealSpeed < 0) {
idealSpeed = 0;
}
println(idealSpeed);
//use this to know how off the target speed we are, and slow down accordingly
//This will be positive if the ideal speed is higher than current speed, negative if ideal speed is lower.
float speedOffset = (idealSpeed - kinematic.getSpeed());
if (abs(speedOffset) < 1) {
kinematic.increaseSpeed(speedOffset, 0);
} else if (idealSpeed < speedOffset) {
kinematic.increaseSpeed(1,0);
} else if (idealSpeed > speedOffset) {
kinematic.increaseSpeed(-1,0);
}
}

View File

@ -1,99 +0,0 @@
/// In this file, you will have to implement seek and waypoint-following
/// The relevant locations are marked with "TODO"
class Crumb
{
PVector position;
Crumb(PVector position)
{
this.position = position;
}
void draw()
{
fill(255);
noStroke();
circle(this.position.x, this.position.y, CRUMB_SIZE);
}
}
class Boid
{
Crumb[] crumbs = {};
int last_crumb;
float acceleration;
float rotational_acceleration;
KinematicMovement kinematic;
PVector target;
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.last_crumb = millis();
this.acceleration = acceleration;
this.rotational_acceleration = rotational_acceleration;
}
void update(float dt)
{
if (target != null)
{
// TODO: Implement seek here
print(kinematic.getHeading());
}
// 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;
}
void follow(ArrayList<PVector> waypoints)
{
// TODO: change to follow *all* waypoints
this.target = waypoints.get(0);
}
}

View File

@ -1,189 +0,0 @@
/// In this file, you will have to implement seek and waypoint-following
/// The relevant locations are marked with "TODO"
class Crumb
{
PVector position;
Crumb(PVector position)
{
this.position = position;
}
void draw()
{
fill(255);
noStroke();
circle(this.position.x, this.position.y, CRUMB_SIZE);
}
}
class Boid
{
Crumb[] crumbs = {};
int last_crumb;
float acceleration;
float rotational_acceleration;
KinematicMovement kinematic;
PVector target;
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.last_crumb = millis();
this.acceleration = 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);
//if the angle is smaller than the threshold in the negative direction, rotate clockwise
} else if (angleToTarget < -.1) {
kinematic.increaseSpeed(0.0, -1);
//if the angle is within our threshold, stop our rotational velocity by rotating opposite
} else if (directionalThreshold > angleToTarget) {
if (kinematic.getRotationalVelocity() > 0) {
kinematic.increaseSpeed(0.0, -1);
} else if (kinematic.getRotationalVelocity() < 0) {
kinematic.increaseSpeed(0.0, 1);
}
//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 (direction.mag() > arrivalThreshold) {
kinematic.increaseSpeed(1,0);
} else if (direction.mag() < arrivalThreshold) {
//Need more specific code here to handle arrivals correctly
if (kinematic.getSpeed() < 40 && direction.mag() > 30) {
kinematic.increaseSpeed(1,0);
} else if (kinematic.getSpeed() < 20 && direction.mag() > 15) {
kinematic.increaseSpeed(.75,0);
} else if (kinematic.getSpeed() < 10 && direction.mag() > 5) {
kinematic.increaseSpeed(.5,0);
} else if (kinematic.getSpeed() < 5 && direction.mag() < 5) {
//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 {
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);
}
// 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)
//{
// //println("func count " + count);
// if(count > waypoints.size() - 1){
// this.target = waypoints.get(0);
// return;
// }
// else {
// // 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);
}
}

View File

@ -1,175 +0,0 @@
/// In this file, you will have to implement seek and waypoint-following
/// The relevant locations are marked with "TODO"
class Crumb
{
PVector position;
Crumb(PVector position)
{
this.position = position;
}
void draw()
{
fill(255);
noStroke();
circle(this.position.x, this.position.y, CRUMB_SIZE);
}
}
class Boid
{
Crumb[] crumbs = {};
int last_crumb;
float acceleration;
float rotational_acceleration;
KinematicMovement kinematic;
PVector target;
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.last_crumb = millis();
this.acceleration = 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(atan2(direction.y, direction.x)) - kinematic.getHeading();
float arrivalThreshold = 60.0;
//This just draws a circle for visual debugging purposes
//circle(target.x, target.y, arrivalThreshold);
//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
} else if (angleToTarget < -directionalThreshold) {
kinematic.increaseSpeed(0.0, -1);
//if the angle is within our threshold, stop our rotational velocity by rotating opposite
} else if (directionalThreshold > angleToTarget) {
if (kinematic.getRotationalVelocity() > 0) {
kinematic.increaseSpeed(0.0, -1);
}
else if (kinematic.getRotationalVelocity() < 0) {
kinematic.increaseSpeed(0.0, 1);
}
}
//Slight flaw: since the arrival threshold is so big, the boid just won't move if its target is that close.
//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 (direction.mag() > arrivalThreshold) {
kinematic.increaseSpeed(1,0);
} else if (direction.mag() < arrivalThreshold) {
//Need more specific code here to handle arrivals correctly
if (kinematic.getSpeed() < 40 && direction.mag() > 30) {
kinematic.increaseSpeed(1,0);
} else if (kinematic.getSpeed() < 20 && direction.mag() > 15) {
kinematic.increaseSpeed(.75,0);
} else if (kinematic.getSpeed() < 10 && direction.mag() > 5) {
kinematic.increaseSpeed(.5,0);
} else if (kinematic.getSpeed() < 5 && direction.mag() < 3) {
kinematic.increaseSpeed(.25,0);
} 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);
}
// 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;
}
void follow(ArrayList<PVector> waypoints)
{
// TODO: change to follow *all* waypoints
this.target = waypoints.get(0);
}
}

View File

@ -1,198 +0,0 @@
/// In this file, you will have to implement seek and waypoint-following
/// The relevant locations are marked with "TODO"
class Crumb
{
PVector position;
Crumb(PVector position)
{
this.position = position;
}
void draw()
{
fill(255);
noStroke();
circle(this.position.x, this.position.y, CRUMB_SIZE);
}
}
class Boid
{
Crumb[] crumbs = {};
int last_crumb;
float acceleration;
float rotational_acceleration;
KinematicMovement kinematic;
PVector target;
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.last_crumb = millis();
this.acceleration = 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);
//if the angle is smaller than the threshold in the negative direction, rotate clockwise
} else if (angleToTarget < -.1) {
kinematic.increaseSpeed(0.0, -1);
//if the angle is within our threshold, stop our rotational velocity by rotating opposite
} else if (directionalThreshold > angleToTarget) {
if (kinematic.getRotationalVelocity() > 0) {
kinematic.increaseSpeed(0.0, -1);
} else if (kinematic.getRotationalVelocity() < 0) {
kinematic.increaseSpeed(0.0, 1);
}
}
//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 (direction.mag() > arrivalThreshold) {
//println("main if");
kinematic.increaseSpeed(.5, 0);
} else if (direction.mag() < arrivalThreshold) {
//Need more specific code here to handle arrivals correctly
if (kinematic.getSpeed() < 40 && direction.mag() > 30) {
//println("if 1");
kinematic.increaseSpeed(1, 0);
} else if (kinematic.getSpeed() < 20 && direction.mag() > 15) {
//println("if .75");
kinematic.increaseSpeed(.75, 0);
} else if (kinematic.getSpeed() < 10 && direction.mag() > 5) {
//println("if .5");
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);
}
// 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)
//{
// //println("func count " + count);
// if(count > waypoints.size() - 1){
// this.target = waypoints.get(0);
// return;
// }
// else {
// // 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);
// println("distance " + PVector.sub(this.target,this.kinematic.position).mag());
for (int i = 1; i < waypoints.size(); i++){
println("distance " + PVector.sub(this.target,this.kinematic.position).mag());
if(PVector.sub(this.target,this.kinematic.position).mag() < 4)
this.target = waypoints.get(i);
}
}
}