Mercurial > MadButterfly
comparison src/coord.c @ 1067:7b4e80ab671a openvg
merge from default branch
author | Thinker K.F. Li <thinker@codemud.net> |
---|---|
date | Wed, 01 Dec 2010 12:25:56 +0800 |
parents | 586e50f82c1f |
children |
comparison
equal
deleted
inserted
replaced
630:bd18951b51d5 | 1067:7b4e80ab671a |
---|---|
1 // -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 4; -*- | |
2 // vim: sw=4:ts=8:sts=4 | |
1 /*! \brief Implement coordination tranform mechanism. | 3 /*! \brief Implement coordination tranform mechanism. |
2 * \file | 4 * \file |
3 * This file implements coordination transforming for containers. | 5 * This file implements coordination transforming for containers. |
4 */ | 6 */ |
5 #include <stdio.h> | 7 #include <stdio.h> |
26 } | 28 } |
27 | 29 |
28 void matrix_mul(co_aix *m1, co_aix *m2, co_aix *dst) { | 30 void matrix_mul(co_aix *m1, co_aix *m2, co_aix *dst) { |
29 co_aix *_dst = dst; | 31 co_aix *_dst = dst; |
30 co_aix fake_dst[6]; | 32 co_aix fake_dst[6]; |
31 | 33 |
32 if(m1 == dst || m2 == dst) | 34 if(m1 == dst || m2 == dst) |
33 _dst = fake_dst; | 35 _dst = fake_dst; |
34 | 36 |
35 mul_matrix(m1, m2, _dst); | 37 mul_matrix(m1, m2, _dst); |
36 | 38 |
37 if(m1 == dst || m2 == dst) { | 39 if(m1 == dst || m2 == dst) { |
38 dst[0] = fake_dst[0]; | 40 dst[0] = fake_dst[0]; |
39 dst[1] = fake_dst[1]; | 41 dst[1] = fake_dst[1]; |
58 } | 60 } |
59 | 61 |
60 /*! \brief Compute aggregated transform matrix. | 62 /*! \brief Compute aggregated transform matrix. |
61 * | 63 * |
62 * Base on parent's aggregated matrix if it is existed, or use transform | 64 * Base on parent's aggregated matrix if it is existed, or use transform |
63 * matrix as aggregated matrix. | 65 * matrix as aggregated matrix. |
64 */ | 66 */ |
65 static void compute_transform_function(coord_t *visit) { | 67 static void compute_transform_function(coord_t *visit) { |
66 if(!coord_is_root(visit)) | 68 if(!coord_is_root(visit)) |
67 mul_matrix(visit->parent->aggr_matrix, | 69 mul_matrix(visit->parent->aggr_matrix, |
68 visit->matrix, visit->aggr_matrix); | 70 visit->matrix, visit->aggr_matrix); |
80 */ | 82 */ |
81 static void compute_transform_function_cached(coord_t *visit) { | 83 static void compute_transform_function_cached(coord_t *visit) { |
82 co_aix *p_matrix; | 84 co_aix *p_matrix; |
83 co_aix cache_p_matrix[6]; | 85 co_aix cache_p_matrix[6]; |
84 co_aix cache_scale_x, cache_scale_y; | 86 co_aix cache_scale_x, cache_scale_y; |
85 | 87 |
86 if(!coord_is_root(visit)) { | 88 if(!coord_is_root(visit)) { |
87 p_matrix = coord_get_aggr_matrix(visit->parent); | 89 p_matrix = coord_get_aggr_matrix(visit->parent); |
88 cache_scale_x = | 90 cache_scale_x = |
89 sqrtf(p_matrix[0] * p_matrix[0] + p_matrix[3] * p_matrix[3]); | 91 sqrtf(p_matrix[0] * p_matrix[0] + p_matrix[3] * p_matrix[3]); |
90 cache_scale_y = | 92 cache_scale_y = |
114 } | 116 } |
115 | 117 |
116 void compute_reverse(co_aix *orig, co_aix *reverse) { | 118 void compute_reverse(co_aix *orig, co_aix *reverse) { |
117 co_aix working[6]; | 119 co_aix working[6]; |
118 co_aix factor; | 120 co_aix factor; |
119 | 121 |
120 #define VEC_MAC(src, factor, dst) \ | 122 #define VEC_MAC(src, factor, dst) \ |
121 do { \ | 123 do { \ |
122 (dst)[0] += (src)[0] * (factor); \ | 124 (dst)[0] += (src)[0] * (factor); \ |
123 (dst)[1] += (src)[1] * (factor); \ | 125 (dst)[1] += (src)[1] * (factor); \ |
124 (dst)[2] += (src)[2] * (factor); \ | 126 (dst)[2] += (src)[2] * (factor); \ |
128 reverse[1] = 0; | 130 reverse[1] = 0; |
129 reverse[2] = 0; | 131 reverse[2] = 0; |
130 reverse[3] = 0; | 132 reverse[3] = 0; |
131 reverse[4] = 1; | 133 reverse[4] = 1; |
132 reverse[5] = 0; | 134 reverse[5] = 0; |
133 | 135 |
134 memcpy(working, orig, sizeof(co_aix) * 6); | 136 memcpy(working, orig, sizeof(co_aix) * 6); |
135 | 137 |
136 factor = -working[3] / working[0]; | 138 factor = -working[3] / working[0]; |
137 VEC_MAC(working, factor, working + 3); | 139 VEC_MAC(working, factor, working + 3); |
138 VEC_MAC(reverse, factor, reverse + 3); | 140 VEC_MAC(reverse, factor, reverse + 3); |
142 VEC_MAC(reverse + 3, factor, reverse); | 144 VEC_MAC(reverse + 3, factor, reverse); |
143 | 145 |
144 reverse[2] = -working[2]; | 146 reverse[2] = -working[2]; |
145 reverse[5] = -working[5]; | 147 reverse[5] = -working[5]; |
146 | 148 |
147 reverse[0] /= working[0]; | 149 factor = 1 / working[0]; |
148 reverse[1] /= working[0]; | 150 reverse[0] *= factor; |
149 reverse[2] /= working[0]; | 151 reverse[1] *= factor; |
150 reverse[3] /= working[4]; | 152 reverse[2] *= factor; |
151 reverse[4] /= working[4]; | 153 factor = 1 / working[4]; |
152 reverse[5] /= working[4]; | 154 reverse[3] *= factor; |
155 reverse[4] *= factor; | |
156 reverse[5] *= factor; | |
153 } | 157 } |
154 | 158 |
155 /*! \brief Update aggregate matrices of elements under a sub-tree. | 159 /*! \brief Update aggregate matrices of elements under a sub-tree. |
156 * | 160 * |
157 * A subtree is specified by the root of it. All elements in the subtree | 161 * A subtree is specified by the root of it. All elements in the subtree |
241 */ | 245 */ |
242 coord_t *preorder_coord_subtree(coord_t *root, coord_t *last) { | 246 coord_t *preorder_coord_subtree(coord_t *root, coord_t *last) { |
243 coord_t *next = NULL; | 247 coord_t *next = NULL; |
244 | 248 |
245 ASSERT(last != NULL); | 249 ASSERT(last != NULL); |
246 | 250 |
247 if((!(last->flags & COF_SKIP_TRIVAL)) && | 251 if((!(last->flags & COF_SKIP_TRIVAL)) && |
248 STAILQ_HEAD(last->children)) { | 252 STAILQ_HEAD(last->children)) { |
249 next = STAILQ_HEAD(last->children); | 253 next = STAILQ_HEAD(last->children); |
250 if(!(next->flags & COF_SKIP_TRIVAL)) | 254 if(!(next->flags & COF_SKIP_TRIVAL)) |
251 return next; | 255 return next; |
268 coord_t *postorder_coord_subtree(coord_t *root, coord_t *last) { | 272 coord_t *postorder_coord_subtree(coord_t *root, coord_t *last) { |
269 coord_t *next; | 273 coord_t *next; |
270 | 274 |
271 if(root == last) | 275 if(root == last) |
272 return NULL; | 276 return NULL; |
273 | 277 |
274 if(last == NULL) { | 278 if(last == NULL) { |
275 /* Go most left leaf. */ | 279 /* Go most left leaf. */ |
276 next = root; | 280 next = root; |
277 while(STAILQ_HEAD(next->children)) | 281 while(STAILQ_HEAD(next->children)) |
278 next = STAILQ_HEAD(next->children); | 282 next = STAILQ_HEAD(next->children); |
321 elms[1].matrix[3] = 5; | 325 elms[1].matrix[3] = 5; |
322 | 326 |
323 update_aggr_matrix(elms); | 327 update_aggr_matrix(elms); |
324 | 328 |
325 /* | -3 5 0 | | 329 /* | -3 5 0 | |
326 * | 5 1 0 | | 330 * | 5 1 0 | |
327 * | 0 0 1 | | 331 * | 0 0 1 | |
328 */ | 332 */ |
329 CU_ASSERT(elms[3].aggr_matrix[0] == -3); | 333 CU_ASSERT(elms[3].aggr_matrix[0] == -3); |
330 CU_ASSERT(elms[3].aggr_matrix[1] == 5); | 334 CU_ASSERT(elms[3].aggr_matrix[1] == 5); |
331 CU_ASSERT(elms[3].aggr_matrix[2] == 0); | 335 CU_ASSERT(elms[3].aggr_matrix[2] == 0); |