diff --git a/build.sh b/build.sh index 845725e..321af16 100755 --- a/build.sh +++ b/build.sh @@ -2,4 +2,4 @@ set -xe -gcc -g -Wall -Wextra -o main main.c +gcc -g -Wall -Wextra -o main main.c -lm diff --git a/gmath.h b/gmath.h index 54eb2c0..f9a7dfc 100644 --- a/gmath.h +++ b/gmath.h @@ -1,9 +1,11 @@ #ifndef GMATH_H #define GMATH_H +#define PI 3.1415926535 #define GMAT_AT(m, r, c) ((m).mat[(r) * (m).width + (c)]) #include +#include typedef struct { float *mat; @@ -11,6 +13,8 @@ typedef struct { short height; } Matrix; +typedef enum { GMatrix_Rotation_X, GMatrix_Rotation_Y, GMatrix_Rotation_Z} GMatrix_Rotation; + Matrix GMatrix_malloc(short width, short height); void GMatrix_fill(Matrix mat, float var); @@ -26,6 +30,10 @@ void GMatrix_sub(Matrix dest, const Matrix mat); void GMatrix_scal(Matrix dest, int val); void GMatrix_prod(Matrix dest, const Matrix mat1, const Matrix mat2); +void GMatrix_vector_scale(Matrix dest, float x, float y, float z); +void GMatrix_vector_translate(Matrix dest, float x, float y, float z); +void GMatrix_vector_rotate(Matrix dest, float d, GMatrix_Rotation r); + #endif #ifdef GMATH_IMPLEMENTATION @@ -35,6 +43,11 @@ void GMatrix_prod(Matrix dest, const Matrix mat1, const Matrix mat2); #define GMATH_MALLOC malloc #endif +#ifndef GMATH_MEMCPY +#include +#define GMATH_MEMCPY memcpy +#endif + #ifndef GMATH_ASSERT #include #define GMATH_ASSERT(n) assert((n)) @@ -107,10 +120,61 @@ void GMatrix_prod(Matrix dest, const Matrix mat1, const Matrix mat2){ for(int column = 0; column < dest.width; column++){ GMAT_AT(dest, row, column) = 0; for(int i=0; i < mat1.width; i++){ - GMAT_AT(dest, row, column) += GMAT_AT(mat1, row, i) * GMAT_AT(mat2, column, i); + GMAT_AT(dest, row, column) += GMAT_AT(mat1, row, i) * GMAT_AT(mat2, i,column); } } } } +void GMatrix_vector_scale(Matrix dest, float x, float y, float z){ + Matrix trans = GMatrix_unit(4); + GMAT_AT(trans, 0, 0) = x; + GMAT_AT(trans, 1, 1) = y; + GMAT_AT(trans, 2, 2) = z; + Matrix ret = {.mat=GMATH_MALLOC(sizeof(float)*dest.width*dest.height), .width=dest.width, .height=dest.height}; + GMATH_MEMCPY(ret.mat, dest.mat, sizeof(float)*dest.width*dest.height); + GMatrix_prod(dest, ret, trans); + free(ret.mat); +} + +void GMatrix_vector_translate(Matrix dest, float x, float y, float z){ + Matrix trans = GMatrix_unit(4); + GMAT_AT(trans, 0, 3) = x; + GMAT_AT(trans, 1, 3) = y; + GMAT_AT(trans, 2, 3) = z; + Matrix ret = {.mat=GMATH_MALLOC(sizeof(float)*dest.width*dest.height), .width=dest.width, .height=dest.height}; + GMATH_MEMCPY(ret.mat, dest.mat, sizeof(float)*dest.width*dest.height); + GMatrix_prod(dest, ret, trans); + free(ret.mat); +} + + +void GMatrix_vector_rotate(Matrix dest, float d, GMatrix_Rotation r){ + Matrix trans = GMatrix_unit(4); + switch (r) { + case GMatrix_Rotation_X: + GMAT_AT(trans, 1, 1) = cosf(d); + GMAT_AT(trans, 1, 2) = -sinf(d); + GMAT_AT(trans, 2, 1) = sinf(d); + GMAT_AT(trans, 2, 2) = cosf(d); + break; + case GMatrix_Rotation_Y: + GMAT_AT(trans, 0, 0) = cosf(d); + GMAT_AT(trans, 0, 2) = sinf(d); + GMAT_AT(trans, 2, 0) = -sinf(d); + GMAT_AT(trans, 2, 2) = cosf(d); + break; + case GMatrix_Rotation_Z: + GMAT_AT(trans, 0, 0) = cosf(d); + GMAT_AT(trans, 0, 1) = -sinf(d); + GMAT_AT(trans, 1, 0) = sinf(d); + GMAT_AT(trans, 1, 1) = cosf(d); + break; + } + Matrix ret = {.mat=GMATH_MALLOC(sizeof(float)*dest.width*dest.height), .width=dest.width, .height=dest.height}; + GMATH_MEMCPY(ret.mat, dest.mat, sizeof(float)*dest.width*dest.height); + GMatrix_prod(dest, ret, trans); + free(ret.mat); +} + #endif diff --git a/main.c b/main.c index 2df777a..1e3c7bb 100644 --- a/main.c +++ b/main.c @@ -2,49 +2,26 @@ #include "gmath.h" #include + int main(void) { - float matrix_shape[] = { - 1, 2, 3, - 4, 5, 6, - 7, 8, 9, - }; - - float matrix_shape2[] = { - 9, 8, 7, - 6, 5, 4, - 3, 2, 1, - }; - - float matrix_shape3[] = { - 3, - 4, - 5, - 1, - }; - - /* Matrix mat[3] = { */ - /* {matrix_shape, 3, 3}, */ - /* {matrix_shape2, 3, 3}, */ - /* GMatrix_malloc(3,3), */ - /* }; */ - - Matrix mat[3] = { - GMatrix_unit(4), - {matrix_shape3, 1, 4}, - GMatrix_malloc(1, 4), - }; - - GMAT_AT(mat[0], 0, 3) = 1; - GMAT_AT(mat[0], 1, 3) = 1; - GMAT_AT(mat[0], 2, 3) = 1; - - - GMatrix_print(mat[0]); + Matrix trans = GMatrix_unit(4); + GMatrix_print(trans); printf("----------------------------------------\n"); - GMatrix_print(mat[1]); - GMatrix_prod(mat[2], mat[0], mat[1]); + GMatrix_vector_translate(trans, 2, 3 ,4); + GMatrix_print(trans); + printf("----------------------------------------\n"); + + GMatrix_vector_scale(trans, 2, 1 ,0.5); + GMatrix_print(trans); + printf("----------------------------------------\n"); + + GMatrix_vector_rotate(trans, PI* 0.5, GMatrix_Rotation_X); + GMatrix_print(trans); + printf("----------------------------------------\n"); + + GMatrix_vector_rotate(trans, PI, GMatrix_Rotation_Y); + GMatrix_print(trans); printf("----------------------------------------\n"); - GMatrix_print(mat[2]); }