summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSam Anthony <sam@samanthony.xyz>2024-10-02 11:42:40 -0400
committerSam Anthony <sam@samanthony.xyz>2024-10-02 11:42:40 -0400
commit49751d69498c265cb46f6cce5033367ae39c5e91 (patch)
tree5dc5293c2c3e5bc0ccfbcfd4ed3bdc311ee38364
parent66559ba8c23e5d1591336a703785a7bc42e98f2d (diff)
downloadballs-49751d69498c265cb46f6cce5033367ae39c5e91.zip
animate
-rw-r--r--Makefile4
-rw-r--r--balls.cpp54
-rw-r--r--balls.h23
-rw-r--r--collision.c34
4 files changed, 101 insertions, 14 deletions
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 <GL/glut.h>
#include <oneapi/tbb.h>
+#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;
+}