// Alignment // Calculates the average velocity of boids in the field of vision and // manipulates the velocity of the current boid in order to match it Pvector Boid::Alignment(vector<Boid> Boids) { float neighbordist = desAli; // Field of vision Pvector sum(0, 0); int count = 0; for (int i = 0; i < Boids.size(); i++) { float d = location.distance(Boids[i].location); if ((d > 0) && (d < neighbordist)) { // 0 < d < 50 sum.addVector(Boids[i].velocity); count++; } } // If there are boids close enough for alignment... if (count > 0) { sum.divScalar(static_cast<float>(count));// Divide sum by the number of close boids (average of velocity) sum.normalize(); // Turn sum into a unit vector, and sum.mulScalar(maxSpeed); // Multiply by maxSpeed // Steer = Desired - Velocity Pvector steer; steer = steer.subTwoVector(sum, velocity); //sum = desired(average) steer.limit(maxForce); return steer; } else { Pvector temp(0, 0); return temp; } }
void Boid::AvoidAsteroids(vector<Boid> v, sf::Vector2f asteroidPos) { Pvector sep = AsteroidSeparation(v, asteroidPos); // Arbitrarily weight these forces sep.mulScalar(1.5); // Add the force vectors to acceleration applyForce(sep); }
// Limits the maxSpeed, finds necessary steering force and // normalizes vectors Pvector Boid::seek(Pvector v) { Pvector desired; desired.subVector(v); // A vector pointing from the location to the target // Normalize desired and scale to maximum speed desired.normalize(); desired.mulScalar(maxSpeed); // Steering = Desired minus Velocity acceleration.subTwoVector(desired, velocity); acceleration.limit(maxForce); // Limit to maximum steering force return acceleration; }
Pvector Predator::Seek(Pvector playerLocation) { auto temp = playerLocation; temp.subScalar(30); Pvector desired = temp - *location; // desired.subVector(playerLocation); // A vector pointing from the location to the target // Normalize desired and scale to maximum speed desired.normalize(); desired.mulScalar(speed); // Steering = Desired minus Velocity *acceleration = desired - *velocity; acceleration->limit(maxSteeringForce); // Limit to maximum steering force return *acceleration; }
// Alignment calculates the average velocity in the field of view and // manipulates the velocity of the Boid passed as parameter to adjust to that // of nearby boids. Pvector Boid::Alignment(vector<Boid> Boids) { // If the boid we're looking at is a predator, do not run the alignment // algorithm //if (predator == true) // return Pvector(0,0); float neighbordist = 140; float neighbordist2 = 140; Pvector sum(0, 0); int count = 0; for (int i = 0; i < Boids.size(); i++) { float d = location.distance(Boids[i].location); if ((d > 0) && (d < neighbordist2) && boidType == FACTORY) // 0 < d < 50 { sum.addVector(Boids[i].velocity); count++; } if ((d > 0) && (d < neighbordist) && boidType == FLOCK) // 0 < d < 50 { sum.addVector(Boids[i].velocity); count++; } } // If there are boids close enough for alignment... if (count > 0) { sum.divScalar((float)count);// Divide sum by the number of close boids (average of velocity) sum.normalize(); // Turn sum into a unit vector, and sum.mulScalar(maxSpeed); // Multiply by maxSpeed // Steer = Desired - Velocity Pvector steer; steer = steer.subTwoVector(sum, velocity); //sum = desired(average) steer.limit(maxForce); return steer; } else { Pvector temp(0, 0); return temp; } }
tuple<bool, Pvector> Boid::CalcLJ(Boid b, sf::Vector2f playerPos) { Pvector R; Pvector p(playerPos.x, playerPos.y); float neighbordist = 500; float neighbordist2 = 200; float A = 100; float B = 5000; float N = 1; float M = 2; float d = location.distance(b.location); float d2 = location.distance(p); if ((d2 > 0) && (d2 < neighbordist2)) { R = location; R.subVector(p); float D = R.magnitude(); float U = -A / pow(D, N) + B / pow(D, M); R.normalize(); R.mulScalar(U); return tuple<bool, Pvector>(true, R); } else if ((d > 0) && (d < neighbordist)) // 0 < d < 500 { R = location; R.subVector(b.location); float D = R.magnitude(); float U = -A / pow(D, N) + B / pow(D, M); R.normalize(); R.mulScalar(U); return tuple<bool, Pvector>(true, R); } else return tuple<bool, Pvector>(false, R); }
//This function is provided to aid you. //It should be used in the spirit of recursion, though you may choose not to. //This function takes an empty vector of points, accum //It also takes a set of control points, pts, and fills accum with //the control points that correspond to the next level of detail. void accumulateNextLevel(Pvector* accum, Pvector pts) { if (pts.empty()) return; accum->push_back(*(pts.begin())); if (pts.size() == 1) return; for (Pvector::iterator it = pts.begin(); it != pts.end() - 1; it++) { /* YOUR CODE HERE (only one to three lines)*/ } //save the last point Point last = *(pts.end()-1); pts.pop_back(); //recursive call accumulateNextLevel(accum, pts); accum->push_back(last); }
// Applies the three laws to the flock of boids void Boid::flock(vector<Boid> v) { Pvector sep = Separation(v); Pvector ali = Alignment(v); Pvector coh = Cohesion(v); // Arbitrarily weight these forces sep.mulScalar(SepW); ali.mulScalar(AliW); // Might need to alter weights for different characteristics coh.mulScalar(CohW); // Add the force vectors to acceleration applyForce(sep); applyForce(ali); applyForce(coh); }