Tuples are complete
This commit is contained in:
parent
8d58ce406e
commit
bdeb7dc90a
@ -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();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user