Mercurial > MadButterfly
changeset 1:b5c0162ccf69
Coordination tranforming
author | Thinker K.F. Li <thinker@branda.to> |
---|---|
date | Wed, 23 Jul 2008 13:57:33 +0800 |
parents | 5aca939dbfbe |
children | 31402929c587 |
files | src/Makefile src/coord.c src/testcase.c |
diffstat | 3 files changed, 182 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/Makefile Wed Jul 23 13:57:33 2008 +0800 @@ -0,0 +1,22 @@ +SRCS = coord.c +TESTCASE_OBJS = ${SRCS:C/(.*)\.c/testcase-\1.o/g} +CFLAGS=-I/usr/local/include + +all: testcase + +testcase: testcase.o $(TESTCASE_OBJS) + $(CC) $(LDFLAGS) -o $@ $(.ALLSRC) -L/usr/local/lib -lcunit + +.for i in $(TESTCASE_OBJS) +${i}: ${i:C/testcase-(.*).o/\1.c/} + $(CC) $(CFLAGS) -DUNITTEST -g -c -o $@ $(.ALLSRC) +.endfor + +testcase.o: testcase.c + $(CC) $(CFLAGS) -c $(.ALLSRC) + +clean: + for i in *.o *~$(BINS); do \ + echo "delete $$i"; \ + rm -f $$i; \ + done
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/coord.c Wed Jul 23 13:57:33 2008 +0800 @@ -0,0 +1,141 @@ +#include <stdio.h> +#include <string.h> + +typedef struct coord { + int seq; + float matrix[6]; + float aggr_matrix[6]; + struct coord *parent; + struct coord *children, *sibling; +} coord_t; + +static void mul_matrix(float *m1, float *m2, float *dst) { + dst[0] = m1[0] * m2[0] + m1[1] * m2[3]; + dst[1] = m1[0] * m2[1] + m1[1] * m2[4]; + dst[2] = m1[0] * m2[2] + m1[1] * m2[5] + m1[2]; + dst[3] = m1[3] * m2[0] + m1[4] * m2[3]; + dst[4] = m1[3] * m2[1] + m1[4] * m2[4]; + dst[5] = m1[3] * m2[2] + m1[4] * m2[5] + m1[5]; +} + +static void compute_transform_function(coord_t *visit) { + if(visit->parent) + mul_matrix(visit->parent->aggr_matrix, + visit->matrix, visit->aggr_matrix); + else + memcpy(visit->aggr_matrix, visit->matrix, sizeof(visit->matrix)); +} + +/*! \brief Update aggregate matrices of elements under a sub-tree. + * + * A subtree is specified by the root of it. All elements in the subtree + * are effected by that changes of matrix of the subtree root. + */ +void update_aggr_matrix(coord_t *start) { + coord_t *visit, *child, *next; + + compute_transform_function(start); + + visit = start; + while(visit) { + child = visit->children; + while(child) { + compute_transform_function(child); + child = child->sibling; + } + + if(visit->children) + visit = visit->children; + else if(visit->sibling) + visit = visit->sibling; + else { + next = NULL; + while(visit->parent && visit->parent != start) { + visit = visit->parent; + if(visit->sibling) { + next = visit->sibling; + break; + } + } + visit = next; + } + } +} + +void coord_init(coord_t *co, coord_t *parent) { + memset(co, 0, sizeof(coord_t)); + if(parent) { + co->parent = parent; + co->sibling = parent->children; + parent->children = co; + } + co->matrix[0] = 1; + co->matrix[4] = 1; +} + +#ifdef UNITTEST + +#include <CUnit/Basic.h> + +void test_update_aggr_matrix(void) { + coord_t elms[6]; + + coord_init(elms, NULL); + coord_init(elms + 1, elms); + coord_init(elms + 2, elms); + coord_init(elms + 3, elms + 1); + coord_init(elms + 4, elms + 1); + coord_init(elms + 5, elms + 2); + + /* | 2 -1 0 | + * | 0 1 0 | + * | 0 0 1 | + */ + elms[0].matrix[0] = 2; + elms[0].matrix[1] = -1; + + /* | 1 3 0 | + * | 5 1 0 | + * | 0 0 1 | + */ + elms[1].matrix[1] = 3; + elms[1].matrix[3] = 5; + + update_aggr_matrix(elms); + + /* | -3 5 0 | + * | 5 1 0 | + * | 0 0 1 | + */ + CU_ASSERT(elms[3].aggr_matrix[0] == -3); + CU_ASSERT(elms[3].aggr_matrix[1] == 5); + CU_ASSERT(elms[3].aggr_matrix[2] == 0); + CU_ASSERT(elms[3].aggr_matrix[3] == 5); + CU_ASSERT(elms[3].aggr_matrix[4] == 1); + CU_ASSERT(elms[3].aggr_matrix[5] == 0); + + CU_ASSERT(elms[4].aggr_matrix[0] == -3); + CU_ASSERT(elms[4].aggr_matrix[1] == 5); + CU_ASSERT(elms[4].aggr_matrix[2] == 0); + CU_ASSERT(elms[4].aggr_matrix[3] == 5); + CU_ASSERT(elms[4].aggr_matrix[4] == 1); + CU_ASSERT(elms[4].aggr_matrix[5] == 0); + + CU_ASSERT(elms[5].aggr_matrix[0] == 2); + CU_ASSERT(elms[5].aggr_matrix[1] == -1); + CU_ASSERT(elms[5].aggr_matrix[2] == 0); + CU_ASSERT(elms[5].aggr_matrix[3] == 0); + CU_ASSERT(elms[5].aggr_matrix[4] == 1); + CU_ASSERT(elms[5].aggr_matrix[5] == 0); +} + +CU_pSuite get_coord_suite(void) { + CU_pSuite suite; + + suite = CU_add_suite("Suite_coord", NULL, NULL); + CU_ADD_TEST(suite, test_update_aggr_matrix); + + return suite; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/testcase.c Wed Jul 23 13:57:33 2008 +0800 @@ -0,0 +1,19 @@ +#include <CUnit/Basic.h> + +extern CU_pSuite get_coord_suite(void); + +int +main(int argc, char * const argv[]) { + CU_pSuite suite; + + if(CU_initialize_registry() != CUE_SUCCESS) + return CU_get_error(); + + get_coord_suite(); + + CU_basic_set_mode(CU_BRM_VERBOSE); + CU_basic_run_tests(); + CU_cleanup_registry(); + + return CU_get_error(); +}