From 63618620505b25137b33540d3d5aa03471d1892d Mon Sep 17 00:00:00 2001 From: Yves Chevallier Date: Tue, 13 Dec 2022 20:48:05 +0100 Subject: [PATCH 1/3] Update Makefile + fixes --- .clang-format | 4 ++++ .gitignore | 3 +++ Boids.cpp | 28 ++++++++++------------------ Makefile | 24 ++++++++++++------------ main.cpp | 15 ++++++++------- 5 files changed, 37 insertions(+), 37 deletions(-) create mode 100644 .clang-format create mode 100644 .gitignore diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..b9f890d --- /dev/null +++ b/.clang-format @@ -0,0 +1,4 @@ +--- +BasedOnStyle: Google + +... \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3904415 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.o +build +sfml-app \ No newline at end of file diff --git a/Boids.cpp b/Boids.cpp index 2ac2b2f..b86152a 100644 --- a/Boids.cpp +++ b/Boids.cpp @@ -1,18 +1,11 @@ #include "Boids.h" #include -#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(rand()) / (static_cast(RAND_MAX / (upper - lower))); -} - Boids::Boids() { texture.loadFromFile("arrow.png"); @@ -22,9 +15,8 @@ Boids::Boids() 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; + phi *= 2.0 * M_PI; velocity = Vector2f(sin(phi), cos(phi)); velocity = velocity.setMag(ReturnIntRandom(2, 4)); @@ -59,9 +51,9 @@ Vector2f Boids::align(Boids (&otherBoids)[S], int alignmentRadius) { int perceptionRadius = alignmentRadius; Vector2f steering = Vector2f(0.f, 0.f); - int total = 0; + size_t total = 0; - for (int i = 0; i < sizeof(otherBoids) / sizeof(otherBoids[0]); i++) + for (size_t i = 0; i < sizeof(otherBoids) / sizeof(otherBoids[0]); i++) { auto distance = position.dist(otherBoids[i].position); if (*this != otherBoids[i] && distance < perceptionRadius) @@ -87,8 +79,8 @@ 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++) + size_t total = 0; + for (size_t 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)) @@ -116,8 +108,8 @@ Vector2f Boids::collision(std::vector &shape) int perceptionRadius = 50; Vector2f steering = Vector2f(0.f, 0.f); - int total = 0; - for (int i = 0; i < shape.size(); i++) + size_t total = 0; + for (size_t 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)) @@ -145,8 +137,8 @@ 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++) + size_t total = 0; + for (size_t i = 0; i < sizeof(otherBoids) / sizeof(otherBoids[0]); i++) { auto distance = position.dist(otherBoids[i].position); if (*this != otherBoids[i] && distance < perceptionRadius) @@ -188,7 +180,7 @@ void Boids::update() acceleration = acceleration.mult(0); float angle = atan2(velocity.y, velocity.x); - angle = angle * (180 / PI) - 90; + angle = angle * (180 / M_PI) - 90; angle = (velocity.x < 0.0f || velocity.y < 0.0f) ? angle - 180 : angle + 180; sprite.setRotation(angle); diff --git a/Makefile b/Makefile index 7bc6d54..b3321a2 100755 --- a/Makefile +++ b/Makefile @@ -1,17 +1,17 @@ -all: sfml-app - ./sfml-app +EXEC = sfml-app +CC = g++ +CFLAGS = -std=c++17 -c -Wall +LDFLAGS = -std=c++17 -o $(EXEC) -ltgui -lsfml-graphics -lsfml-window -lsfml-audio -lsfml-system +SRCS = Vector2.cpp Boids.cpp main.cpp +OBJS = $(SRCS:.cpp=.o) -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 +all: $(EXEC) -Vector2.o : Vector2.cpp Vector2.h; - g++ -std=c++17 -c Vector2.cpp +$(EXEC): $(OBJS) + $(CC) $^ $(LDFLAGS) -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) +%.o: %.cpp + $(CC) $(CFLAGS) $< -o $@ clean: - rm -rf *o sfml-app + $(RM) -rf *o $(EXEC) diff --git a/main.cpp b/main.cpp index 02a3c07..73725f0 100644 --- a/main.cpp +++ b/main.cpp @@ -1,5 +1,6 @@ -#include "SFML/Graphics.hpp" -#include "TGUI/TGUI.hpp" +#include +#include +#include #include "Boids.h" #include @@ -100,7 +101,7 @@ int main() { case sf::Mouse::Left: { - if (resetButton->mouseOnWidget((sf::Vector2f)sf::Mouse::getPosition(window))) + if (resetButton->isMouseOnWidget((sf::Vector2f)sf::Mouse::getPosition(window))) { buttonPressed = true; } @@ -108,15 +109,15 @@ int main() { mouseDraw = true; } - if (alignmentSlider->mouseOnWidget(sf::Vector2f(event.mouseButton.x, event.mouseButton.y))) + if (alignmentSlider->isMouseOnWidget(sf::Vector2f(event.mouseButton.x, event.mouseButton.y))) { alignmentSliderMoved = true; } - if (cohesionSlider->mouseOnWidget(sf::Vector2f(event.mouseButton.x, event.mouseButton.y))) + if (cohesionSlider->isMouseOnWidget(sf::Vector2f(event.mouseButton.x, event.mouseButton.y))) { cohesionSliderMoved = true; } - if (separationSlider->mouseOnWidget(sf::Vector2f(event.mouseButton.x, event.mouseButton.y))) + if (separationSlider->isMouseOnWidget(sf::Vector2f(event.mouseButton.x, event.mouseButton.y))) { separationSliderMoved = true; } @@ -162,7 +163,7 @@ int main() separationSlider->setValue(sf::Mouse::getPosition(window).x / 2 - separationSlider->getPosition().x / 2); } - if (resetButton->mouseOnWidget((sf::Vector2f)sf::Mouse::getPosition(window))) + if (resetButton->isMouseOnWidget((sf::Vector2f)sf::Mouse::getPosition(window))) { resetButtonRenderer->setTextColor(tgui::Color(255, 0, 255)); } From b891deca8506f97e7f2868dec5bd8eab4bbcf5db Mon Sep 17 00:00:00 2001 From: Yves Chevallier Date: Tue, 13 Dec 2022 21:05:40 +0100 Subject: [PATCH 2/3] Add CMakeLists.txt and refactoring --- CMakeLists.txt | 23 ++++++ Makefile | 2 +- Boids.cpp => boids.cpp | 129 ++++++++++++------------------ Boids.h => boids.hpp | 27 +++---- main.cpp | 157 +++++++++++++++++-------------------- Vector2.cpp => vector2.cpp | 13 +-- Vector2.h => vector2.hpp | 1 - 7 files changed, 161 insertions(+), 191 deletions(-) create mode 100644 CMakeLists.txt rename Boids.cpp => boids.cpp (64%) rename Boids.h => boids.hpp (59%) rename Vector2.cpp => vector2.cpp (98%) rename Vector2.h => vector2.hpp (99%) diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..376d272 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,23 @@ +cmake_minimum_required(VERSION 2.8...3.13) +project(boids) + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -Wall") +set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_modules" ${CMAKE_MODULE_PATH}) + +find_package(SFML 2 REQUIRED system window graphics network audio) +find_package(TGUI 0.10 REQUIRED) + +if(NOT SFML_FOUND) + message(FATAL_ERROR "Could not find SFML") +endif() + +if(NOT TGUI_FOUND) + message(FATAL_ERROR "Could not find TGUI") +endif() +set(CMAKE_VERBOSE_MAKEFILE ON) +file(GLOB SRCS *.cpp ) + +add_executable(${PROJECT_NAME} ${SRCS}) +target_link_libraries(${PROJECT_NAME} tgui sfml-system sfml-window sfml-graphics sfml-network sfml-audio) +file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/arrow.png + DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) \ No newline at end of file diff --git a/Makefile b/Makefile index b3321a2..533ca38 100755 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ EXEC = sfml-app CC = g++ CFLAGS = -std=c++17 -c -Wall LDFLAGS = -std=c++17 -o $(EXEC) -ltgui -lsfml-graphics -lsfml-window -lsfml-audio -lsfml-system -SRCS = Vector2.cpp Boids.cpp main.cpp +SRCS = $(wildcard *.cpp) OBJS = $(SRCS:.cpp=.o) all: $(EXEC) diff --git a/Boids.cpp b/boids.cpp similarity index 64% rename from Boids.cpp rename to boids.cpp index b86152a..9567636 100644 --- a/Boids.cpp +++ b/boids.cpp @@ -1,16 +1,16 @@ -#include "Boids.h" +#include "boids.hpp" + #include -int ReturnIntRandom(int lower, int upper) -{ +int ReturnIntRandom(int lower, int upper) { return (rand() % (upper - lower + 1)) + lower; } -Boids::Boids() -{ +Boids::Boids() { texture.loadFromFile("arrow.png"); sprite.setTexture(texture); - sprite.setOrigin(sf::Vector2f(texture.getSize().x/2,texture.getSize().y/2)); + 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)); @@ -25,45 +25,33 @@ Boids::Boids() maxSpeed = 5.0f; } - -void Boids::AvoidEdges(const int& HEIGHT, const int& WIDTH) -{ - if (position.x > WIDTH) - { +void Boids::AvoidEdges(const int &HEIGHT, const int &WIDTH) { + if (position.x > WIDTH) { position.x = 0; - } - else if (position.x < 0) - { + } else if (position.x < 0) { position.x = WIDTH; } - if (position.y > HEIGHT) - { + if (position.y > HEIGHT) { position.y = 0; - } - else if (position.y < 0) - { + } else if (position.y < 0) { position.y = HEIGHT; } } template -Vector2f Boids::align(Boids (&otherBoids)[S], int alignmentRadius) -{ +Vector2f Boids::align(Boids (&otherBoids)[S], int alignmentRadius) { int perceptionRadius = alignmentRadius; Vector2f steering = Vector2f(0.f, 0.f); size_t total = 0; - for (size_t i = 0; i < sizeof(otherBoids) / sizeof(otherBoids[0]); i++) - { + for (size_t i = 0; i < sizeof(otherBoids) / sizeof(otherBoids[0]); i++) { auto distance = position.dist(otherBoids[i].position); - if (*this != otherBoids[i] && distance < perceptionRadius) - { + if (*this != otherBoids[i] && distance < perceptionRadius) { steering = steering.add(otherBoids[i].velocity); total++; } } - if (total > 0) - { + if (total > 0) { steering = steering.divide(total); steering = steering.setMag(maxSpeed); steering = steering.sub(velocity); @@ -72,29 +60,23 @@ Vector2f Boids::align(Boids (&otherBoids)[S], int alignmentRadius) return steering; } - template -Vector2f Boids::separation(Boids (&otherBoids)[S], int separationRadius) -{ +Vector2f Boids::separation(Boids (&otherBoids)[S], int separationRadius) { int perceptionRadius = separationRadius; Vector2f steering = Vector2f(0.f, 0.f); size_t total = 0; - for (size_t i = 0; i < sizeof(otherBoids) / sizeof(otherBoids[0]); i++) - { + for (size_t 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)) - { - + 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)); + if (distance < 1.0f) diff = diff.mult(1 / (distance * distance)); steering = steering.add(diff); total++; } } - if (total > 0) - { + if (total > 0) { steering = steering.divide(total); steering = steering.setMag(maxSpeed); steering = steering.sub(velocity); @@ -103,27 +85,23 @@ Vector2f Boids::separation(Boids (&otherBoids)[S], int separationRadius) return steering; } -Vector2f Boids::collision(std::vector &shape) -{ +Vector2f Boids::collision(std::vector &shape) { int perceptionRadius = 50; Vector2f steering = Vector2f(0.f, 0.f); size_t total = 0; - for (size_t 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)); + for (size_t 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) - { + if (total > 0) { steering = steering.divide(total); steering = steering.setMag(maxSpeed); steering = steering.sub(velocity); @@ -133,22 +111,18 @@ Vector2f Boids::collision(std::vector &shape) } template -Vector2f Boids::cohesion(Boids (&otherBoids)[S], int cohesionRadius) -{ +Vector2f Boids::cohesion(Boids (&otherBoids)[S], int cohesionRadius) { int perceptionRadius = cohesionRadius; Vector2f steering = Vector2f(0.f, 0.f); size_t total = 0; - for (size_t i = 0; i < sizeof(otherBoids) / sizeof(otherBoids[0]); i++) - { + for (size_t i = 0; i < sizeof(otherBoids) / sizeof(otherBoids[0]); i++) { auto distance = position.dist(otherBoids[i].position); - if (*this != otherBoids[i] && distance < perceptionRadius) - { + if (*this != otherBoids[i] && distance < perceptionRadius) { steering = steering.add(otherBoids[i].position); total++; } } - if (total > 0) - { + if (total > 0) { steering = steering.divide(total); steering = steering.sub(position); steering = steering.setMag(maxSpeed); @@ -158,9 +132,10 @@ Vector2f Boids::cohesion(Boids (&otherBoids)[S], int cohesionRadius) return steering; } -template < std::size_t S> -void Boids::flock(Boids (&otherBoids)[S], std::vector &shape, int alignmentRadius, int cohesionRadius, int separationRadius) -{ +template +void Boids::flock(Boids (&otherBoids)[S], std::vector &shape, + int alignmentRadius, int cohesionRadius, + int separationRadius) { Vector2f alignment = align(otherBoids, alignmentRadius); Vector2f cohes = cohesion(otherBoids, cohesionRadius); Vector2f sep = separation(otherBoids, separationRadius); @@ -172,8 +147,7 @@ void Boids::flock(Boids (&otherBoids)[S], std::vector &shape, i acceleration = acceleration.add(col); } -void Boids::update() -{ +void Boids::update() { position = position.add(velocity); velocity = velocity.add(acceleration); velocity = velocity.limit(maxSpeed); @@ -187,21 +161,18 @@ void Boids::update() sprite.setPosition(position.ConverttoSF()); } -void Boids::draw(sf::RenderWindow &window) -{ - window.draw(sprite); -} - +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.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); -} +bool operator!=(const Boids &a, const Boids &b) { return !(a == b); } -template void Boids::flock(Boids (&otherBoids)[200], std::vector &shape, int alignmentRadius, int cohesionRadius, int separationRadius); +template void Boids::flock(Boids (&otherBoids)[200], + std::vector &shape, + int alignmentRadius, int cohesionRadius, + int separationRadius); diff --git a/Boids.h b/boids.hpp similarity index 59% rename from Boids.h rename to boids.hpp index 70e8a2f..4312331 100644 --- a/Boids.h +++ b/boids.hpp @@ -1,9 +1,7 @@ -#ifndef BOIDS_H -#define BOIDS_H -#include "Vector2.h" +#pragma once +#include "vector2.hpp" -class Boids -{ +class Boids { Vector2f position; Vector2f velocity; Vector2f acceleration; @@ -11,29 +9,28 @@ class Boids sf::Texture texture; sf::Sprite sprite; -public: + public: Boids(); - void AvoidEdges(const int& HEIGHT, const int& WIDTH); + void AvoidEdges(const int &HEIGHT, const int &WIDTH); - template < std::size_t S> + template Vector2f align(Boids (&otherBoids)[S], int alignmentRadius); - template < std::size_t S> + template Vector2f separation(Boids (&otherBoids)[S], int separationRadius); - template < std::size_t S> + template Vector2f cohesion(Boids (&otherBoids)[S], int cohesionRadius); - Vector2f collision(std::vector& shape); + Vector2f collision(std::vector &shape); template - void flock(Boids (&otherBoids)[S], std::vector &shape, int alignmentRadius, int aohesionRadius, int separationRadius); + void flock(Boids (&otherBoids)[S], std::vector &shape, + int alignmentRadius, int aohesionRadius, int separationRadius); void update(); - void draw(sf::RenderWindow& window); + 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 diff --git a/main.cpp b/main.cpp index 73725f0..6243bbd 100644 --- a/main.cpp +++ b/main.cpp @@ -1,15 +1,14 @@ +#include "boids.hpp" + #include -#include #include -#include "Boids.h" +#include #include #define WIDTH 900 #define HEIGHT 600 - -int main() -{ +int main() { srand(time(0)); sf::RenderWindow window(sf::VideoMode(WIDTH, HEIGHT), "BOIDS"); window.setFramerateLimit(30); @@ -42,7 +41,9 @@ int main() auto alignmentText = tgui::Label::create(); alignmentText->setSize(70, 40); - alignmentText->setPosition(alignmentSlider->getPosition().x + alignmentSlider->getSize().x + 10, alignmentSlider->getPosition().y); + alignmentText->setPosition( + alignmentSlider->getPosition().x + alignmentSlider->getSize().x + 10, + alignmentSlider->getPosition().y); alignmentText->setText(std::to_string((int)alignmentSlider->getValue())); alignmentText->setTextSize(20); @@ -52,14 +53,18 @@ int main() auto cohesionText = tgui::Label::create(); cohesionText->setSize(70, 40); - cohesionText->setPosition(cohesionSlider->getPosition().x + cohesionSlider->getSize().x + 10, cohesionSlider->getPosition().y); + cohesionText->setPosition( + cohesionSlider->getPosition().x + cohesionSlider->getSize().x + 10, + cohesionSlider->getPosition().y); cohesionText->setText(std::to_string((int)cohesionSlider->getValue())); cohesionText->setTextSize(20); gui.add(cohesionText); auto separationText = tgui::Label::create(); separationText->setSize(70, 40); - separationText->setPosition(separationSlider->getPosition().x + separationSlider->getSize().x + 10, separationSlider->getPosition().y); + separationText->setPosition( + separationSlider->getPosition().x + separationSlider->getSize().x + 10, + separationSlider->getPosition().y); separationText->setText(std::to_string((int)separationSlider->getValue())); separationText->setTextSize(20); gui.add(separationText); @@ -74,7 +79,6 @@ int main() resetButtonRenderer->setBackgroundColor(tgui::Color(0, 0, 0, 0)); gui.add(resetButton); - bool alignmentSliderMoved = false; bool cohesionSliderMoved = false; bool separationSliderMoved = false; @@ -84,94 +88,78 @@ int main() Boids boids[200]; std::vector vec; - while (window.isOpen()) - { + while (window.isOpen()) { sf::Event event; - while (window.pollEvent(event)) - { - - switch (event.type) - { - case sf::Event::Closed: - window.close(); - break; - case sf::Event::MouseButtonPressed: - { - switch (event.mouseButton.button) - { - case sf::Mouse::Left: - { - if (resetButton->isMouseOnWidget((sf::Vector2f)sf::Mouse::getPosition(window))) - { - buttonPressed = true; - } - if (sf::Mouse::getPosition(window).y < window.getSize().y - 50) - { - mouseDraw = true; - } - if (alignmentSlider->isMouseOnWidget(sf::Vector2f(event.mouseButton.x, event.mouseButton.y))) - { - alignmentSliderMoved = true; - } - if (cohesionSlider->isMouseOnWidget(sf::Vector2f(event.mouseButton.x, event.mouseButton.y))) - { - cohesionSliderMoved = true; + while (window.pollEvent(event)) { + switch (event.type) { + case sf::Event::Closed: + window.close(); + break; + case sf::Event::MouseButtonPressed: { + switch (event.mouseButton.button) { + case sf::Mouse::Left: { + if (resetButton->isMouseOnWidget( + (sf::Vector2f)sf::Mouse::getPosition(window))) { + buttonPressed = true; + } + if (sf::Mouse::getPosition(window).y < window.getSize().y - 50) { + mouseDraw = true; + } + if (alignmentSlider->isMouseOnWidget( + sf::Vector2f(event.mouseButton.x, event.mouseButton.y))) { + alignmentSliderMoved = true; + } + if (cohesionSlider->isMouseOnWidget( + sf::Vector2f(event.mouseButton.x, event.mouseButton.y))) { + cohesionSliderMoved = true; + } + if (separationSlider->isMouseOnWidget( + sf::Vector2f(event.mouseButton.x, event.mouseButton.y))) { + separationSliderMoved = true; + } + } break; } - if (separationSlider->isMouseOnWidget(sf::Vector2f(event.mouseButton.x, event.mouseButton.y))) - { - separationSliderMoved = true; - } - } - break; - } - break; - } - case sf::Event::MouseButtonReleased: - { - switch (event.mouseButton.button) - { - case sf::Mouse::Left: - { - mouseDraw = false; - alignmentSliderMoved = false; - cohesionSliderMoved = false; - separationSliderMoved = false; - buttonPressed = false; + break; } - break; + case sf::Event::MouseButtonReleased: { + switch (event.mouseButton.button) { + case sf::Mouse::Left: { + mouseDraw = false; + alignmentSliderMoved = false; + cohesionSliderMoved = false; + separationSliderMoved = false; + buttonPressed = false; + } break; + } + break; } - break; - } } - if (mouseDraw && event.type == sf::Event::MouseMoved) - { + if (mouseDraw && event.type == sf::Event::MouseMoved) { sf::CircleShape shape(3); shape.setPosition(sf::Vector2f(event.mouseMove.x, event.mouseMove.y)); vec.push_back(shape); } } - if (alignmentSliderMoved) - { - alignmentSlider->setValue(sf::Mouse::getPosition(window).x / 2 - alignmentSlider->getPosition().x / 2); + if (alignmentSliderMoved) { + alignmentSlider->setValue(sf::Mouse::getPosition(window).x / 2 - + alignmentSlider->getPosition().x / 2); } - if (cohesionSliderMoved) - { - cohesionSlider->setValue(sf::Mouse::getPosition(window).x / 2 - cohesionSlider->getPosition().x / 2); + if (cohesionSliderMoved) { + cohesionSlider->setValue(sf::Mouse::getPosition(window).x / 2 - + cohesionSlider->getPosition().x / 2); } - if (separationSliderMoved) - { - separationSlider->setValue(sf::Mouse::getPosition(window).x / 2 - separationSlider->getPosition().x / 2); + if (separationSliderMoved) { + separationSlider->setValue(sf::Mouse::getPosition(window).x / 2 - + separationSlider->getPosition().x / 2); } - if (resetButton->isMouseOnWidget((sf::Vector2f)sf::Mouse::getPosition(window))) - { + if (resetButton->isMouseOnWidget( + (sf::Vector2f)sf::Mouse::getPosition(window))) { resetButtonRenderer->setTextColor(tgui::Color(255, 0, 255)); - } - else + } else resetButtonRenderer->setTextColor(tgui::Color(255, 255, 255)); - if (buttonPressed) - { + if (buttonPressed) { vec.clear(); alignmentSlider->setValue(0); cohesionSlider->setValue(0); @@ -186,13 +174,12 @@ int main() separationText->setText(std::to_string((int)separationSlider->getValue())); window.clear(); - for (auto i : vec) - { + for (auto i : vec) { window.draw(i); } - for (auto &i : boids) - { - i.flock(boids, vec, alignmentSlider->getValue(), cohesionSlider->getValue(), separationSlider->getValue()); + for (auto &i : boids) { + i.flock(boids, vec, alignmentSlider->getValue(), + cohesionSlider->getValue(), separationSlider->getValue()); i.AvoidEdges(HEIGHT, WIDTH); i.update(); i.draw(window); diff --git a/Vector2.cpp b/vector2.cpp similarity index 98% rename from Vector2.cpp rename to vector2.cpp index ba8b1f4..64b7919 100644 --- a/Vector2.cpp +++ b/vector2.cpp @@ -1,5 +1,7 @@ -#include "Vector2.h" +#include "vector2.hpp" + #include + template Vector2::Vector2():x(0.0f),y(0.0f) { @@ -21,10 +23,6 @@ sf::Vector2 Vector2::ConverttoSF() return sf::Vector2(static_cast(x),static_cast(y)); } - - - - template Vector2 Vector2::add( Vector2 a) { @@ -79,10 +77,6 @@ Vector2 Vector2::limit(int n) return *this; } - - - - template Vector2 Vector2::operator+( const Vector2& Right ) { @@ -109,7 +103,6 @@ bool Vector2::operator!=(const Vector2 &obj) return !((x == obj.x) && (y == obj.y)); } - template bool Vector2::operator==(const Vector2 &obj) { diff --git a/Vector2.h b/vector2.hpp similarity index 99% rename from Vector2.h rename to vector2.hpp index a55f84a..8aad4f6 100644 --- a/Vector2.h +++ b/vector2.hpp @@ -24,7 +24,6 @@ explicit Vector2(const Vector2& vector); sf::Vector2 ConverttoSF(); - Vector2 add( Vector2); Vector2 sub( Vector2); Vector2 divide( int); From eedcead65191548e9d73988b1b191a0ab369a607 Mon Sep 17 00:00:00 2001 From: Yves Chevallier Date: Tue, 13 Dec 2022 22:18:58 +0100 Subject: [PATCH 3/3] Vector.hpp --- boids.cpp | 73 ++++++++++++-------------- boids.hpp | 5 +- main.cpp | 5 +- vector2.cpp | 114 ---------------------------------------- vector2.hpp | 148 +++++++++++++++++++++++++++++++++------------------- 5 files changed, 134 insertions(+), 211 deletions(-) delete mode 100644 vector2.cpp diff --git a/boids.cpp b/boids.cpp index 9567636..6037535 100644 --- a/boids.cpp +++ b/boids.cpp @@ -14,7 +14,7 @@ Boids::Boids() { sprite.setScale(0.02f, 0.02f); position = Vector2f(ReturnIntRandom(0, 800), ReturnIntRandom(0, 500)); - sprite.setPosition(position.ConverttoSF()); + sprite.setPosition(position.x, position.y); auto phi = rand() / (double)(RAND_MAX); phi *= 2.0 * M_PI; velocity = Vector2f(sin(phi), cos(phi)); @@ -45,16 +45,16 @@ Vector2f Boids::align(Boids (&otherBoids)[S], int alignmentRadius) { size_t total = 0; for (size_t i = 0; i < sizeof(otherBoids) / sizeof(otherBoids[0]); i++) { - auto distance = position.dist(otherBoids[i].position); + auto distance = position.distance(otherBoids[i].position); if (*this != otherBoids[i] && distance < perceptionRadius) { - steering = steering.add(otherBoids[i].velocity); + steering = steering + otherBoids[i].velocity; total++; } } if (total > 0) { - steering = steering.divide(total); + steering = steering / total; steering = steering.setMag(maxSpeed); - steering = steering.sub(velocity); + steering = steering - velocity; steering = steering.limit(maxForce); } return steering; @@ -67,19 +67,19 @@ Vector2f Boids::separation(Boids (&otherBoids)[S], int separationRadius) { size_t total = 0; for (size_t i = 0; i < sizeof(otherBoids) / sizeof(otherBoids[0]); i++) { - float distance = position.dist(otherBoids[i].position); + float distance = position.distance(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); + Vector2f diff = position - otherBoids[i].position; + if (distance < 1.0f) diff = diff * (1 / (distance * distance)); + steering = steering +diff; total++; } } if (total > 0) { - steering = steering.divide(total); + steering = steering / total; steering = steering.setMag(maxSpeed); - steering = steering.sub(velocity); + steering = steering - velocity; steering = steering.limit(maxForce); } return steering; @@ -91,20 +91,19 @@ Vector2f Boids::collision(std::vector &shape) { size_t total = 0; for (size_t i = 0; i < shape.size(); i++) { - float distance = position.dist( + float distance = position.distance( 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); + Vector2f diff = position - Vector2f(shape[i].getPosition().x, shape[i].getPosition().y); + if (distance < 1.0f) diff *= (1 / (distance * distance)); + steering = steering +diff; total++; } } if (total > 0) { - steering = steering.divide(total); + steering = steering / total; steering = steering.setMag(maxSpeed); - steering = steering.sub(velocity); + steering = steering - velocity; steering = steering.limit(maxForce); } return steering; @@ -116,17 +115,17 @@ Vector2f Boids::cohesion(Boids (&otherBoids)[S], int cohesionRadius) { Vector2f steering = Vector2f(0.f, 0.f); size_t total = 0; for (size_t i = 0; i < sizeof(otherBoids) / sizeof(otherBoids[0]); i++) { - auto distance = position.dist(otherBoids[i].position); + auto distance = position.distance(otherBoids[i].position); if (*this != otherBoids[i] && distance < perceptionRadius) { - steering = steering.add(otherBoids[i].position); + steering += otherBoids[i].position; total++; } } if (total > 0) { - steering = steering.divide(total); - steering = steering.sub(position); + steering /= total; + steering -= position; steering = steering.setMag(maxSpeed); - steering = steering.sub(velocity); + steering -= velocity; steering = steering.limit(maxForce); } return steering; @@ -136,38 +135,32 @@ template void Boids::flock(Boids (&otherBoids)[S], std::vector &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); + acceleration += align(otherBoids, alignmentRadius); + acceleration += cohesion(otherBoids, cohesionRadius); + acceleration += separation(otherBoids, separationRadius); + acceleration += collision(shape); } void Boids::update() { - position = position.add(velocity); - velocity = velocity.add(acceleration); + position += velocity; + velocity += acceleration; velocity = velocity.limit(maxSpeed); - acceleration = acceleration.mult(0); + acceleration *= 0; float angle = atan2(velocity.y, velocity.x); angle = angle * (180 / M_PI) - 90; angle = (velocity.x < 0.0f || velocity.y < 0.0f) ? angle - 180 : angle + 180; sprite.setRotation(angle); - sprite.setPosition(position.ConverttoSF()); + sprite.setPosition(position.x, position.y); } 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); + return a.position == b.position && + a.velocity == b.velocity && + a.acceleration == b.acceleration; } bool operator!=(const Boids &a, const Boids &b) { return !(a == b); } diff --git a/boids.hpp b/boids.hpp index 4312331..3583fab 100644 --- a/boids.hpp +++ b/boids.hpp @@ -1,6 +1,9 @@ #pragma once + #include "vector2.hpp" +#include + class Boids { Vector2f position; Vector2f velocity; @@ -26,7 +29,7 @@ class Boids { template void flock(Boids (&otherBoids)[S], std::vector &shape, - int alignmentRadius, int aohesionRadius, int separationRadius); + int alignmentRadius, int cohesionRadius, int separationRadius); void update(); void draw(sf::RenderWindow &window); diff --git a/main.cpp b/main.cpp index 6243bbd..8414083 100644 --- a/main.cpp +++ b/main.cpp @@ -11,8 +11,7 @@ int main() { srand(time(0)); sf::RenderWindow window(sf::VideoMode(WIDTH, HEIGHT), "BOIDS"); - window.setFramerateLimit(30); - + window.setFramerateLimit(60); tgui::Gui gui{window}; auto alignmentSlider = tgui::Slider::create(); @@ -173,7 +172,7 @@ int main() { cohesionText->setText(std::to_string((int)cohesionSlider->getValue())); separationText->setText(std::to_string((int)separationSlider->getValue())); - window.clear(); + window.clear(sf::Color(20, 30, 50)); for (auto i : vec) { window.draw(i); } diff --git a/vector2.cpp b/vector2.cpp deleted file mode 100644 index 64b7919..0000000 --- a/vector2.cpp +++ /dev/null @@ -1,114 +0,0 @@ -#include "vector2.hpp" - -#include - -template -Vector2::Vector2():x(0.0f),y(0.0f) -{ -} - -template -Vector2::Vector2(T x): x(x), y(x) -{ -} - -template -Vector2::Vector2(T x, T y): x(x),y(y) -{ -} - -template -sf::Vector2 Vector2::ConverttoSF() -{ - return sf::Vector2(static_cast(x),static_cast(y)); -} - -template -Vector2 Vector2::add( Vector2 a) -{ - return Vector2(this->x + a.x, this->y + a.y); -} - -template -Vector2 Vector2::sub( Vector2 a) -{ - return Vector2(this->x - a.x, this->y - a.y); -} - -template -Vector2 Vector2::divide( int n) -{ - return Vector2(this->x/n, this->y/n); -} - -template -Vector2 Vector2::mult( int n) -{ - return Vector2(this->x * n, this->y * n); -} - -template -float Vector2::dist( Vector2 a) -{ - T DiffX = this->x - a.x; - T DiffY = this->y - a.y; - - return sqrt(DiffX * DiffX + DiffY * DiffY); -} - -template -Vector2 Vector2::setMag(float NewMag) -{ - - auto mag = sqrt(this->x * this->x + this->y * this->y); - return Vector2((this->x * NewMag) / mag, (this->y * NewMag) / mag); -} - - -template -Vector2 Vector2::limit(int n) -{ - - auto mag = sqrt(this->x * this->x + this->y * this->y); - if(mag > n) - { - return Vector2((this->x * n) / mag, (this->y * n) / mag); - } - return *this; -} - -template -Vector2 Vector2::operator+( const Vector2& Right ) -{ - return Vector2(x + Right.x, y + Right.y); -} - -template -Vector2 Vector2::operator-( const Vector2& Right) -{ - return Vector2(x - Right.x, y - Right.y); -} - -template -Vector2& Vector2::operator=(const Vector2& Vector2Obj) -{ - x = Vector2Obj.x; - y = Vector2Obj.y; - return *this; -} - -template -bool Vector2::operator!=(const Vector2 &obj) -{ - return !((x == obj.x) && (y == obj.y)); -} - -template -bool Vector2::operator==(const Vector2 &obj) -{ - return ((x == obj.x) && (y == obj.y)); -} - -template class Vector2; -template class Vector2; -template class Vector2; diff --git a/vector2.hpp b/vector2.hpp index 8aad4f6..9a81910 100644 --- a/vector2.hpp +++ b/vector2.hpp @@ -1,56 +1,98 @@ -#ifndef VECTOR2_H -#define VECTOR2_H -#include -#include "SFML/Graphics.hpp" - - -template -class Vector2 final -{ -public: - T x; - T y; - -Vector2(); - -Vector2(T x); - -Vector2(T x, T y); - -template -explicit Vector2(const Vector2& vector); - - -sf::Vector2 ConverttoSF(); - - -Vector2 add( Vector2); -Vector2 sub( Vector2); -Vector2 divide( int); -Vector2 mult( int); -float dist( Vector2); -Vector2 setMag( float); -Vector2 limit( int); - - - -Vector2& operator=(const Vector2& Vector2Obj); - -Vector2 operator+( const Vector2& Right ); - -Vector2 operator-( const Vector2& Right); - - -bool operator!=(const Vector2 &obj); - -bool operator==(const Vector2 &obj); +#pragma once +#include +#include + + +template +class Vector2 { + public: + using value_type = T; + using class_type = Vector2; + value_type x; + value_type y; + + Vector2(T value) : x(value), y(value) {} + Vector2(T x = 0, T y = 0) : x(x), y(y) {} + Vector2(const class_type& vector) : x(vector.x), y(vector.y) {} + + auto operator+(const class_type& right) const { + return class_type(x + right.x, y + right.y); + } + auto operator-(const class_type& right) const { + return class_type(x - right.x, y - right.y); + } + auto operator+(T n) const { return class_type(x + n, y + n); } + auto operator*(T n) { return class_type(x * n, y * n); } + auto operator/(T n) { return class_type(x / n, y / n); } + + auto operator==(const class_type& right) const { + return x == right.x && y == right.y; + } + auto operator!=(const class_type& right) const { + return x != right.x || y != right.y; + } + auto operator=(const class_type& right) { + x = right.x; + y = right.y; + return *this; + } + + auto operator*= (const T &n) { + x *= n; + y *= n; + return *this; + } + auto operator/= (const T &n) { + x /= n; + y /= n; + return *this; + } + auto operator+= (const T &n) { + x += n; + y += n; + return *this; + } + auto operator-= (const T &n) { + x -= n; + y -= n; + return *this; + } + auto operator-= (const class_type &n) { + x -= n.x; + y -= n.y; + return *this; + } + auto operator+= (const class_type &n) { + x += n.x; + y += n.y; + return *this; + } + + auto distance(const class_type& right) { + auto dx = x - right.x; + auto dy = y - right.y; + return sqrt(dx * dx + dy * dy); + } + + auto magnitude() const { return sqrt(x * x + y * y); }; + auto normalize() const { + const auto mag = magnitude(); + return class_type(x / mag, y / mag); + } + auto setMag(float magnitude) { + const auto mag = this->magnitude(); + return class_type((x * magnitude) / mag, (y * magnitude) / mag); + } + auto limit(float max) { + if (magnitude() > max) { + return setMag(max); + } + return *this; + } + auto heading() const { return atan2(y, x); } }; -typedef Vector2 Vector2i; -typedef Vector2 Vector2u; -typedef Vector2 Vector2f; - - - -#endif /* VECTOR2_H */ +using Vector2f = Vector2; +using Vector2i = Vector2; +using Vector2u = Vector2;