From 49751d69498c265cb46f6cce5033367ae39c5e91 Mon Sep 17 00:00:00 2001 From: Sam Anthony Date: Wed, 2 Oct 2024 11:42:40 -0400 Subject: animate --- Makefile | 4 ++-- balls.cpp | 54 ++++++++++++++++++++++++++++++++++++++++++------------ balls.h | 23 +++++++++++++++++++++++ collision.c | 34 ++++++++++++++++++++++++++++++++++ 4 files changed, 101 insertions(+), 14 deletions(-) create mode 100644 balls.h create mode 100644 collision.c diff --git a/Makefile b/Makefile index be1b32b..8bd89f1 100644 --- a/Makefile +++ b/Makefile @@ -2,9 +2,9 @@ CC = g++ CFLAGS = -Wall -pedantic LDFLAGS = -ltbb -lglut -lGLU -lGL -balls: balls.o +balls: balls.o collision.o ${CC} -o $@ $^ ${LDFLAGS} @echo done -%.o: %.cpp +%.o: %.cpp balls.h ${CC} -c ${CFLAGS} $< \ No newline at end of file diff --git a/balls.cpp b/balls.cpp index 555b192..621fb13 100644 --- a/balls.cpp +++ b/balls.cpp @@ -2,27 +2,32 @@ #include #include +#include "balls.h" + using namespace std; -enum window { WIDTH = 800, HEIGHT = 600 }; -enum keys { KEY_QUIT = 'q' }; -enum { CIRCLE_SEGS = 32 }; +enum { + WIDTH = 800, + HEIGHT = 600, + + KEY_QUIT = 'q', -typedef struct { - double x, y; -} Point; + CIRCLE_SEGS = 32, -typedef struct { - Point min, max; -} Rectangle; + FPS = 60, + MS_PER_S = 1000, + FRAME_TIME_MS = MS_PER_S / FPS, +}; void keyboard(unsigned char key, int x, int y); void display(void); void drawBg(void); void drawCircle(double radius, Point p); void reshape(int w, int h); +void animate(int v); const static Rectangle bounds = {{-1.5, -1.0}, {1.5, 1.0}}; +static Ball ball = {{0.25, 0.25}, {0.25, 0.25}, 0.200, 0.25}; int main(int argc, char *argv[]) { @@ -34,6 +39,7 @@ main(int argc, char *argv[]) { glutKeyboardFunc(keyboard); glutDisplayFunc(display); glutReshapeFunc(reshape); + glutTimerFunc(FRAME_TIME_MS, animate, 0); glClearColor(1.0, 1.0, 1.0, 1.0); @@ -50,12 +56,10 @@ keyboard(unsigned char key, int x, int y) { void display(void) { - static Point p = {0.35, 0.35}; - glClearColor(0, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT); drawBg(); - drawCircle(0.25, p); + drawCircle(ball.r, ball.p); glutSwapBuffers(); } @@ -102,3 +106,29 @@ reshape(int w, int h) { glOrtho(-1, 1, -1.0/ratio, 1.0/ratio, -1, 1); glMatrixMode(GL_MODELVIEW); } + +void +animate(int v) { + ball.p = ptAddVec(ball.p, ball.v); + + collideWall(&ball, bounds); + + display(); + glutTimerFunc(FRAME_TIME_MS, animate, 0); +} + +Point +ptAddVec(Point p, Vector v) { + p.x += v.x; + p.y += v.y; + return p; +} + +Rectangle +insetRect(Rectangle r, double n) { + r.min.x += n; + r.min.y += n; + r.max.x -= n; + r.max.y -= n; + return r; +} diff --git a/balls.h b/balls.h new file mode 100644 index 0000000..3205959 --- /dev/null +++ b/balls.h @@ -0,0 +1,23 @@ +typedef struct { + double x, y; +} Point; + +typedef struct { + Point min, max; +} Rectangle; + +typedef struct { + double x, y; +} Vector; + +typedef struct { + Point p; /* position [m] */ + Vector v; /* velocity [m/s] */ + double m; /* mass [kg] */ + double r; /* radius [m] */ +} Ball; + +Point ptAddVec(Point p, Vector v); +Rectangle insetRect(Rectangle r, double n); + +void collideWall(Ball *b, Rectangle wall); \ No newline at end of file diff --git a/collision.c b/collision.c new file mode 100644 index 0000000..17889a4 --- /dev/null +++ b/collision.c @@ -0,0 +1,34 @@ +#include "balls.h" + +static double clamp(double v, double lo, double hi); +static double min(double a, double b); +static double max(double a, double b); + +void +collideWall(Ball *b, Rectangle wall) { + wall = insetRect(wall, b->r); + + if (b->p.x < wall.min.x || b->p.x > wall.max.x) { + b->p.x = clamp(b->p.x, wall.min.x, wall.max.x); + b->v.x = -b->v.x; + } + if (b->p.y < wall.min.y || b->p.y > wall.max.y) { + b->p.y = clamp(b->p.y, wall.min.y, wall.max.y); + b->v.y = -b->v.y; + } +} + +static double +clamp(double v, double lo, double hi) { + return min(hi, max(v, lo)); +} + +static double +min(double a, double b) { + return (a < b) ? a : b; +} + +static double +max(double a, double b) { + return (a > b) ? a : b; +} -- cgit v1.2.3