-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Fredrik Jonsén
committed
Oct 13, 2015
1 parent
f438cb6
commit 743cd1c
Showing
22 changed files
with
2,062 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
#include <iostream> | ||
#include "SDL/SDL.h" | ||
#include "MinPQ.h" | ||
#include "Event.h" | ||
#include "Particle.h" | ||
#include "CollisionSystem.h" | ||
|
||
CollisionSystem:: | ||
CollisionSystem(vector<Particle> _particles, SDL_Surface* _screen) | ||
: t(0.0), hz(0.5), particles(_particles), screen(_screen), quit(false) {} | ||
|
||
/** | ||
* Event based simulation for limit seconds | ||
*/ | ||
void | ||
CollisionSystem:: | ||
simulate(double limit) | ||
{ | ||
for (int i = 0; i < particles.size(); i++) | ||
{ | ||
predict(&particles[i], limit); | ||
} | ||
pq.insert(Event(0.0, 0, 0)); // redraw event | ||
|
||
// the main event-driven simulation loop | ||
while (!pq.isEmpty() && !quit) { | ||
|
||
handleIOEvents(); | ||
|
||
// get impending event, discard if invalidated | ||
Event e; | ||
pq.deleteMin(e); | ||
if (!e.isValid()) continue; | ||
|
||
Particle* a = e.getA(); | ||
Particle* b = e.getB(); | ||
|
||
// physical collision, so update positions, and then simulation clock | ||
for (int i = 0; i < particles.size(); i++) | ||
particles[i].move(e.getTime() - t); | ||
t = e.getTime(); | ||
|
||
// process event | ||
if (a != 0 && b != 0) a->bounceOff(*b); // particle-particle collision | ||
else if (a != 0 && b == 0) a->bounceOffVerticalWall(); // particle-wall collision | ||
else if (a == 0 && b != 0) b->bounceOffHorizontalWall(); // particle-wall collision | ||
else if (a == 0 && b == 0) redraw(limit); // redraw event | ||
|
||
// update the priority queue with new collisions involving a or b | ||
predict(a, limit); | ||
predict(b, limit); | ||
} | ||
} | ||
|
||
/** | ||
* Update priority queue with all new events for particle a | ||
*/ | ||
void | ||
CollisionSystem:: | ||
predict(Particle* a, double limit) | ||
{ | ||
if (a == 0) return; | ||
|
||
// particle-particle collisions | ||
for (int i = 0; i < particles.size(); i++) | ||
{ | ||
double dt = a->timeToHit(particles[i]); | ||
if (t + dt <= limit) | ||
{ | ||
pq.insert(Event(t + dt, a, &particles[i])); | ||
} | ||
} | ||
|
||
// particle-wall collisions | ||
double dtX = a->timeToHitVerticalWall(); | ||
double dtY = a->timeToHitHorizontalWall(); | ||
if (t + dtX <= limit) pq.insert(Event(t + dtX, a, 0)); | ||
if (t + dtY <= limit) pq.insert(Event(t + dtY, 0, a)); | ||
} | ||
|
||
/** | ||
* Redraw all particles | ||
*/ | ||
void | ||
CollisionSystem:: | ||
redraw(double limit) | ||
{ | ||
SDL_FillRect(screen, &screen->clip_rect, SDL_MapRGB( screen->format, 0xFF, 0xFF, 0xFF )); // clear the screen with white | ||
SDL_LockSurface(screen); | ||
|
||
for (int i = 0; i < particles.size(); i++) | ||
{ | ||
particles[i].draw(screen); | ||
} | ||
SDL_FreeSurface(screen); | ||
SDL_Flip(screen); // display screen | ||
SDL_Delay(20); // pause for 20 milliseconds | ||
if (t < limit) | ||
{ | ||
pq.insert(Event(t + 1.0 / hz, 0, 0)); | ||
} | ||
} | ||
|
||
/** | ||
* Handle keyboard and mouse events | ||
*/ | ||
void | ||
CollisionSystem:: | ||
handleIOEvents() | ||
{ | ||
while (SDL_PollEvent(&ioevents)) | ||
{ | ||
if (ioevents.type == SDL_QUIT) // The user closed the window? | ||
{ | ||
quit = true; // Quit the program | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/************************************************************************* | ||
* | ||
* Simulates N particles and their motion according to the laws | ||
* of elastic collisions. | ||
* | ||
*************************************************************************/ | ||
#ifndef COLLISIONSYSTEM_H | ||
#define COLLISIONSYSTEM_H | ||
|
||
#include "SDL/SDL.h" | ||
#include "MinPQ.h" | ||
#include "Event.h" | ||
#include "Particle.h" | ||
|
||
class CollisionSystem | ||
{ | ||
public: | ||
CollisionSystem(vector<Particle>, SDL_Surface*); | ||
|
||
void simulate(double); | ||
|
||
private: | ||
MinPQ<Event> pq; // the priority queue | ||
double t; // simulation clock time | ||
double hz; // number of redraw events per clock tick | ||
vector<Particle> particles; // the array of particles | ||
SDL_Surface* screen; // main screen used for rendering | ||
SDL_Event ioevents; // SDL event queue | ||
bool quit; // quit flag, program exits when tru | ||
|
||
void predict(Particle*, double); | ||
|
||
void redraw(double); | ||
void handleIOEvents(); | ||
}; | ||
|
||
#endif |
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
#include "Event.h" | ||
#include "Particle.h" | ||
|
||
Event:: | ||
Event() {} | ||
|
||
Event:: | ||
Event(double t, Particle* _a, Particle* _b) | ||
: time(t), a(_a), b(_b), countA(-1), countB(-1) | ||
{ | ||
if (a != 0) countA = a->collisions(); | ||
if (b != 0) countB = b->collisions(); | ||
} | ||
|
||
bool | ||
Event:: | ||
isValid() | ||
{ | ||
if (a != 0 && a->collisions() != countA) return false; | ||
if (b != 0 && b->collisions() != countB) return false; | ||
return true; | ||
} | ||
|
||
Particle* | ||
Event:: | ||
getA() | ||
{ | ||
return a; | ||
} | ||
|
||
|
||
Particle* | ||
Event:: | ||
getB() | ||
{ | ||
return b; | ||
} | ||
|
||
double | ||
Event:: | ||
getTime() | ||
{ | ||
return time; | ||
} | ||
|
||
bool | ||
Event:: | ||
operator<(const Event& rhs) const | ||
{ | ||
return time < rhs.time; | ||
} | ||
|
||
bool | ||
Event:: | ||
operator==(const Event& rhs) const | ||
{ | ||
return time == rhs.time; | ||
} | ||
|
||
bool | ||
Event:: | ||
operator!=(const Event& rhs) const | ||
{ | ||
return !(*this == rhs); | ||
} | ||
|
||
bool | ||
Event:: | ||
operator>(const Event& rhs) const | ||
{ | ||
return (rhs < *this); | ||
} | ||
|
||
bool | ||
Event:: | ||
operator<=(const Event& rhs) const | ||
{ | ||
return !(rhs < *this); | ||
} | ||
|
||
bool | ||
Event:: | ||
operator>=(const Event& rhs) const | ||
{ | ||
return !(*this < rhs); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
/************************************************************************* | ||
* An event during a particle collision simulation. Each event contains | ||
* the time at which it will occur (assuming no supervening actions) | ||
* and the particles a and b involved. | ||
* | ||
* - a and b both null: redraw event | ||
* - a null, b not null: collision with vertical wall | ||
* - a not null, b null: collision with horizontal wall | ||
* - a and b both not null: binary collision between a and b | ||
* | ||
*************************************************************************/ | ||
#ifndef EVENT_H | ||
#define EVENT_H | ||
|
||
#include "Particle.h" | ||
|
||
class Event | ||
{ | ||
public: | ||
Event(); | ||
Event(double, Particle*, Particle*); | ||
|
||
bool isValid(); | ||
Particle* getA(); | ||
Particle* getB(); | ||
double getTime(); | ||
bool operator<(const Event&) const; | ||
bool operator==(const Event&) const; | ||
bool operator!=(const Event&) const; | ||
bool operator>(const Event&) const; | ||
bool operator<=(const Event&) const; | ||
bool operator>=(const Event&) const; | ||
|
||
private: | ||
double time; // time that event is scheduled to occur | ||
Particle* a; // particle involved in event, possibly null | ||
Particle* b; // particle involved in event, possibly null | ||
int countA; // collision counts at event creation | ||
int countB; // collision counts at event creation | ||
}; | ||
|
||
#endif |
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# | ||
# Makefile för simulering | ||
# | ||
|
||
CCC = g++ | ||
LFLAGS = -L/usr/lib/x86_64-linux-gnu -lSDL -lm | ||
|
||
all: simulation.cc CollisionSystem.o Event.o Particle.o | ||
$(CCC) -o simulation simulation.cc CollisionSystem.o Event.o Particle.o $(LFLAGS$) | ||
|
||
CollisionSystem.o: CollisionSystem.cc CollisionSystem.h MinPQ.h | ||
$(CCC) -c CollisionSystem.cc CollisionSystem.h MinPQ.h | ||
|
||
Event.o: Event.cc Event.h | ||
$(CCC) -c Event.cc Event.h | ||
|
||
Particle.o: Particle.cc Particle.h | ||
$(CCC) -c Particle.cc Particle.h | ||
|
||
clean: | ||
@ \rm -rf *.o *.gch core | ||
|
||
zap: clean | ||
@ \rm -f simulation *~ |
Oops, something went wrong.