#include <iostream>
#include <vector>
#include <cmath>
#include <cstdlib>
#include <ctime>
// Constants
const float WIDTH = 800.0f;
const float HEIGHT = 600.0f;
const int BOID_COUNT = 100;
const float MAX_SPEED = 5.0f;
const float MAX_FORCE = 0.1f;
const float NEIGHBOR_RADIUS = 50.0f;
const float SEPARATION_RADIUS = 20.0f;
// Vector2 class for 2D vector operations
class Vector2 {
public:
float x, y;
Vector2(float x = 0, float y = 0) : x(x), y(y) {}
Vector2 operator+(const Vector2& v) const {
return Vector2(x + v.x, y + v.y);
}
Vector2 operator-(const Vector2& v) const {
return Vector2(x - v.x, y - v.y);
}
Vector2 operator*(float scalar) const {
return Vector2(x * scalar, y * scalar);
}
Vector2& operator+=(const Vector2& v) {
x += v.x;
y += v.y;
return *this;
}
Vector2& operator-=(const Vector2& v) {
x -= v.x;
y -= v.y;
return *this;
}
Vector2& operator*=(float scalar) {
x *= scalar;
y *= scalar;
return *this;
}
float length() const {
return std::sqrt(x * x + y * y);
}
Vector2 normalize() const {
float len = length();
if (len > 0) {
return *this * (1.0f / len);
}
return *this;
}
};
// Boid class
class Boid {
public:
Vector2 position;
Vector2 velocity;
Vector2 acceleration;
Boid(float x, float y) : position(x, y), velocity(rand() % 2 - 1, rand() % 2 - 1), acceleration(0, 0) {}
void update() {
velocity += acceleration;
if (velocity.length() > MAX_SPEED) {
velocity = velocity.normalize() * MAX_SPEED;
}
position += velocity;
acceleration *= 0;
wrapAround();
}
void applyForce(const Vector2& force) {
acceleration += force;
}
void wrapAround() {
if (position.x < 0) position.x += WIDTH;
if (position.x > WIDTH) position.x -= WIDTH;
if (position.y < 0) position.y += HEIGHT;
if (position.y > HEIGHT) position.y -= HEIGHT;
}
};
// Main simulation function
void simulate(std::vector<Boid>& boids) {
for (auto& boid : boids) {
Vector2 alignment(0, 0);
Vector2 cohesion(0, 0);
Vector2 separation(0, 0);
int neighborCount = 0;
for (const auto& other : boids) {
if (&boid == &other) continue;
Vector2 diff = boid.position - other.position;
float distance = diff.length();
if (distance < NEIGHBOR_RADIUS) {
alignment += other.velocity;
cohesion += other.position;
if (distance < SEPARATION_RADIUS) {
separation += diff.normalize() / distance;
}
neighborCount++;
}
}
if (neighborCount > 0) {
alignment = alignment * (1.0f / neighborCount);
cohesion = (cohesion * (1.0f / neighborCount) - boid.position).normalize();
separation = separation.normalize();
}
alignment = alignment.normalize() * MAX_SPEED - boid.velocity;
cohesion = cohesion.normalize() * MAX_SPEED - boid.velocity;
separation = separation.normalize() * MAX_SPEED - boid.velocity;
alignment *= 1.0f;
cohesion *= 1.0f;
separation *= 1.5f;
boid.applyForce(alignment);
boid.applyForce(cohesion);
boid.applyForce(separation);
boid.update();
}
}
int main() {
srand(static_cast<unsigned>(time(0)));
std::vector<Boid> boids;
for (int i = 0; i < BOID_COUNT; ++i) {
boids.emplace_back(rand() % static_cast<int>(WIDTH), rand() % static_cast<int>(HEIGHT));
}
while (true) {
simulate(boids);
// Here you would typically add rendering code to visualize the boids
}
return 0;
}