From ba9f85849e061e478f7cfc36cf93bff07bbcebb0 Mon Sep 17 00:00:00 2001 From: Caleb Sander <caleb.sander@gmail.com> Date: Thu, 19 Mar 2020 21:01:20 -0400 Subject: [PATCH] Rename types to _t --- include/body.h | 45 +++++----- include/collision.h | 3 +- include/forces.h | 22 +++-- include/scene.h | 30 ++++--- tests/test_suite_body.c | 177 +++++++++++++++++++------------------- tests/test_suite_forces.c | 78 ++++++++--------- tests/test_suite_scene.c | 132 ++++++++++++++-------------- 7 files changed, 250 insertions(+), 237 deletions(-) diff --git a/include/body.h b/include/body.h index 8ecc37e..9681495 100644 --- a/include/body.h +++ b/include/body.h @@ -2,7 +2,6 @@ #define __BODY_H__ #include <stdbool.h> - #include "color.h" #include "list.h" #include "vector.h" @@ -13,13 +12,13 @@ * Bodies can accumulate forces and impulses during each tick. * Angular physics (i.e. torques) are not currently implemented. */ -typedef struct body Body; +typedef struct body body_t; /** * Initializes a body without any info. * Acts like body_init_with_info() where info and info_freer are NULL. */ -Body *body_init(List *shape, double mass, RGBColor color); +body_t *body_init(list_t *shape, double mass, rgb_color_t color); /** * Allocates memory for a body with the given parameters. @@ -27,15 +26,19 @@ Body *body_init(List *shape, double mass, RGBColor color); * Asserts that the mass is positive and that the required memory is allocated. * * @param shape a list of vectors describing the initial shape of the body - * @param mass the mass of the body (if INFINITY, prevents the body from moving) + * @param mass the mass of the body (if INFINITY, stops the body from moving) * @param color the color of the body, used to draw it on the screen * @param info additional information to associate with the body, * e.g. its type if the scene has multiple types of bodies * @param info_freer if non-NULL, a function call on the info to free it * @return a pointer to the newly allocated body */ -Body *body_init_with_info( - List *shape, double mass, RGBColor color, void *info, FreeFunc info_freer +body_t *body_init_with_info( + list_t *shape, + double mass, + rgb_color_t color, + void *info, + free_func_t info_freer ); /** @@ -43,7 +46,7 @@ Body *body_init_with_info( * * @param body a pointer to a body returned from body_init() */ -void body_free(Body *body); +void body_free(body_t *body); /** * Gets the current shape of a body. @@ -52,7 +55,7 @@ void body_free(Body *body); * @param body a pointer to a body returned from body_init() * @return the polygon describing the body's current position */ -List *body_get_shape(Body *body); +list_t *body_get_shape(body_t *body); /** * Gets the current center of mass of a body. @@ -63,7 +66,7 @@ List *body_get_shape(Body *body); * @param body a pointer to a body returned from body_init() * @return the body's center of mass */ -Vector body_get_centroid(Body *body); +vector_t body_get_centroid(body_t *body); /** * Gets the current velocity of a body. @@ -71,7 +74,7 @@ Vector body_get_centroid(Body *body); * @param body a pointer to a body returned from body_init() * @return the body's velocity vector */ -Vector body_get_velocity(Body *body); +vector_t body_get_velocity(body_t *body); /** * Gets the mass of a body. @@ -79,7 +82,7 @@ Vector body_get_velocity(Body *body); * @param body a pointer to a body returned from body_init() * @return the mass passed to body_init(), which must be greater than 0 */ -double body_get_mass(Body *body); +double body_get_mass(body_t *body); /** * Gets the display color of a body. @@ -87,7 +90,7 @@ double body_get_mass(Body *body); * @param body a pointer to a body returned from body_init() * @return the color passed to body_init(), as an (R, G, B) tuple */ -RGBColor body_get_color(Body *body); +rgb_color_t body_get_color(body_t *body); /** * Gets the information associated with a body. @@ -95,7 +98,7 @@ RGBColor body_get_color(Body *body); * @param body a pointer to a body returned from body_init() * @return the info passed to body_init() */ -void *body_get_info(Body *body); +void *body_get_info(body_t *body); /** * Translates a body to a new position. @@ -104,7 +107,7 @@ void *body_get_info(Body *body); * @param body a pointer to a body returned from body_init() * @param x the body's new centroid */ -void body_set_centroid(Body *body, Vector x); +void body_set_centroid(body_t *body, vector_t x); /** * Changes a body's velocity (the time-derivative of its position). @@ -112,7 +115,7 @@ void body_set_centroid(Body *body, Vector x); * @param body a pointer to a body returned from body_init() * @param v the body's new velocity */ -void body_set_velocity(Body *body, Vector v); +void body_set_velocity(body_t *body, vector_t v); /** * Changes a body's orientation in the plane. @@ -122,7 +125,7 @@ void body_set_velocity(Body *body, Vector v); * @param body a pointer to a body returned from body_init() * @param angle the body's new angle in radians. Positive is counterclockwise. */ -void body_set_rotation(Body *body, double angle); +void body_set_rotation(body_t *body, double angle); /** * Applies a force to a body over the current tick. @@ -132,7 +135,7 @@ void body_set_rotation(Body *body, double angle); * @param body a pointer to a body returned from body_init() * @param force the force vector to apply */ -void body_add_force(Body *body, Vector force); +void body_add_force(body_t *body, vector_t force); /** * Applies an impulse to a body. @@ -144,7 +147,7 @@ void body_add_force(Body *body, Vector force); * @param body a pointer to a body returned from body_init() * @param impulse the impulse vector to apply */ -void body_add_impulse(Body *body, Vector impulse); +void body_add_impulse(body_t *body, vector_t impulse); /** * Updates the body after a given time interval has elapsed. @@ -157,7 +160,7 @@ void body_add_impulse(Body *body, Vector impulse); * @param body the body to tick * @param dt the number of seconds elapsed since the last tick */ -void body_tick(Body *body, double dt); +void body_tick(body_t *body, double dt); /** * Marks a body for removal--future calls to body_is_removed() will return true. @@ -166,7 +169,7 @@ void body_tick(Body *body, double dt); * * @param body the body to mark for removal */ -void body_remove(Body *body); +void body_remove(body_t *body); /** * Returns whether a body has been marked for removal. @@ -176,6 +179,6 @@ void body_remove(Body *body); * @param body the body to check * @return whether body_remove() has been called on the body */ -bool body_is_removed(Body *body); +bool body_is_removed(body_t *body); #endif // #ifndef __BODY_H__ diff --git a/include/collision.h b/include/collision.h index 4f524cf..5c4616f 100644 --- a/include/collision.h +++ b/include/collision.h @@ -3,7 +3,6 @@ #include <stdbool.h> #include "list.h" -#include "vector.h" /** * Determines whether two convex polygons intersect. @@ -15,6 +14,6 @@ * @param shape2 the second shape * @return whether the shapes are colliding */ -bool find_collision(List *shape1, List *shape2); +bool find_collision(list_t *shape1, list_t *shape2); #endif // #ifndef __COLLISION_H__ diff --git a/include/forces.h b/include/forces.h index c446f55..cef8567 100644 --- a/include/forces.h +++ b/include/forces.h @@ -4,7 +4,9 @@ #include "scene.h" /** - * Adds a Newtonian gravitational force between two bodies in a scene. + * Adds a force creator to a scene that applies gravity between two bodies. + * The force creator will be called each tick + * to compute the Newtonian gravitational force between the bodies. * See https://en.wikipedia.org/wiki/Newton%27s_law_of_universal_gravitation#Vector_form. * The force should not be applied when the bodies are very close, * because its magnitude blows up as the distance between the bodies goes to 0. @@ -14,10 +16,12 @@ * @param body1 the first body * @param body2 the second body */ -void create_newtonian_gravity(Scene *scene, double G, Body *body1, Body *body2); +void create_newtonian_gravity(scene_t *scene, double G, body_t *body1, body_t *body2); /** - * Adds a Hooke's-Law spring force between two bodies in a scene. + * Adds a force creator to a scene that acts like a spring between two bodies. + * The force creator will be called each tick + * to compute the Hooke's-Law spring force between the bodies. * See https://en.wikipedia.org/wiki/Hooke%27s_law. * * @param scene the scene containing the bodies @@ -25,10 +29,12 @@ void create_newtonian_gravity(Scene *scene, double G, Body *body1, Body *body2); * @param body1 the first body * @param body2 the second body */ -void create_spring(Scene *scene, double k, Body *body1, Body *body2); +void create_spring(scene_t *scene, double k, body_t *body1, body_t *body2); /** - * Adds a drag force on a body proportional to its velocity. + * Adds a force creator to a scene that applies a drag force on a body. + * The force creator will be called each tick + * to compute the drag force on the body proportional to its velocity. * The force points opposite the body's velocity. * * @param scene the scene containing the bodies @@ -36,16 +42,16 @@ void create_spring(Scene *scene, double k, Body *body1, Body *body2); * (higher gamma means more drag) * @param body the body to slow down */ -void create_drag(Scene *scene, double gamma, Body *body); +void create_drag(scene_t *scene, double gamma, body_t *body); /** - * Adds a ForceCreator to a scene that destroys two bodies when they collide. + * Adds a force creator to a scene that destroys two bodies when they collide. * The bodies should be destroyed by calling body_remove(). * * @param scene the scene containing the bodies * @param body1 the first body * @param body2 the second body */ -void create_destructive_collision(Scene *scene, Body *body1, Body *body2); +void create_destructive_collision(scene_t *scene, body_t *body1, body_t *body2); #endif // #ifndef __FORCES_H__ diff --git a/include/scene.h b/include/scene.h index 9922370..e1d0e8e 100644 --- a/include/scene.h +++ b/include/scene.h @@ -1,7 +1,6 @@ #ifndef __SCENE_H__ #define __SCENE_H__ -#include <stdbool.h> #include "body.h" #include "list.h" @@ -10,14 +9,14 @@ * The scene automatically resizes to store * arbitrarily many bodies and force creators. */ -typedef struct scene Scene; +typedef struct scene scene_t; /** * A function which adds some forces or impulses to bodies, * e.g. from collisions, gravity, or spring forces. * Takes in an auxiliary value that can store parameters or state. */ -typedef void (*ForceCreator)(void *aux); +typedef void (*force_creator_t)(void *aux); /** * Allocates memory for an empty scene. @@ -26,7 +25,7 @@ typedef void (*ForceCreator)(void *aux); * * @return the new scene */ -Scene *scene_init(void); +scene_t *scene_init(void); /** * Releases memory allocated for a given scene @@ -34,7 +33,7 @@ Scene *scene_init(void); * * @param scene a pointer to a scene returned from scene_init() */ -void scene_free(Scene *scene); +void scene_free(scene_t *scene); /** * Gets the number of bodies in a given scene. @@ -42,7 +41,7 @@ void scene_free(Scene *scene); * @param scene a pointer to a scene returned from scene_init() * @return the number of bodies added with scene_add_body() */ -size_t scene_bodies(Scene *scene); +size_t scene_bodies(scene_t *scene); /** * Gets the body at a given index in a scene. @@ -52,7 +51,7 @@ size_t scene_bodies(Scene *scene); * @param index the index of the body in the scene (starting at 0) * @return a pointer to the body at the given index */ -Body *scene_get_body(Scene *scene, size_t index); +body_t *scene_get_body(scene_t *scene, size_t index); /** * Adds a body to a scene. @@ -60,7 +59,7 @@ Body *scene_get_body(Scene *scene, size_t index); * @param scene a pointer to a scene returned from scene_init() * @param body a pointer to the body to add to the scene */ -void scene_add_body(Scene *scene, Body *body); +void scene_add_body(scene_t *scene, body_t *body); /** * @deprecated Use body_remove() instead @@ -71,14 +70,17 @@ void scene_add_body(Scene *scene, Body *body); * @param scene a pointer to a scene returned from scene_init() * @param index the index of the body in the scene (starting at 0) */ -void scene_remove_body(Scene *scene, size_t index); +void scene_remove_body(scene_t *scene, size_t index); /** * @deprecated Use scene_add_bodies_force_creator() instead * so the scene knows which bodies the force creator depends on */ void scene_add_force_creator( - Scene *scene, ForceCreator forcer, void *aux, FreeFunc freer + scene_t *scene, + force_creator_t forcer, + void *aux, + free_func_t freer ); /** @@ -97,7 +99,11 @@ void scene_add_force_creator( * @param freer if non-NULL, a function to call in order to free aux */ void scene_add_bodies_force_creator( - Scene *scene, ForceCreator forcer, void *aux, List *bodies, FreeFunc freer + scene_t *scene, + force_creator_t forcer, + void *aux, + list_t *bodies, + free_func_t freer ); /** @@ -110,6 +116,6 @@ void scene_add_bodies_force_creator( * @param scene a pointer to a scene returned from scene_init() * @param dt the time elapsed since the last tick, in seconds */ -void scene_tick(Scene *scene, double dt); +void scene_tick(scene_t *scene, double dt); #endif // #ifndef __SCENE_H__ diff --git a/tests/test_suite_body.c b/tests/test_suite_body.c index c6b3e00..01c8956 100644 --- a/tests/test_suite_body.c +++ b/tests/test_suite_body.c @@ -5,23 +5,23 @@ #include <stdlib.h> void test_body_init() { - Vector v[] = {{1, 1}, {2, 1}, {2, 2}, {1, 2}}; + vector_t v[] = {{1, 1}, {2, 1}, {2, 2}, {1, 2}}; const size_t VERTICES = sizeof(v) / sizeof(*v); - List *shape = list_init(0, free); + list_t *shape = list_init(0, free); for (size_t i = 0; i < VERTICES; i++) { - Vector *list_v = malloc(sizeof(*list_v)); + vector_t *list_v = malloc(sizeof(*list_v)); *list_v = v[i]; list_add(shape, list_v); } - RGBColor color = {0, 0.5, 1}; - Body *body = body_init(shape, 3, color); - List *shape2 = body_get_shape(body); + rgb_color_t color = {0, 0.5, 1}; + body_t *body = body_init(shape, 3, color); + list_t *shape2 = body_get_shape(body); assert(list_size(shape2) == VERTICES); for (size_t i = 0; i < VERTICES; i++) { - assert(vec_isclose(*(Vector *) list_get(shape2, i), v[i])); + assert(vec_isclose(*(vector_t *) list_get(shape2, i), v[i])); } list_free(shape2); - assert(vec_isclose(body_get_centroid(body), (Vector) {1.5, 1.5})); + assert(vec_isclose(body_get_centroid(body), (vector_t) {1.5, 1.5})); assert(vec_equal(body_get_velocity(body), VEC_ZERO)); assert(body_get_color(body).r == color.r); assert(body_get_color(body).g == color.g); @@ -31,65 +31,65 @@ void test_body_init() { } void test_body_setters() { - List *shape = list_init(3, free); - Vector *v = malloc(sizeof(*v)); - *v = (Vector) {+1, 0}; + list_t *shape = list_init(3, free); + vector_t *v = malloc(sizeof(*v)); + *v = (vector_t) {+1, 0}; list_add(shape, v); v = malloc(sizeof(*v)); - *v = (Vector) {0, +1}; + *v = (vector_t) {0, +1}; list_add(shape, v); v = malloc(sizeof(*v)); - *v = (Vector) {-1, 0}; + *v = (vector_t) {-1, 0}; list_add(shape, v); - Body *body = body_init(shape, 1, (RGBColor) {0, 0, 0}); - body_set_velocity(body, (Vector) {+5, -5}); - assert(vec_equal(body_get_velocity(body), (Vector) {+5, -5})); - assert(vec_isclose(body_get_centroid(body), (Vector) {0, 1.0 / 3.0})); - body_set_centroid(body, (Vector) {1, 2}); - assert(vec_isclose(body_get_centroid(body), (Vector) {1, 2})); + body_t *body = body_init(shape, 1, (rgb_color_t) {0, 0, 0}); + body_set_velocity(body, (vector_t) {+5, -5}); + assert(vec_equal(body_get_velocity(body), (vector_t) {+5, -5})); + assert(vec_isclose(body_get_centroid(body), (vector_t) {0, 1.0 / 3.0})); + body_set_centroid(body, (vector_t) {1, 2}); + assert(vec_isclose(body_get_centroid(body), (vector_t) {1, 2})); shape = body_get_shape(body); assert(list_size(shape) == 3); - assert(vec_isclose(*(Vector *) list_get(shape, 0), (Vector) {2, 5.0 / 3.0})); - assert(vec_isclose(*(Vector *) list_get(shape, 1), (Vector) {1, 8.0 / 3.0})); - assert(vec_isclose(*(Vector *) list_get(shape, 2), (Vector) {0, 5.0 / 3.0})); + assert(vec_isclose(*(vector_t *) list_get(shape, 0), (vector_t) {2, 5.0 / 3.0})); + assert(vec_isclose(*(vector_t *) list_get(shape, 1), (vector_t) {1, 8.0 / 3.0})); + assert(vec_isclose(*(vector_t *) list_get(shape, 2), (vector_t) {0, 5.0 / 3.0})); list_free(shape); body_set_rotation(body, M_PI / 2); - assert(vec_isclose(body_get_centroid(body), (Vector) {1, 2})); + assert(vec_isclose(body_get_centroid(body), (vector_t) {1, 2})); shape = body_get_shape(body); assert(list_size(shape) == 3); - assert(vec_isclose(*(Vector *) list_get(shape, 0), (Vector) {4.0 / 3.0, 3})); - assert(vec_isclose(*(Vector *) list_get(shape, 1), (Vector) {1.0 / 3.0, 2})); - assert(vec_isclose(*(Vector *) list_get(shape, 2), (Vector) {4.0 / 3.0, 1})); + assert(vec_isclose(*(vector_t *) list_get(shape, 0), (vector_t) {4.0 / 3.0, 3})); + assert(vec_isclose(*(vector_t *) list_get(shape, 1), (vector_t) {1.0 / 3.0, 2})); + assert(vec_isclose(*(vector_t *) list_get(shape, 2), (vector_t) {4.0 / 3.0, 1})); list_free(shape); - body_set_centroid(body, (Vector) {3, 4}); - assert(vec_isclose(body_get_centroid(body), (Vector) {3, 4})); + body_set_centroid(body, (vector_t) {3, 4}); + assert(vec_isclose(body_get_centroid(body), (vector_t) {3, 4})); shape = body_get_shape(body); assert(list_size(shape) == 3); - assert(vec_isclose(*(Vector *) list_get(shape, 0), (Vector) {10.0 / 3.0, 5})); - assert(vec_isclose(*(Vector *) list_get(shape, 1), (Vector) {7.0 / 3.0, 4})); - assert(vec_isclose(*(Vector *) list_get(shape, 2), (Vector) {10.0 / 3.0, 3})); + assert(vec_isclose(*(vector_t *) list_get(shape, 0), (vector_t) {10.0 / 3.0, 5})); + assert(vec_isclose(*(vector_t *) list_get(shape, 1), (vector_t) {7.0 / 3.0, 4})); + assert(vec_isclose(*(vector_t *) list_get(shape, 2), (vector_t) {10.0 / 3.0, 3})); list_free(shape); body_free(body); } void test_body_tick() { - const Vector A = {1, 2}; + const vector_t A = {1, 2}; const double DT = 1e-6; const int STEPS = 1000000; - List *shape = list_init(4, free); - Vector *v = malloc(sizeof(*v)); + list_t *shape = list_init(4, free); + vector_t *v = malloc(sizeof(*v)); v->x = v->y = -1; list_add(shape, v); v = malloc(sizeof(*v)); - *v = (Vector) {+1, -1}; + *v = (vector_t) {+1, -1}; list_add(shape, v); v = malloc(sizeof(*v)); v->x = v->y = +1; list_add(shape, v); v = malloc(sizeof(*v)); - *v = (Vector) {-1, +1}; + *v = (vector_t) {-1, +1}; list_add(shape, v); - Body *body = body_init(shape, 1, (RGBColor) {0, 0, 0}); + body_t *body = body_init(shape, 1, (rgb_color_t) {0, 0, 0}); // Apply constant acceleration and ensure position is (a / 2) * t ** 2 for (int i = 0; i < STEPS; i++) { @@ -99,66 +99,66 @@ void test_body_tick() { body_tick(body, DT); } double t = STEPS * DT; - Vector new_x = vec_multiply(t * t / 2, A); + vector_t new_x = vec_multiply(t * t / 2, A); shape = body_get_shape(body); - assert(vec_isclose(*(Vector *) list_get(shape, 0), vec_add((Vector) {-1, -1}, new_x))); - assert(vec_isclose(*(Vector *) list_get(shape, 1), vec_add((Vector) {+1, -1}, new_x))); - assert(vec_isclose(*(Vector *) list_get(shape, 2), vec_add((Vector) {+1, +1}, new_x))); - assert(vec_isclose(*(Vector *) list_get(shape, 3), vec_add((Vector) {-1, +1}, new_x))); + assert(vec_isclose(*(vector_t *) list_get(shape, 0), vec_add((vector_t) {-1, -1}, new_x))); + assert(vec_isclose(*(vector_t *) list_get(shape, 1), vec_add((vector_t) {+1, -1}, new_x))); + assert(vec_isclose(*(vector_t *) list_get(shape, 2), vec_add((vector_t) {+1, +1}, new_x))); + assert(vec_isclose(*(vector_t *) list_get(shape, 3), vec_add((vector_t) {-1, +1}, new_x))); list_free(shape); body_free(body); } void test_infinite_mass() { - List *shape = list_init(10, free); - Vector *v = malloc(sizeof(*v)); + list_t *shape = list_init(10, free); + vector_t *v = malloc(sizeof(*v)); *v = VEC_ZERO; list_add(shape, v); v = malloc(sizeof(*v)); - *v = (Vector) {+1, 0}; + *v = (vector_t) {+1, 0}; list_add(shape, v); v = malloc(sizeof(*v)); - *v = (Vector) {+1, +1}; + *v = (vector_t) {+1, +1}; list_add(shape, v); v = malloc(sizeof(*v)); - *v = (Vector) {0, +1}; + *v = (vector_t) {0, +1}; list_add(shape, v); - Body *body = body_init(shape, INFINITY, (RGBColor) {0, 0, 0}); - body_set_velocity(body, (Vector) {2, 3}); + body_t *body = body_init(shape, INFINITY, (rgb_color_t) {0, 0, 0}); + body_set_velocity(body, (vector_t) {2, 3}); assert(body_get_mass(body) == INFINITY); - body_add_force(body, (Vector) {1, 1}); + body_add_force(body, (vector_t) {1, 1}); body_tick(body, 1.0); - assert(vec_equal(body_get_velocity(body), (Vector) {2, 3})); - assert(vec_isclose(body_get_centroid(body), (Vector) {2.5, 3.5})); + assert(vec_equal(body_get_velocity(body), (vector_t) {2, 3})); + assert(vec_isclose(body_get_centroid(body), (vector_t) {2.5, 3.5})); body_free(body); } void test_forces() { const double MASS = 10; const double DT = 0.1; - List *shape = list_init(3, free); - Vector *v = malloc(sizeof(*v)); - *v = (Vector) {+1, 0}; + list_t *shape = list_init(3, free); + vector_t *v = malloc(sizeof(*v)); + *v = (vector_t) {+1, 0}; list_add(shape, v); v = malloc(sizeof(*v)); - *v = (Vector) {0, +1}; + *v = (vector_t) {0, +1}; list_add(shape, v); v = malloc(sizeof(*v)); - *v = (Vector) {-1, 0}; + *v = (vector_t) {-1, 0}; list_add(shape, v); - Body *body = body_init(shape, MASS, (RGBColor) {0, 0, 0}); + body_t *body = body_init(shape, MASS, (rgb_color_t) {0, 0, 0}); body_set_centroid(body, VEC_ZERO); - Vector old_velocity = {1, -2}; + vector_t old_velocity = {1, -2}; body_set_velocity(body, old_velocity); - body_add_force(body, (Vector) {MASS * 3, MASS * 4}); - body_add_impulse(body, (Vector) {MASS * 10, MASS * 5}); - body_add_force(body, (Vector) {MASS * 3, MASS * 4}); + body_add_force(body, (vector_t) {MASS * 3, MASS * 4}); + body_add_impulse(body, (vector_t) {MASS * 10, MASS * 5}); + body_add_force(body, (vector_t) {MASS * 3, MASS * 4}); body_tick(body, DT); - Vector new_velocity = - vec_add(old_velocity, (Vector) {10 + 6 * DT, 5 + 8 * DT}); + vector_t new_velocity = + vec_add(old_velocity, (vector_t) {10 + 6 * DT, 5 + 8 * DT}); assert(vec_isclose(body_get_velocity(body), new_velocity)); - Vector new_centroid = - vec_multiply(DT / 2.0, vec_add(old_velocity, new_velocity)); + vector_t new_centroid = + vec_multiply(DT / 2, vec_add(old_velocity, new_velocity)); assert(vec_isclose(body_get_centroid(body), new_centroid)); body_tick(body, DT); assert(vec_isclose( @@ -169,17 +169,17 @@ void test_forces() { } void test_body_remove() { - List *shape = list_init(3, free); - Vector *v = malloc(sizeof(*v)); - *v = (Vector) {+1, 0}; + list_t *shape = list_init(3, free); + vector_t *v = malloc(sizeof(*v)); + *v = (vector_t) {+1, 0}; list_add(shape, v); v = malloc(sizeof(*v)); - *v = (Vector) {0, +1}; + *v = (vector_t) {0, +1}; list_add(shape, v); v = malloc(sizeof(*v)); - *v = (Vector) {-1, 0}; + *v = (vector_t) {-1, 0}; list_add(shape, v); - Body *body = body_init(shape, 1, (RGBColor) {0, 0, 0}); + body_t *body = body_init(shape, 1, (rgb_color_t) {0, 0, 0}); assert(!body_is_removed(body)); body_remove(body); assert(body_is_removed(body)); @@ -189,36 +189,36 @@ void test_body_remove() { } void test_body_info() { - List *shape = list_init(3, free); - Vector *v = malloc(sizeof(*v)); - *v = (Vector) {+1, 0}; + list_t *shape = list_init(3, free); + vector_t *v = malloc(sizeof(*v)); + *v = (vector_t) {+1, 0}; list_add(shape, v); v = malloc(sizeof(*v)); - *v = (Vector) {0, +1}; + *v = (vector_t) {0, +1}; list_add(shape, v); v = malloc(sizeof(*v)); - *v = (Vector) {-1, 0}; + *v = (vector_t) {-1, 0}; list_add(shape, v); int *info = malloc(sizeof(*info)); *info = 123; - Body *body = body_init_with_info(shape, 1, (RGBColor) {0, 0, 0}, info, NULL); + body_t *body = body_init_with_info(shape, 1, (rgb_color_t) {0, 0, 0}, info, NULL); assert(*(int *) body_get_info(body) == 123); body_free(body); free(info); } void test_body_info_freer() { - List *shape = list_init(3, free); - Vector *v = malloc(sizeof(*v)); - *v = (Vector) {+1, 0}; + list_t *shape = list_init(3, free); + vector_t *v = malloc(sizeof(*v)); + *v = (vector_t) {+1, 0}; list_add(shape, v); v = malloc(sizeof(*v)); - *v = (Vector) {0, +1}; + *v = (vector_t) {0, +1}; list_add(shape, v); v = malloc(sizeof(*v)); - *v = (Vector) {-1, 0}; + *v = (vector_t) {-1, 0}; list_add(shape, v); - List *info = list_init(3, free); + list_t *info = list_init(3, free); int *info_elem = malloc(sizeof(*info_elem)); *info_elem = 10; list_add(info, info_elem); @@ -228,8 +228,12 @@ void test_body_info_freer() { info_elem = malloc(sizeof(*info_elem)); *info_elem = 30; list_add(info, info_elem); - Body *body = body_init_with_info( - shape, 1, (RGBColor) {0, 0, 0}, info, (FreeFunc) list_free + body_t *body = body_init_with_info( + shape, + 1, + (rgb_color_t) {0, 0, 0}, + info, + (free_func_t) list_free ); assert(*(int *) list_get(body_get_info(body), 0) == 10); assert(*(int *) list_get(body_get_info(body), 1) == 20); @@ -256,5 +260,4 @@ int main(int argc, char *argv[]) { DO_TEST(test_body_info_freer) puts("body_test PASS"); - return 0; } diff --git a/tests/test_suite_forces.c b/tests/test_suite_forces.c index 39dd352..2cb6db7 100644 --- a/tests/test_suite_forces.c +++ b/tests/test_suite_forces.c @@ -4,19 +4,19 @@ #include <math.h> #include <stdlib.h> -List *make_shape() { - List *shape = list_init(4, free); - Vector *v = malloc(sizeof(*v)); - *v = (Vector) {-1, -1}; +list_t *make_shape() { + list_t *shape = list_init(4, free); + vector_t *v = malloc(sizeof(*v)); + *v = (vector_t) {-1, -1}; list_add(shape, v); v = malloc(sizeof(*v)); - *v = (Vector) {+1, -1}; + *v = (vector_t) {+1, -1}; list_add(shape, v); v = malloc(sizeof(*v)); - *v = (Vector) {+1, +1}; + *v = (vector_t) {+1, +1}; list_add(shape, v); v = malloc(sizeof(*v)); - *v = (Vector) {-1, +1}; + *v = (vector_t) {-1, +1}; list_add(shape, v); return shape; } @@ -28,29 +28,30 @@ void test_spring_sinusoid() { const double A = 3; const double DT = 1e-6; const int STEPS = 1000000; - Scene *scene = scene_init(); - Body *mass = body_init(make_shape(), M, (RGBColor) {0, 0, 0}); - body_set_centroid(mass, (Vector) {A, 0}); + scene_t *scene = scene_init(); + body_t *mass = body_init(make_shape(), M, (rgb_color_t) {0, 0, 0}); + body_set_centroid(mass, (vector_t) {A, 0}); scene_add_body(scene, mass); - Body *anchor = body_init(make_shape(), INFINITY, (RGBColor) {0, 0, 0}); + body_t *anchor = body_init(make_shape(), INFINITY, (rgb_color_t) {0, 0, 0}); scene_add_body(scene, anchor); create_spring(scene, K, mass, anchor); for (int i = 0; i < STEPS; i++) { assert(vec_isclose( body_get_centroid(mass), - (Vector) {A * cos(sqrt(K / M) * i * DT), 0} + (vector_t) {A * cos(sqrt(K / M) * i * DT), 0} )); + assert(vec_equal(body_get_centroid(anchor), VEC_ZERO)); scene_tick(scene, DT); } scene_free(scene); } -double gravity_potential(double G, Body *body1, Body *body2) { - Vector r = vec_subtract(body_get_centroid(body2), body_get_centroid(body1)); +double gravity_potential(double G, body_t *body1, body_t *body2) { + vector_t r = vec_subtract(body_get_centroid(body2), body_get_centroid(body1)); return -G * body_get_mass(body1) * body_get_mass(body2) / sqrt(vec_dot(r, r)); } -double kinetic_energy(Body *body) { - Vector v = body_get_velocity(body); +double kinetic_energy(body_t *body) { + vector_t v = body_get_velocity(body); return body_get_mass(body) * vec_dot(v, v) / 2; } @@ -60,11 +61,11 @@ void test_energy_conservation() { const double G = 1e3; const double DT = 1e-6; const int STEPS = 1000000; - Scene *scene = scene_init(); - Body *mass1 = body_init(make_shape(), M1, (RGBColor) {0, 0, 0}); + scene_t *scene = scene_init(); + body_t *mass1 = body_init(make_shape(), M1, (rgb_color_t) {0, 0, 0}); scene_add_body(scene, mass1); - Body *mass2 = body_init(make_shape(), M2, (RGBColor) {0, 0, 0}); - body_set_centroid(mass2, (Vector) {10, 20}); + body_t *mass2 = body_init(make_shape(), M2, (rgb_color_t) {0, 0, 0}); + body_set_centroid(mass2, (vector_t) {10, 20}); scene_add_body(scene, mass2); create_newtonian_gravity(scene, G, mass1, mass2); double initial_energy = gravity_potential(G, mass1, mass2); @@ -72,24 +73,24 @@ void test_energy_conservation() { assert(body_get_centroid(mass1).x < body_get_centroid(mass2).x); double energy = gravity_potential(G, mass1, mass2) + kinetic_energy(mass1) + kinetic_energy(mass2); - assert(within(1e-5, energy / initial_energy, 1)); + assert(within(1e-4, energy / initial_energy, 1)); scene_tick(scene, DT); } scene_free(scene); } -Body *make_triangle_body() { - List *shape = list_init(3, free); - Vector *v = malloc(sizeof(*v)); - *v = (Vector) {1, 0}; +body_t *make_triangle_body() { + list_t *shape = list_init(3, free); + vector_t *v = malloc(sizeof(*v)); + *v = (vector_t) {1, 0}; list_add(shape, v); v = malloc(sizeof(*v)); - *v = (Vector) {-0.5, +sqrt(3) / 2}; + *v = (vector_t) {-0.5, +sqrt(3) / 2}; list_add(shape, v); v = malloc(sizeof(*v)); - *v = (Vector) {-0.5, -sqrt(3) / 2}; + *v = (vector_t) {-0.5, -sqrt(3) / 2}; list_add(shape, v); - return body_init(shape, 1, (RGBColor) {0, 0, 0}); + return body_init(shape, 1, (rgb_color_t) {0, 0, 0}); } // Tests that destructive collisions remove bodies from the scene @@ -99,19 +100,19 @@ void test_collisions() { const double SEPARATION_AT_COLLISION = 1.5; const int TICKS_TO_COLLISION = 10; - Scene *scene = scene_init(); - Body *body1 = make_triangle_body(); - Vector initial_separation = + scene_t *scene = scene_init(); + body_t *body1 = make_triangle_body(); + vector_t initial_separation = {SEPARATION_AT_COLLISION + V * DT * (TICKS_TO_COLLISION - 0.5), 0}; body_set_centroid(body1, vec_negate(initial_separation)); - body_set_velocity(body1, (Vector) {+V, 0}); + body_set_velocity(body1, (vector_t) {+V, 0}); scene_add_body(scene, body1); - Body *body2 = make_triangle_body(); + body_t *body2 = make_triangle_body(); scene_add_body(scene, body2); - Body *body3 = make_triangle_body(); - body_set_velocity(body3, (Vector) {-V, 0}); + body_t *body3 = make_triangle_body(); + body_set_velocity(body3, (vector_t) {-V, 0}); body_set_centroid(body3, initial_separation); scene_add_body(scene, body3); @@ -134,10 +135,10 @@ void test_collisions() { // Tests that force creators properly register their list of affected bodies. // If they don't, asan will report a heap-use-after-free failure. void test_forces_removed() { - Scene *scene = scene_init(); + scene_t *scene = scene_init(); for (int i = 0; i < 10; i++) { - Body *body = body_init(make_shape(), 1, (RGBColor) {0, 0, 0}); - body_set_centroid(body, (Vector) {i, i}); + body_t *body = body_init(make_shape(), 1, (rgb_color_t) {0, 0, 0}); + body_set_centroid(body, (vector_t) {i, i}); scene_add_body(scene, body); for (int j = 0; j < i; j++) { create_newtonian_gravity(scene, 1, body, scene_get_body(scene, j)); @@ -167,5 +168,4 @@ int main(int argc, char *argv[]) { DO_TEST(test_forces_removed) puts("forces_test PASS"); - return 0; } diff --git a/tests/test_suite_scene.c b/tests/test_suite_scene.c index 01ab24e..4bba824 100644 --- a/tests/test_suite_scene.c +++ b/tests/test_suite_scene.c @@ -5,14 +5,14 @@ #include <stdlib.h> void scene_get_first(void *scene) { - scene_get_body((Scene *) scene, 0); + scene_get_body(scene, 0); } void scene_remove_first(void *scene) { - scene_remove_body((Scene *) scene, 0); + scene_remove_body(scene, 0); } void test_empty_scene() { - Scene *scene = scene_init(); + scene_t *scene = scene_init(); assert(scene_bodies(scene) == 0); for (int i = 0; i < 10; i++) scene_tick(scene, 1); assert(test_assert_fail(scene_get_first, scene)); @@ -20,37 +20,37 @@ void test_empty_scene() { scene_free(scene); } -List *make_shape() { - List *shape = list_init(4, free); - Vector *v = malloc(sizeof(*v)); - *v = (Vector) {-1, -1}; +list_t *make_shape() { + list_t *shape = list_init(4, free); + vector_t *v = malloc(sizeof(*v)); + *v = (vector_t) {-1, -1}; list_add(shape, v); v = malloc(sizeof(*v)); - *v = (Vector) {+1, -1}; + *v = (vector_t) {+1, -1}; list_add(shape, v); v = malloc(sizeof(*v)); - *v = (Vector) {+1, +1}; + *v = (vector_t) {+1, +1}; list_add(shape, v); v = malloc(sizeof(*v)); - *v = (Vector) {-1, +1}; + *v = (vector_t) {-1, +1}; list_add(shape, v); return shape; } void test_scene() { // Build a scene with 3 bodies - Scene *scene = scene_init(); + scene_t *scene = scene_init(); assert(scene_bodies(scene) == 0); - Body *body1 = body_init(make_shape(), 1, (RGBColor) {1, 1, 1}); + body_t *body1 = body_init(make_shape(), 1, (rgb_color_t) {1, 1, 1}); scene_add_body(scene, body1); assert(scene_bodies(scene) == 1); assert(scene_get_body(scene, 0) == body1); - Body *body2 = body_init(make_shape(), 2, (RGBColor) {1, 1, 1}); + body_t *body2 = body_init(make_shape(), 2, (rgb_color_t) {1, 1, 1}); scene_add_body(scene, body2); assert(scene_bodies(scene) == 2); assert(scene_get_body(scene, 0) == body1); assert(scene_get_body(scene, 1) == body2); - Body *body3 = body_init(make_shape(), 3, (RGBColor) {1, 1, 1}); + body_t *body3 = body_init(make_shape(), 3, (rgb_color_t) {1, 1, 1}); scene_add_body(scene, body3); assert(scene_bodies(scene) == 3); assert(scene_get_body(scene, 0) == body1); @@ -58,20 +58,20 @@ void test_scene() { assert(scene_get_body(scene, 2) == body3); // Set the bodies' positions with no velocity and ensure they match - body_set_centroid(body1, (Vector) {1, 1}); - body_set_centroid(body2, (Vector) {2, 2}); - body_set_centroid(body3, (Vector) {3, 3}); + body_set_centroid(body1, (vector_t) {1, 1}); + body_set_centroid(body2, (vector_t) {2, 2}); + body_set_centroid(body3, (vector_t) {3, 3}); scene_tick(scene, 1); - assert(vec_isclose(body_get_centroid(body1), (Vector) {1, 1})); - assert(vec_isclose(body_get_centroid(body2), (Vector) {2, 2})); - assert(vec_isclose(body_get_centroid(body3), (Vector) {3, 3})); - body_set_velocity(body1, (Vector) {+1, 0}); - body_set_velocity(body2, (Vector) {-1, 0}); - body_set_velocity(body3, (Vector) {0, +1}); + assert(vec_isclose(body_get_centroid(body1), (vector_t) {1, 1})); + assert(vec_isclose(body_get_centroid(body2), (vector_t) {2, 2})); + assert(vec_isclose(body_get_centroid(body3), (vector_t) {3, 3})); + body_set_velocity(body1, (vector_t) {+1, 0}); + body_set_velocity(body2, (vector_t) {-1, 0}); + body_set_velocity(body3, (vector_t) {0, +1}); scene_tick(scene, 1); - assert(vec_isclose(body_get_centroid(body1), (Vector) {2, 1})); - assert(vec_isclose(body_get_centroid(body2), (Vector) {1, 2})); - assert(vec_isclose(body_get_centroid(body3), (Vector) {3, 4})); + assert(vec_isclose(body_get_centroid(body1), (vector_t) {2, 1})); + assert(vec_isclose(body_get_centroid(body2), (vector_t) {1, 2})); + assert(vec_isclose(body_get_centroid(body3), (vector_t) {3, 4})); // Try removing the second body scene_remove_body(scene, 1); @@ -83,19 +83,19 @@ void test_scene() { // Tick the remaining bodies scene_tick(scene, 1); - assert(vec_isclose(body_get_centroid(body1), (Vector) {3, 1})); - assert(vec_isclose(body_get_centroid(body3), (Vector) {3, 5})); + assert(vec_isclose(body_get_centroid(body1), (vector_t) {3, 1})); + assert(vec_isclose(body_get_centroid(body3), (vector_t) {3, 5})); scene_free(scene); } // A force creator that moves a body in uniform circular motion about the origin void centripetal_force(void *aux) { - Body *body = (Body *) aux; - Vector v = body_get_velocity(body); - Vector r = body_get_centroid(body); + body_t *body = aux; + vector_t v = body_get_velocity(body); + vector_t r = body_get_centroid(body); assert(isclose(vec_dot(v, r), 0)); - Vector force = + vector_t force = vec_multiply(-body_get_mass(body) * vec_dot(v, v) / vec_dot(r, r), r); body_add_force(body, force); } @@ -105,14 +105,15 @@ void test_force_creator() { const double R = 2; const double DT = 1e-6; const int STEPS = 1000000; - Scene *scene = scene_init(); - Body *body = body_init(make_shape(), 123, (RGBColor) {0, 0, 0}); - body_set_centroid(body, (Vector) {R, 0}); - body_set_velocity(body, (Vector) {0, OMEGA * R}); + scene_t *scene = scene_init(); + body_t *body = body_init(make_shape(), 123, (rgb_color_t) {0, 0, 0}); + vector_t radius = {R, 0}; + body_set_centroid(body, radius); + body_set_velocity(body, (vector_t) {0, OMEGA * R}); scene_add_body(scene, body); scene_add_force_creator(scene, centripetal_force, body, NULL); for (int i = 0; i < STEPS; i++) { - Vector expected_x = vec_rotate((Vector) {R, 0}, OMEGA * i * DT); + vector_t expected_x = vec_rotate(radius, OMEGA * i * DT); assert(vec_within(1e-4, body_get_centroid(body), expected_x)); scene_tick(scene, DT); } @@ -120,29 +121,29 @@ void test_force_creator() { } typedef struct { - Scene *scene; + scene_t *scene; double coefficient; -} ForceAux; +} force_aux_t; // A force creator that applies constant downwards gravity to all bodies in a scene void constant_gravity(void *aux) { - ForceAux *gravity_aux = (ForceAux *) aux; + force_aux_t *gravity_aux = aux; size_t body_count = scene_bodies(gravity_aux->scene); for (size_t i = 0; i < body_count; i++) { - Body *body = scene_get_body(gravity_aux->scene, i); - Vector force = {0, -gravity_aux->coefficient * body_get_mass(body)}; + body_t *body = scene_get_body(gravity_aux->scene, i); + vector_t force = {0, -gravity_aux->coefficient * body_get_mass(body)}; body_add_force(body, force); } } // A force creator that applies drag proportional to v ** 2 to all bodies in a scene void air_drag(void *aux) { - ForceAux *drag_aux = (ForceAux *) aux; + force_aux_t *drag_aux = aux; size_t body_count = scene_bodies(drag_aux->scene); for (size_t i = 0; i < body_count; i++) { - Body *body = scene_get_body(drag_aux->scene, i); - Vector v = body_get_velocity(body); - Vector force = + body_t *body = scene_get_body(drag_aux->scene, i); + vector_t v = body_get_velocity(body); + vector_t force = vec_multiply(-drag_aux->coefficient * sqrt(vec_dot(v, v)), v); body_add_force(body, force); } @@ -153,27 +154,27 @@ void test_force_creator_aux() { const double GRAVITY = 9.8, DRAG = 3; const double DT = 1e-3; const int STEPS = 100000; - Scene *scene = scene_init(); - Body *light = body_init(make_shape(), LIGHT_MASS, (RGBColor) {0, 0, 0}); + scene_t *scene = scene_init(); + body_t *light = body_init(make_shape(), LIGHT_MASS, (rgb_color_t) {0, 0, 0}); scene_add_body(scene, light); - Body *heavy = body_init(make_shape(), HEAVY_MASS, (RGBColor) {0, 0, 0}); + body_t *heavy = body_init(make_shape(), HEAVY_MASS, (rgb_color_t) {0, 0, 0}); scene_add_body(scene, heavy); - ForceAux *gravity_aux = malloc(sizeof(*gravity_aux)); + force_aux_t *gravity_aux = malloc(sizeof(*gravity_aux)); gravity_aux->scene = scene; gravity_aux->coefficient = GRAVITY; scene_add_force_creator(scene, constant_gravity, gravity_aux, free); - ForceAux *drag_aux = malloc(sizeof(*drag_aux)); + force_aux_t *drag_aux = malloc(sizeof(*drag_aux)); drag_aux->scene = scene; drag_aux->coefficient = DRAG; scene_add_force_creator(scene, air_drag, drag_aux, free); for (int i = 0; i < STEPS; i++) scene_tick(scene, DT); assert(vec_isclose( body_get_velocity(light), - (Vector) {0, -sqrt(GRAVITY * LIGHT_MASS / DRAG) + (vector_t) {0, -sqrt(GRAVITY * LIGHT_MASS / DRAG) })); assert(vec_isclose( body_get_velocity(heavy), - (Vector) {0, -sqrt(GRAVITY * HEAVY_MASS / DRAG) + (vector_t) {0, -sqrt(GRAVITY * HEAVY_MASS / DRAG) })); scene_free(scene); } @@ -187,7 +188,7 @@ void test_force_creator_aux() { so it should only be called during the first two ticks. */ void remove_body(void *aux) { - Scene *scene = (Scene *) aux; + scene_t *scene = aux; size_t body_count = scene_bodies(scene); if (body_count > 0) { body_remove(scene_get_body(scene, body_count - 1)); @@ -195,10 +196,10 @@ void remove_body(void *aux) { } typedef struct { int count; - Scene *scene; -} CountAux; + scene_t *scene; +} count_aux_t; void count_calls(void *aux) { - CountAux *count_aux = (CountAux *) aux; + count_aux_t *count_aux = aux; // Every time count_calls() is called, the body count should decrease by 1 assert(scene_bodies(count_aux->scene) == 3 - count_aux->count); // Record that count_calls() was called an additional time @@ -206,23 +207,19 @@ void count_calls(void *aux) { } void test_reaping() { - Scene *scene = scene_init(); + scene_t *scene = scene_init(); for (int i = 0; i < 3; i++) { - scene_add_body(scene, body_init(make_shape(), 1, (RGBColor) {0, 0, 0})); + scene_add_body(scene, body_init(make_shape(), 1, (rgb_color_t) {0, 0, 0})); } - scene_add_bodies_force_creator( - scene, remove_body, scene, list_init(0, NULL), NULL - ); + scene_add_bodies_force_creator(scene, remove_body, scene, list_init(0, NULL), NULL); - CountAux *count_aux = malloc(sizeof(*count_aux)); + count_aux_t *count_aux = malloc(sizeof(*count_aux)); count_aux->count = 0; count_aux->scene = scene; - List *required_bodies = list_init(2, NULL); + list_t *required_bodies = list_init(2, NULL); list_add(required_bodies, scene_get_body(scene, 0)); list_add(required_bodies, scene_get_body(scene, 1)); - scene_add_bodies_force_creator( - scene, count_calls, count_aux, required_bodies, NULL - ); + scene_add_bodies_force_creator(scene, count_calls, count_aux, required_bodies, NULL); while (scene_bodies(scene) > 0) { scene_tick(scene, 1); @@ -249,5 +246,4 @@ int main(int argc, char *argv[]) { DO_TEST(test_reaping) puts("scene_test PASS"); - return 0; } -- GitLab