Repository navigation
Expand file tree
/
Copy pathmain.cpp
More file actions
128 lines (110 loc) · 4.6 KB
/
Copy pathmain.cpp
File metadata and controls
128 lines (110 loc) · 4.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include "BallSimulation.hpp"
#include <SFML/Graphics.hpp>
#include <vector>
#include <random>
#include <cmath>
#include <unordered_map>
int main() {
sf::RenderWindow window(sf::VideoMode(WINDOW_WIDTH, WINDOW_HEIGHT), "Ball Simulation", sf::Style::Default);
window.setFramerateLimit(60);
sf::CircleShape disturbanceBall(30.f);
disturbanceBall.setFillColor(sf::Color::Red);
disturbanceBall.setOrigin(30.f, 30.f);
bool disturbanceActive = false;
std::vector<Ball> balls(NUM_BALLS);
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<float> x_dist(0, WINDOW_WIDTH);
std::uniform_real_distribution<float> y_dist(0, WINDOW_HEIGHT);
for (auto& ball : balls) {
ball.position.x = x_dist(gen);
ball.position.y = y_dist(gen);
ball.velocity = sf::Vector2f(0.f, 0.f);
ball.color = sf::Color::Blue; // Initialize with blue color
}
while (window.isOpen()) {
sf::Event event;
while (window.pollEvent(event)) {
if (event.type == sf::Event::Closed)
window.close();
if (event.type == sf::Event::MouseButtonPressed && event.mouseButton.button == sf::Mouse::Left)
disturbanceActive = true;
if (event.type == sf::Event::MouseButtonReleased && event.mouseButton.button == sf::Mouse::Left)
disturbanceActive = false;
}
if (disturbanceActive) {
sf::Vector2i mousePosition = sf::Mouse::getPosition(window);
for (auto& ball : balls) {
sf::Vector2f direction = ball.position - static_cast<sf::Vector2f>(mousePosition);
float distanceSquared = direction.x * direction.x + direction.y * direction.y;
if (distanceSquared < REPEL_DISTANCE * REPEL_DISTANCE && distanceSquared > 0) {
float distance = std::sqrt(distanceSquared);
direction /= distance;
ball.velocity += direction * DISTURBANCE_FORCE / distance;
}
}
}
std::unordered_map<std::pair<int, int>, std::vector<Ball*>, PairHash> grid;
for (auto& ball : balls) {
auto gridPos = getGridPosition(ball.position);
grid[gridPos].push_back(&ball);
}
for (auto& cell : grid) {
auto& cellBalls = cell.second;
for (size_t i = 0; i < cellBalls.size(); ++i) {
for (size_t j = i + 1; j < cellBalls.size(); ++j) {
handleCollision(*cellBalls[i], *cellBalls[j]);
}
}
auto [x, y] = cell.first;
for (int dx = -1; dx <= 1; ++dx) {
for (int dy = -1; dy <= 1; ++dy) {
auto neighbor = std::make_pair(x + dx, y + dy);
if (grid.find(neighbor) != grid.end()) {
auto& neighborBalls = grid[neighbor];
for (auto& ball1 : cellBalls) {
for (auto& ball2 : neighborBalls) {
handleCollision(*ball1, *ball2);
}
}
}
}
}
}
for (auto& ball : balls) {
ball.velocity.y += GRAVITY;
ball.velocity *= FRICTION;
ball.position += ball.velocity;
if (ball.position.x < BALL_RADIUS) {
ball.position.x = BALL_RADIUS;
ball.velocity.x = -ball.velocity.x;
}
if (ball.position.x > WINDOW_WIDTH - BALL_RADIUS) {
ball.position.x = WINDOW_WIDTH - BALL_RADIUS;
ball.velocity.x = -ball.velocity.x;
}
if (ball.position.y < BALL_RADIUS) {
ball.position.y = BALL_RADIUS;
ball.velocity.y = -ball.velocity.y;
}
if (ball.position.y > WINDOW_HEIGHT - BALL_RADIUS) {
ball.position.y = WINDOW_HEIGHT - BALL_RADIUS;
ball.velocity.y = -ball.velocity.y;
}
}
window.clear(sf::Color::White);
if (disturbanceActive) {
disturbanceBall.setPosition(static_cast<sf::Vector2f>(sf::Mouse::getPosition(window)));
window.draw(disturbanceBall);
}
sf::CircleShape ballShape(BALL_RADIUS);
ballShape.setOrigin(BALL_RADIUS, BALL_RADIUS);
ballShape.setFillColor(sf::Color::Blue);
for (const auto& ball : balls) {
ballShape.setPosition(ball.position);
window.draw(ballShape);
}
window.display();
}
return 0;
}