Tuples are complete

This commit is contained in:
Zachary D. Rowitsch 2020-08-01 23:19:33 -04:00
parent 8d58ce406e
commit bdeb7dc90a
4 changed files with 206 additions and 2 deletions
module_datastructures
test/module_datastructures

@ -4,6 +4,7 @@
#include <assert.h>
#include <stdlib.h>
#include <math.h>
#include <CException.h>
#define VECTOR 0.0
@ -77,8 +78,70 @@ void TUPLES_subtract(TUPLES_Tuple* dest, const TUPLES_Tuple* t1, const TUPLES_Tu
assert(TUPLES_is_vector(dest) || TUPLES_is_point(dest));
}
void TUPLES_negate(TUPLES_Vector* vec) {
assert(vec);
assert(TUPLES_is_vector(vec));
vec->x = 0.0 - vec->x;
vec->y = 0.0 - vec->y;
vec->z = 0.0 - vec->z;
}
void TUPLES_multiply(TUPLES_Tuple* dest, const TUPLES_Tuple* t1, const double mult) {
assert(t1);
assert(dest);
dest->x = t1->x * mult;
dest->y = t1->y * mult;
dest->z = t1->z * mult;
dest->w = t1->w;
assert(TUPLES_is_vector(dest) || TUPLES_is_point(dest));
}
void TUPLES_divide(TUPLES_Tuple* dest, const TUPLES_Tuple* t1, const double div) {
assert(t1);
assert(dest);
dest->x = t1->x / div;
dest->y = t1->y / div;
dest->z = t1->z / div;
dest->w = t1->w;
assert(TUPLES_is_vector(dest) || TUPLES_is_point(dest));
}
double TUPLES_magnitude(const TUPLES_Vector* v) {
assert(v);
assert(TUPLES_is_vector(v));
return sqrt(v->x * v->x + v->y * v->y + v->z * v->z);
}
void TUPLES_normalize(TUPLES_Vector* v) {
assert(v);
assert(TUPLES_is_vector(v));
double magnitude = TUPLES_magnitude(v);
assert(!double_equal(0, magnitude));
v->x = v->x / magnitude;
v->y = v->y / magnitude;
v->z = v->z / magnitude;
}
double TUPLES_dot(const TUPLES_Vector* v1, const TUPLES_Vector* v2) {
assert(v1);
assert(TUPLES_is_vector(v1));
assert(v2);
assert(TUPLES_is_vector(v2));
return v1->x * v2->x + v1->y * v2->y + v1->z * v2->z;
}
void TUPLES_cross(TUPLES_Vector* dest, const TUPLES_Vector* v1, const TUPLES_Vector* v2) {
assert(v1 && v2 && dest);
assert(TUPLES_is_vector(v1) && TUPLES_is_vector(v2));
dest->w = VECTOR;
dest->x = v1->y * v2->z - v1->z * v2->y;
dest->y = v1->z * v2->x - v1->x * v2->z;
dest->z = v1->x * v2->y - v1->y * v2->x;
}
void TUPLES_destroy(TUPLES_Tuple* tuple) {
if (tuple) {
free(tuple);
}
}

@ -68,6 +68,20 @@ void TUPLES_add(TUPLES_Tuple* dest, const TUPLES_Tuple* t1, const TUPLES_Tuple*
*/
void TUPLES_subtract(TUPLES_Tuple* dest, const TUPLES_Tuple* t1, const TUPLES_Tuple* t2);
/**
* Negate a vector
* @param tuple
*/
void TUPLES_negate(TUPLES_Vector* vec);
void TUPLES_multiply(TUPLES_Tuple* dest, const TUPLES_Tuple* t1, const double);
void TUPLES_divide(TUPLES_Tuple* dest, const TUPLES_Tuple* t1, const double);
double TUPLES_magnitude(const TUPLES_Vector* v);
void TUPLES_normalize(TUPLES_Vector* v);
double TUPLES_dot(const TUPLES_Vector* v1, const TUPLES_Vector* v2);
void TUPLES_cross(TUPLES_Vector* dest, const TUPLES_Vector* v1, const TUPLES_Vector* v2);
void TUPLES_destroy(TUPLES_Tuple* tuple);
#endif //MODULE_DATASTRUCTURES_TUPLE

@ -2,5 +2,7 @@ add_executable(module_datastructures_tuples
test_tuples.c)
target_link_libraries(module_datastructures_tuples
module_datastructures
Unity)
Unity
m)
add_test(datastructures_tuples module_datastructures_tuples)

@ -1,6 +1,7 @@
#define UNITY_DOUBLE_PRECISION 0.00001f
#include <unity.h>
#include <stdlib.h>
#include <stdbool.h>
#include <math.h>
#include "tuples.h"
void setUp() {}
@ -92,6 +93,120 @@ void test_subtract_vector_from_point()
TEST_ASSERT_TRUE_MESSAGE(TUPLES_is_point(&a3), "Subtracting vectors should create a vector");
}
void test_negate_vector()
{
TUPLES_Vector v;
TUPLES_init_vector(&v, 1, -2, 3);
TUPLES_negate(&v);
TEST_ASSERT_EQUAL_DOUBLE(-1, v.x);
TEST_ASSERT_EQUAL_DOUBLE(2, v.y);
TEST_ASSERT_EQUAL_DOUBLE(-3, v.z);
}
void test_multiply_tuple_by_scalar()
{
TUPLES_Vector v;
TUPLES_init_vector(&v, 1, -2, 3);
TUPLES_multiply(&v, &v, 3.5);
TEST_ASSERT_EQUAL_DOUBLE(3.5, v.x);
TEST_ASSERT_EQUAL_DOUBLE(-7, v.y);
TEST_ASSERT_EQUAL_DOUBLE(10.5, v.z);
}
void test_multiply_tuple_by_fraction()
{
TUPLES_Vector v;
TUPLES_init_vector(&v, 1, -2, 3);
TUPLES_multiply(&v, &v, 0.5);
TEST_ASSERT_EQUAL_DOUBLE(0.5, v.x);
TEST_ASSERT_EQUAL_DOUBLE(-1, v.y);
TEST_ASSERT_EQUAL_DOUBLE(1.5, v.z);
}
void test_divide_tuple_by_scalar()
{
TUPLES_Vector v;
TUPLES_init_vector(&v, 1, -2, 3);
TUPLES_divide(&v, &v, 2);
TEST_ASSERT_EQUAL_DOUBLE(0.5, v.x);
TEST_ASSERT_EQUAL_DOUBLE(-1, v.y);
TEST_ASSERT_EQUAL_DOUBLE(1.5, v.z);
}
void test_a_magnitude(double x, double y, double z, double expected_magnitude)
{
TUPLES_Vector v;
char str[80];
double magnitude;
TUPLES_init_vector(&v, x, y, z);
magnitude = TUPLES_magnitude(&v);
sprintf(str, "Vector(%f, %f, %f)", v.x, v.y, v.z);
TEST_ASSERT_EQUAL_DOUBLE_MESSAGE(expected_magnitude, magnitude, str);
}
void test_magnitude()
{
test_a_magnitude(1, 0, 0, 1);
test_a_magnitude(0, 1, 0, 1);
test_a_magnitude(0, 0, 1, 1);
test_a_magnitude(1, 2, 3, sqrt(14));
test_a_magnitude(-1, -2, -3, sqrt(14));
}
void test_simple_normalize()
{
TUPLES_Vector v;
TUPLES_init_vector(&v, 4, 0, 0);
TUPLES_normalize(&v);
TEST_ASSERT_EQUAL_DOUBLE(1, v.x);
TEST_ASSERT_EQUAL_DOUBLE(0, v.y);
TEST_ASSERT_EQUAL_DOUBLE(0, v.z);
}
void test_less_simple_normalize()
{
TUPLES_Vector v;
TUPLES_init_vector(&v, 1, 2, 3);
TUPLES_normalize(&v);
TEST_ASSERT_EQUAL_DOUBLE(0.26726, v.x);
TEST_ASSERT_EQUAL_DOUBLE(0.53452, v.y);
TEST_ASSERT_EQUAL_DOUBLE(0.80178, v.z);
}
void test_magnitude_normalized_vector()
{
TUPLES_Vector v;
TUPLES_init_vector(&v, 15, 25, 37);
TUPLES_normalize(&v);
TEST_ASSERT_EQUAL_DOUBLE(1, TUPLES_magnitude(&v));
}
void test_simple_dot_product()
{
TUPLES_Vector v1, v2;
TUPLES_init_vector(&v1, 1, 2, 3);
TUPLES_init_vector(&v2, 2, 3, 4);
double dot = TUPLES_dot(&v1, &v2);
TEST_ASSERT_EQUAL_DOUBLE(20, dot);
}
void test_cross_product()
{
TUPLES_Vector result, v1, v2;
TUPLES_init_vector(&v1, 1, 2, 3);
TUPLES_init_vector(&v2, 2, 3, 4);
TUPLES_cross(&result, &v1, &v2);
TEST_ASSERT_EQUAL_DOUBLE(-1, result.x);
TEST_ASSERT_EQUAL_DOUBLE(2, result.y);
TEST_ASSERT_EQUAL_DOUBLE(-1, result.z);
TUPLES_cross(&result, &v2, &v1);
TEST_ASSERT_EQUAL_DOUBLE(1, result.x);
TEST_ASSERT_EQUAL_DOUBLE(-2, result.y);
TEST_ASSERT_EQUAL_DOUBLE(1, result.z);
}
int main(void)
{
UNITY_BEGIN();
@ -103,6 +218,16 @@ int main(void)
RUN_TEST(test_subtract_points);
RUN_TEST(test_subtract_vectors);
RUN_TEST(test_subtract_vector_from_point);
RUN_TEST(test_negate_vector);
RUN_TEST(test_multiply_tuple_by_scalar);
RUN_TEST(test_multiply_tuple_by_fraction);
RUN_TEST(test_divide_tuple_by_scalar);
RUN_TEST(test_magnitude);
RUN_TEST(test_simple_normalize);
RUN_TEST(test_less_simple_normalize);
RUN_TEST(test_magnitude_normalized_vector);
RUN_TEST(test_simple_dot_product);
RUN_TEST(test_cross_product);
return UNITY_END();
}