Skip to content

Commit

Permalink
Added classes
Browse files Browse the repository at this point in the history
  • Loading branch information
abhayMore committed Apr 19, 2021
1 parent d0c2b29 commit 6115b7d
Show file tree
Hide file tree
Showing 4 changed files with 272 additions and 230 deletions.
215 changes: 215 additions & 0 deletions Boids.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
#include "Boids.h"
#include <cmath>

#define PI 3.14159265

int ReturnIntRandom(int lower, int upper)
{
return (rand() % (upper - lower + 1)) + lower;
}

float ReturnFloatRandom(float lower, float upper)
{
float r3 = lower + static_cast<float>(rand()) / (static_cast<float>(RAND_MAX / (upper - lower)));
}

Boids::Boids()
{
texture.loadFromFile("arrow.png");
sprite.setTexture(texture);
sprite.setOrigin(sf::Vector2f(texture.getSize().x/2,texture.getSize().y/2));

sprite.setScale(0.02f, 0.02f);
position = Vector2f(ReturnIntRandom(0, 800), ReturnIntRandom(0, 500));
sprite.setPosition(position.ConverttoSF());
auto pi = 4.0 * atan(1.0);
auto phi = rand() / (double)(RAND_MAX);
phi *= 2.0 * pi;
velocity = Vector2f(sin(phi), cos(phi));

velocity = velocity.setMag(ReturnIntRandom(2, 4));
acceleration = Vector2f(0.0f, 0.0f);
maxForce = 1.5f;
maxSpeed = 5.0f;
}


void Boids::AvoidEdges(const int& HEIGHT, const int& WIDTH)
{
if (position.x > WIDTH)
{
position.x = 0;
}
else if (position.x < 0)
{
position.x = WIDTH;
}
if (position.y > HEIGHT)
{
position.y = 0;
}
else if (position.y < 0)
{
position.y = HEIGHT;
}
}

template <typename std::size_t S>
Vector2f Boids::align(Boids (&otherBoids)[S], int alignmentRadius)
{
int perceptionRadius = alignmentRadius;
Vector2f steering = Vector2f(0.f, 0.f);
int total = 0;

for (int i = 0; i < sizeof(otherBoids) / sizeof(otherBoids[0]); i++)
{
auto distance = position.dist(otherBoids[i].position);
if (*this != otherBoids[i] && distance < perceptionRadius)
{
steering = steering.add(otherBoids[i].velocity);
total++;
}
}
if (total > 0)
{
steering = steering.divide(total);
steering = steering.setMag(maxSpeed);
steering = steering.sub(velocity);
steering = steering.limit(maxForce);
}
return steering;
}


template <typename std::size_t S>
Vector2f Boids::separation(Boids (&otherBoids)[S], int separationRadius)
{
int perceptionRadius = separationRadius;
Vector2f steering = Vector2f(0.f, 0.f);

int total = 0;
for (int i = 0; i < sizeof(otherBoids) / sizeof(otherBoids[0]); i++)
{
float distance = position.dist(otherBoids[i].position);
if ((*this != otherBoids[i]) && (distance < perceptionRadius) && (distance > 0.0f))
{

Vector2f diff = position.sub(otherBoids[i].position);
if (distance < 1.0f)
diff = diff.mult(1 / (distance * distance));
steering = steering.add(diff);
total++;
}
}
if (total > 0)
{
steering = steering.divide(total);
steering = steering.setMag(maxSpeed);
steering = steering.sub(velocity);
steering = steering.limit(maxForce);
}
return steering;
}

Vector2f Boids::collision(std::vector<sf::CircleShape> &shape)
{
int perceptionRadius = 50;
Vector2f steering = Vector2f(0.f, 0.f);

int total = 0;
for (int i = 0; i < shape.size(); i++)
{
float distance = position.dist(Vector2f(shape[i].getPosition().x, shape[i].getPosition().y));
if ((distance < perceptionRadius) && (distance > 0.0f))
{

Vector2f diff = position.sub(Vector2f(shape[i].getPosition().x, shape[i].getPosition().y));
if (distance < 1.0f)
diff = diff.mult(1 / (distance * distance));
steering = steering.add(diff);
total++;
}
}
if (total > 0)
{
steering = steering.divide(total);
steering = steering.setMag(maxSpeed);
steering = steering.sub(velocity);
steering = steering.limit(maxForce);
}
return steering;
}

template <typename std::size_t S>
Vector2f Boids::cohesion(Boids (&otherBoids)[S], int cohesionRadius)
{
int perceptionRadius = cohesionRadius;
Vector2f steering = Vector2f(0.f, 0.f);
int total = 0;
for (int i = 0; i < sizeof(otherBoids) / sizeof(otherBoids[0]); i++)
{
auto distance = position.dist(otherBoids[i].position);
if (*this != otherBoids[i] && distance < perceptionRadius)
{
steering = steering.add(otherBoids[i].position);
total++;
}
}
if (total > 0)
{
steering = steering.divide(total);
steering = steering.sub(position);
steering = steering.setMag(maxSpeed);
steering = steering.sub(velocity);
steering = steering.limit(maxForce);
}
return steering;
}

template < std::size_t S>
void Boids::flock(Boids (&otherBoids)[S], std::vector<sf::CircleShape> &shape, int alignmentRadius, int cohesionRadius, int separationRadius)
{
Vector2f alignment = align(otherBoids, alignmentRadius);
Vector2f cohes = cohesion(otherBoids, cohesionRadius);
Vector2f sep = separation(otherBoids, separationRadius);
Vector2f col = collision(shape);

acceleration = acceleration.add(alignment);
acceleration = acceleration.add(cohes);
acceleration = acceleration.add(sep);
acceleration = acceleration.add(col);
}

void Boids::update()
{
position = position.add(velocity);
velocity = velocity.add(acceleration);
velocity = velocity.limit(maxSpeed);
acceleration = acceleration.mult(0);

float angle = atan2(velocity.y, velocity.x);
angle = angle * (180 / PI) - 90;
angle = (velocity.x < 0.0f || velocity.y < 0.0f) ? angle - 180 : angle + 180;

sprite.setRotation(angle);
sprite.setPosition(position.ConverttoSF());
}

void Boids::draw(sf::RenderWindow &window)
{
window.draw(sprite);
}



bool operator==(const Boids &a, const Boids &b)
{
return (a.position.x == b.position.x) && (a.position.y == b.position.y) && (a.velocity.x == b.velocity.x) && (a.velocity.y == b.velocity.y) && (a.acceleration.x == b.acceleration.x) && (a.acceleration.y == b.acceleration.y);
}

bool operator!=(const Boids &a, const Boids &b)
{
return !(a == b);
}

template void Boids::flock(Boids (&otherBoids)[200], std::vector<sf::CircleShape> &shape, int alignmentRadius, int cohesionRadius, int separationRadius);
39 changes: 39 additions & 0 deletions Boids.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#ifndef BOIDS_H
#define BOIDS_H
#include "Vector2.h"

class Boids
{
Vector2f position;
Vector2f velocity;
Vector2f acceleration;
float maxSpeed, maxForce;
sf::Texture texture;
sf::Sprite sprite;

public:
Boids();
void AvoidEdges(const int& HEIGHT, const int& WIDTH);

template < std::size_t S>
Vector2f align(Boids (&otherBoids)[S], int alignmentRadius);

template < std::size_t S>
Vector2f separation(Boids (&otherBoids)[S], int separationRadius);

template < std::size_t S>
Vector2f cohesion(Boids (&otherBoids)[S], int cohesionRadius);

Vector2f collision(std::vector<sf::CircleShape>& shape);

template <std::size_t S>
void flock(Boids (&otherBoids)[S], std::vector<sf::CircleShape> &shape, int alignmentRadius, int aohesionRadius, int separationRadius);

void update();
void draw(sf::RenderWindow& window);

friend bool operator==(const Boids &a, const Boids &b);
friend bool operator!=(const Boids &a, const Boids &b);
};

#endif //BOIDS_H
11 changes: 7 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
all: sfml-app
./sfml-app

sfml-app: $(F2) Vector2.o
g++ -std=c++17 $(F2) Vector2.o -o sfml-app -ltgui -lsfml-graphics -lsfml-window -lsfml-audio -lsfml-system
sfml-app: $(F2) Vector2.o Boids.o
g++ -std=c++17 $(F2) Vector2.o Boids.o -o sfml-app -ltgui -lsfml-graphics -lsfml-window -lsfml-audio -lsfml-system

Vector2.o : Vector2.cpp Vector2.h;
g++ -std=c++17 -c Vector2.cpp

$(F2) : Vector2.h $(F1)
g++ -c $(F1)
Boids.o : Boids.cpp Boids.h
g++ -std=c++17 -c Boids.cpp

$(F2) : Vector2.h $(F1) Boids.h
g++ -std=c++17 -c $(F1)

clean:
rm -rf *o sfml-app
Loading

0 comments on commit 6115b7d

Please sign in to comment.