diff --git a/seminar09_libraries/01_balls/balls.cpp b/seminar09_libraries/01_balls/balls.cpp new file mode 100644 index 0000000..17eb832 --- /dev/null +++ b/seminar09_libraries/01_balls/balls.cpp @@ -0,0 +1,94 @@ +#include +#include +#include +#include +#include + +using namespace std; + + +struct Ball +{ + float radius; + sf::Vector2f position; + sf::Vector2f velocity; +}; + + +int main() +{ + srand(time(0)); + + const int width = 1000; + const int height = 800; + const int n_balls = 100; + + // Шаг по времени + const float delta_t = 0.1; + + // Создаём экземпляр класса окно + sf::RenderWindow window(sf::VideoMode(width, height), "My window"); + // Задаём максимальное количество кадров в секунду + window.setFramerateLimit(60); + + // Так как sf::CircleShape занимает много памяти, создаём всего 1 экземпляр + sf::CircleShape circle(50.0f); + circle.setFillColor({200, 216, 200}); + + std::vector balls; + balls.resize(n_balls); + for (int i = 0; i < n_balls; i++) + { + balls[i].radius = 4 + rand() % 8; + balls[i].position = {(float)(rand() % width), (float)(rand() % height)}; + balls[i].velocity = {(float)(rand() % 100 - 50), (float)(rand() % 100 - 50)}; + } + + while (window.isOpen()) + { + sf::Event event; + while (window.pollEvent(event)) + { + // В данном примере проверяем окно на закрытие + if (event.type == sf::Event::Closed) + window.close(); + } + + // очистить скрытый холст черным цветом + window.clear(sf::Color::Black); + + for (int i = 0; i < n_balls; i++) + { + balls[i].position += balls[i].velocity * delta_t; + + /* + if (balls[i].position.x < 0) + balls[i].position.x += width; + if (balls[i].position.x > width) + balls[i].position.x -= width; + + if (balls[i].position.y < 0) + balls[i].position.y += height; + if (balls[i].position.y > height) + balls[i].position.y -= height; + */ + + // Используем 1 sf::CircleShape, чтобы нарисовать все шары + circle.setRadius(balls[i].radius); + // setOrigin - задаёт центр объекта + // По умолчанию центр - в левом верхнем угле объекта + // Строка ниже устанавливает центр в центре шарика + // В дальнейшем функция, setPosition устанавливает положение шарика так, + // чтобы его центр был в точке balls[i].position + circle.setOrigin(balls[i].radius, balls[i].radius); + circle.setPosition(balls[i].position); + + window.draw(circle); + } + + // отображаем содержимое скрытого холста на экран + window.display(); + } + + return 0; +} \ No newline at end of file diff --git a/seminar09_libraries/02_thor/Makefile b/seminar09_libraries/02_thor/Makefile new file mode 100644 index 0000000..8fd709a --- /dev/null +++ b/seminar09_libraries/02_thor/Makefile @@ -0,0 +1,2 @@ +balls: + g++ ./balls.cpp -std=c++11 -o balls.exe -I../../../3rdparty/SFML-2.5.1/include -L ../../../3rdparty/SFML-2.5.1/lib/ -lsfml-graphics -lsfml-window -lsfml-system diff --git a/seminar09_libraries/02_thor/balls.cpp b/seminar09_libraries/02_thor/balls.cpp new file mode 100644 index 0000000..3ce2b4e --- /dev/null +++ b/seminar09_libraries/02_thor/balls.cpp @@ -0,0 +1,93 @@ +#include +#include +#include +#include +#include + +using namespace std; + + +struct Ball +{ + float radius; + sf::Vector2f position; + sf::Vector2f velocity; +}; + + +int main() +{ + srand(time(0)); + + const int width = 1000; + const int height = 800; + const int n_balls = 100; + // Шаг по времени + const float delta_t = 0.1; + + // Создаём экземпляр класса окно + sf::RenderWindow window(sf::VideoMode(width, height), "My window"); + // Задаём максимальное количество кадров в секунду + window.setFramerateLimit(60); + + // Так как sf::CircleShape занимает много памяти, создаём всего 1 экземпляр + sf::CircleShape circle(50.0f); + circle.setFillColor({200, 216, 200}); + + std::vector balls; + balls.resize(n_balls); + for (int i = 0; i < n_balls; i++) + { + balls[i].radius = 4 + rand() % 8; + balls[i].position = {(float)(rand() % width), (float)(rand() % height)}; + balls[i].velocity = {(float)(rand() % 100 - 50), (float)(rand() % 100 - 50)}; + } + + while (window.isOpen()) + { + sf::Event event; + while (window.pollEvent(event)) + { + // В данном примере проверяем окно на закрытие + if (event.type == sf::Event::Closed) + window.close(); + } + + // очистить скрытый холст черным цветом + window.clear(sf::Color::Black); + + for (int i = 0; i < n_balls; i++) + { + balls[i].position += balls[i].velocity * delta_t; + + + if (balls[i].position.x < 0) + balls[i].position.x += width; + if (balls[i].position.x > width) + balls[i].position.x -= width; + + if (balls[i].position.y < 0) + balls[i].position.y += height; + if (balls[i].position.y > height) + balls[i].position.y -= height; + + + // Используем 1 sf::CircleShape, чтобы нарисовать все шары + circle.setRadius(balls[i].radius); + // setOrigin - задаёт центр объекта + // По умолчанию центр - в левом верхнем угле объекта + // Строка ниже устанавливает центр в центре шарика + // В дальнейшем функция, setPosition устанавливает положение шарика так, + // чтобы его центр был в точке balls[i].position + circle.setOrigin(balls[i].radius, balls[i].radius); + circle.setPosition(balls[i].position); + + window.draw(circle); + } + + // отображаем содержимое скрытого холста на экран + window.display(); + } + + return 0; +} diff --git a/seminar09_libraries/03_walls/balls.cpp b/seminar09_libraries/03_walls/balls.cpp new file mode 100644 index 0000000..ac923e9 --- /dev/null +++ b/seminar09_libraries/03_walls/balls.cpp @@ -0,0 +1,90 @@ +#include +#include +#include +#include +#include + +using namespace std; + + +struct Ball +{ + float radius; + sf::Vector2f position; + sf::Vector2f velocity; +}; + + +int main() +{ + srand(time(0)); + + const int width = 1000; + const int height = 800; + const int n_balls = 100; + + // Шаг по времени + const float delta_t = 0.1; /// + + // Создаём экземпляр класса окно + sf::RenderWindow window(sf::VideoMode(width, height), "My window"); + // Задаём максимальное количество кадров в секунду + window.setFramerateLimit(60); + + // Так как sf::CircleShape занимает много памяти, создаём всего 1 экземпляр + sf::CircleShape circle(50.0f); + circle.setFillColor({200, 216, 200}); + + std::vector balls; + balls.resize(n_balls); + for (int i = 0; i < n_balls; i++) + { + balls[i].radius = 4 + rand() % 8; + balls[i].position = {(float)(rand() % width), (float)(rand() % height)}; + balls[i].velocity = {(float)(rand() % 100 - 50), (float)(rand() % 100 - 50)}; + } + + while (window.isOpen()) + { + sf::Event event; + while (window.pollEvent(event)) + { + // В данном примере проверяем окно на закрытие + if (event.type == sf::Event::Closed) + window.close(); + } + + // очистить скрытый холст черным цветом + window.clear(sf::Color::Black); + + for (int i = 0; i < n_balls; i++) + { + balls[i].position += balls[i].velocity * delta_t; + + + if ((balls[i].position.x < 0) || (balls[i].position.x > width)) + balls[i].velocity.x = -balls[i].velocity.x; + + if ((balls[i].position.y < 0) || (balls[i].position.y > height)) + balls[i].velocity.y = -balls[i].velocity.y; + + + // Используем 1 sf::CircleShape, чтобы нарисовать все шары + circle.setRadius(balls[i].radius); + // setOrigin - задаёт центр объекта + // По умолчанию центр - в левом верхнем угле объекта + // Строка ниже устанавливает центр в центре шарика + // В дальнейшем функция, setPosition устанавливает положение шарика так, + // чтобы его центр был в точке balls[i].position + circle.setOrigin(balls[i].radius, balls[i].radius); + circle.setPosition(balls[i].position); + + window.draw(circle); + } + + // отображаем содержимое скрытого холста на экран + window.display(); + } + + return 0; +} diff --git a/seminar09_libraries/04_n_bodies/balls.cpp b/seminar09_libraries/04_n_bodies/balls.cpp new file mode 100644 index 0000000..0ec3f0f --- /dev/null +++ b/seminar09_libraries/04_n_bodies/balls.cpp @@ -0,0 +1,89 @@ +#include +#include +#include +#include +#include +#include + +using namespace std; + +const int min_distance = 5; +const float G = 500; + +struct Ball +{ + float radius; + float mass = 1; + sf::Vector2f position; + sf::Vector2f velocity; +}; + + +int main() +{ + srand(time(0)); + + const int width = 1000; + const int height = 800; + const int n_balls = 15; + + // Шаг по времени + const float delta_t = 0.1; + sf::RenderWindow window(sf::VideoMode(width, height), "My window"); + window.setFramerateLimit(60); + sf::CircleShape circle(50.0f); + circle.setFillColor({200, 216, 200}); + std::vector balls; + balls.resize(n_balls); + for (int i = 0; i < n_balls; i++) + { + balls[i].radius = 4 + rand() % 8; + balls[i].position = {(float)(rand() % width), (float)(rand() % height)}; + balls[i].velocity = {(float)(rand() % 100 - 50), (float)(rand() % 100 - 50)}; + } + while (window.isOpen()) + { + sf::Event event; + while (window.pollEvent(event)) + { + if (event.type == sf::Event::Closed) + window.close(); + } + + window.clear(sf::Color::Black); + + for (int i = 0; i < n_balls; i++) + { + + balls[i].position += balls[i].velocity * delta_t; + for (int j = 0; j < n_balls; ++j) { + if (i == j) + continue; + float distance = std::sqrt((balls[j].position.x - balls[i].position.x) * (balls[j].position.x - balls[i].position.x) + (balls[j].position.y - balls[i].position.y) * (balls[j].position.y - balls[i].position.y)); + if (distance < min_distance) + continue; + auto direction = balls[j].position - balls[i].position; + balls[i].velocity += (direction * G * delta_t * balls[j].mass) / (distance * distance); + } + + if (((balls[i].position.x - balls[i].radius) < 0) || (balls[i].position.x + balls[i].radius> width)) { + balls[i].velocity.x = -balls[i].velocity.x; + balls[i].position.x = (balls[i].position.x - balls[i].radius < 0 ? balls[i].radius : width - balls[i].radius); + } + if ((balls[i].position.y - balls[i].radius < 0) || (balls[i].position.y + balls[i].radius > height)) { + balls[i].velocity.y = -balls[i].velocity.y; + balls[i].position.y = (balls[i].position.y - balls[i].radius < 0 ? balls[i].radius : height - balls[i].radius); + } + + circle.setRadius(balls[i].radius); + circle.setOrigin(balls[i].radius, balls[i].radius); + circle.setPosition(balls[i].position); + + window.draw(circle); + } + + window.display(); + } + + return 0; +} diff --git a/seminar09_libraries/05_n_bodies_mass/balls.cpp b/seminar09_libraries/05_n_bodies_mass/balls.cpp new file mode 100644 index 0000000..daab660 --- /dev/null +++ b/seminar09_libraries/05_n_bodies_mass/balls.cpp @@ -0,0 +1,95 @@ +#include +#include +#include +#include +#include +#include + +using namespace std; + +const int min_distance = 5; +const float G = 500; + +struct Ball +{ + float radius; + float mass; + sf::Vector2f position; + sf::Vector2f velocity; +}; + + +int main() +{ + srand(time(0)); + + const int width = 1000; + const int height = 800; + const int n_balls = 15; + + // Шаг по времени + const float delta_t = 0.1; + sf::RenderWindow window(sf::VideoMode(width, height), "My window"); + window.setFramerateLimit(60); + sf::CircleShape circle(50.0f); + circle.setFillColor({200, 216, 200}); + std::vector balls; + balls.resize(n_balls); + for (int i = 0; i < n_balls; i++) + { + balls[i].radius = 4 + rand() % 8; + balls[i].mass = balls[i].radius * balls[i].radius / 100; + balls[i].position = {(float)(rand() % width), (float)(rand() % height)}; + balls[i].velocity = {(float)(rand() % 100 - 50), (float)(rand() % 100 - 50)}; + } +/* balls[0].radius = 15; + balls[0].mass = 1000; + balls[0].position = {(float)(rand() % width), (float)(rand() % height)}; + balls[0].velocity = {(float)(rand() % 100 - 50), (float)(rand() % 100 - 50)}; + */ + while (window.isOpen()) + { + sf::Event event; + while (window.pollEvent(event)) + { + if (event.type == sf::Event::Closed) + window.close(); + } + + window.clear(sf::Color::Black); + + for (int i = 0; i < n_balls; i++) + { + + balls[i].position += balls[i].velocity * delta_t; + for (int j = 0; j < n_balls; ++j) { + if (i == j) + continue; + float distance = std::sqrt((balls[j].position.x - balls[i].position.x) * (balls[j].position.x - balls[i].position.x) + (balls[j].position.y - balls[i].position.y) * (balls[j].position.y - balls[i].position.y)); + if (distance < min_distance) + continue; + auto direction = balls[j].position - balls[i].position; + balls[i].velocity += (direction * G * delta_t * balls[j].mass) / (distance * distance); + } + + if (((balls[i].position.x - balls[i].radius) < 0) || (balls[i].position.x + balls[i].radius> width)) { + balls[i].velocity.x = -balls[i].velocity.x; + balls[i].position.x = (balls[i].position.x - balls[i].radius < 0 ? balls[i].radius : width - balls[i].radius); + } + if ((balls[i].position.y - balls[i].radius < 0) || (balls[i].position.y + balls[i].radius > height)) { + balls[i].velocity.y = -balls[i].velocity.y; + balls[i].position.y = (balls[i].position.y - balls[i].radius < 0 ? balls[i].radius : height - balls[i].radius); + } + + circle.setRadius(balls[i].radius); + circle.setOrigin(balls[i].radius, balls[i].radius); + circle.setPosition(balls[i].position); + + window.draw(circle); + } + + window.display(); + } + + return 0; +} diff --git a/seminar09_libraries/06_n_bodies_charges/balls.cpp b/seminar09_libraries/06_n_bodies_charges/balls.cpp new file mode 100644 index 0000000..d4b38ac --- /dev/null +++ b/seminar09_libraries/06_n_bodies_charges/balls.cpp @@ -0,0 +1,99 @@ +#include +#include +#include +#include +#include +#include + +using namespace std; + +const int min_distance = 5; +const float K = 25; + +struct Ball +{ + float radius; + float charge; + sf::Vector2f position; + sf::Vector2f velocity; +}; + + +int main() +{ + srand(time(0)); + + const int width = 1000; + const int height = 800; + int n_balls = 4; + + const float delta_t = 0.1; + sf::RenderWindow window(sf::VideoMode(width, height), "My window"); + window.setFramerateLimit(60); + sf::CircleShape circle(50.0f); + + std::vector balls; + balls.resize(n_balls); + for (int i = 0; i < n_balls; i++) + { + balls[i].radius = 4 + rand() % 8; + balls[i].charge = (rand() % 8 - rand() % 8) * balls[i].radius * balls[i].radius; + while (!balls[i].charge) { + balls[i].charge = (rand() % 8 - rand() % 8) * balls[i].radius * balls[i].radius; + } + balls[i].position = {(float)(rand() % width), (float)(rand() % height)}; + balls[i].velocity = {(float)(rand() % 100 - 50), (float)(rand() % 100 - 50)}; + } + while (window.isOpen()) + { + sf::Event event; + while (window.pollEvent(event)) + { + if (event.type == sf::Event::Closed) + window.close(); + } + + window.clear(sf::Color::Black); + + for (int i = 0; i < n_balls; i++) + { + + balls[i].position += balls[i].velocity * delta_t; + for (int j = 0; j < n_balls; ++j) { + if (i == j) + continue; + float distance = std::sqrt((balls[j].position.x - balls[i].position.x) * (balls[j].position.x - balls[i].position.x) + (balls[j].position.y - balls[i].position.y) * (balls[j].position.y - balls[i].position.y)); + if (distance < min_distance) + continue; + auto direction = balls[j].position - balls[i].position; + if (balls[i].charge * balls[j].charge > 0) + balls[i].velocity -= (direction * K * delta_t * std::abs(balls[j].charge)) / (distance * distance); + else + balls[i].velocity += (direction * K * delta_t * std::abs(balls[j].charge)) / (distance * distance); + } + + if (((balls[i].position.x - balls[i].radius) < 0) || (balls[i].position.x + balls[i].radius> width)) { + balls[i].velocity.x = -balls[i].velocity.x; + balls[i].position.x = (balls[i].position.x - balls[i].radius < 0 ? balls[i].radius : width - balls[i].radius); + } + if ((balls[i].position.y - balls[i].radius < 0) || (balls[i].position.y + balls[i].radius > height)) { + balls[i].velocity.y = -balls[i].velocity.y; + balls[i].position.y = (balls[i].position.y - balls[i].radius < 0 ? balls[i].radius : height - balls[i].radius); + } + + circle.setRadius(balls[i].radius); + circle.setOrigin(balls[i].radius, balls[i].radius); + circle.setPosition(balls[i].position); + + if (balls[i].charge > 0) + circle.setFillColor({static_cast(balls[i].charge/1152 * 255 + 100), 0, 0}); + else + circle.setFillColor({0, 0, static_cast(std::abs(balls[i].charge)/1152 * 255 + 100)}); + window.draw(circle); + } + + window.display(); + } + + return 0; +} diff --git a/seminar09_libraries/07_n_bodies_charges_mouse/balls.cpp b/seminar09_libraries/07_n_bodies_charges_mouse/balls.cpp new file mode 100644 index 0000000..5bd8959 --- /dev/null +++ b/seminar09_libraries/07_n_bodies_charges_mouse/balls.cpp @@ -0,0 +1,114 @@ +#include +#include +#include +#include +#include +#include + +using namespace std; + +const int min_distance = 5; +const float K = 5; + +struct Ball +{ + float radius; + float charge; + sf::Vector2f position; + sf::Vector2f velocity; +}; + + +int main() +{ + srand(time(0)); + + const int width = 1000; + const int height = 800; + int n_balls = 0; + + char sign = 1; + + // Шаг по времени + const float delta_t = 0.1; + sf::RenderWindow window(sf::VideoMode(width, height), "My window"); + window.setFramerateLimit(60); + sf::CircleShape circle(50.0f); + + std::vector balls; + balls.resize(n_balls); + while (window.isOpen()) + { + sf::Event event; + while (window.pollEvent(event)) + { + if (event.type == sf::Event::Closed) + window.close(); + if (event.type == sf::Event::KeyPressed) { + if (event.key.code == sf::Keyboard::LShift) { + sign = -1; + } + } + if (event.type == sf::Event::KeyReleased) { + if (event.key.code == sf::Keyboard::LShift) { + sign = 1; + } + } + if(event.type == sf::Event::MouseButtonPressed) { + Ball b; + if(event.mouseButton.button == sf::Mouse::Right) + b.radius = 15; + else if(event.mouseButton.button == sf::Mouse::Left) + b.radius = 5; + b.charge = sign * b.radius * b.radius; + b.position = {(float)(event.mouseButton.x), (float)(event.mouseButton.y)}; + b.velocity = {(float)(0), (float)(0)}; + balls.push_back(b); + n_balls++; + } + } + + window.clear(sf::Color::Black); + + for (int i = 0; i < n_balls; i++) + { + + balls[i].position += balls[i].velocity * delta_t; + for (int j = 0; j < n_balls; ++j) { + if (i == j) + continue; + float distance = std::sqrt((balls[j].position.x - balls[i].position.x) * (balls[j].position.x - balls[i].position.x) + (balls[j].position.y - balls[i].position.y) * (balls[j].position.y - balls[i].position.y)); + if (distance < min_distance) + continue; + auto direction = balls[j].position - balls[i].position; + if (balls[i].charge * balls[j].charge > 0) + balls[i].velocity -= (direction * K * delta_t * std::abs(balls[j].charge)) / (distance * distance); + else + balls[i].velocity += (direction * K * delta_t * std::abs(balls[j].charge)) / (distance * distance); + } + + if (((balls[i].position.x - balls[i].radius) < 0) || (balls[i].position.x + balls[i].radius> width)) { + balls[i].velocity.x = -balls[i].velocity.x; + balls[i].position.x = (balls[i].position.x - balls[i].radius < 0 ? balls[i].radius : width - balls[i].radius); + } + if ((balls[i].position.y - balls[i].radius < 0) || (balls[i].position.y + balls[i].radius > height)) { + balls[i].velocity.y = -balls[i].velocity.y; + balls[i].position.y = (balls[i].position.y - balls[i].radius < 0 ? balls[i].radius : height - balls[i].radius); + } + + circle.setRadius(balls[i].radius); + circle.setOrigin(balls[i].radius, balls[i].radius); + circle.setPosition(balls[i].position); + + if (balls[i].charge > 0) + circle.setFillColor({200, 0, 0}); + else + circle.setFillColor({0, 0, 200}); + window.draw(circle); + } + + window.display(); + } + + return 0; +} diff --git a/seminar09_libraries/homework_libraries.pdf b/seminar09_libraries/homework_libraries.pdf new file mode 100644 index 0000000..3e86d17 Binary files /dev/null and b/seminar09_libraries/homework_libraries.pdf differ