Mercurial > MadButterfly
comparison src/shape_path.c @ 1134:bd0cfb8666b8
Pass testcases for _calc_center() of shape_path.c.
author | Thinker K.F. Li <thinker@codemud.net> |
---|---|
date | Sun, 19 Dec 2010 17:56:23 +0800 |
parents | eca737d33a18 |
children | 9f2b5a1a0d84 |
comparison
equal
deleted
inserted
replaced
1133:bc619172bd2c | 1134:bd0cfb8666b8 |
---|---|
46 (x)++; \ | 46 (x)++; \ |
47 } | 47 } |
48 #define OK 0 | 48 #define OK 0 |
49 #define ERR -1 | 49 #define ERR -1 |
50 #define PI 3.1415926535897931 | 50 #define PI 3.1415926535897931 |
51 #define FRAC_PI 51472 | 51 #define FRAC_PI ((int)(PI * FRACTION_ONE)) |
52 | 52 |
53 #define SWAP(x, y) do { x ^= y; y ^= x; x ^= y; } while(0) | 53 #define SWAP(x, y) do { x ^= y; y ^= x; x ^= y; } while(0) |
54 #define MAX(x, y) (((x) > (y))? (x): (y)) | 54 #define MAX(x, y) (((x) > (y))? (x): (y)) |
55 #define MIN(x, y) (((x) > (y))? (y): (x)) | 55 #define MIN(x, y) (((x) > (y))? (y): (x)) |
56 #define IS_NEGATIVE(x) ((x) & ~(-1 >> 1)) | 56 #define IS_NEGATIVE(x) ((x) < 0) |
57 | 57 |
58 #ifdef UNITTEST | 58 #ifdef UNITTEST |
59 #undef rdman_man_shape | 59 #undef rdman_man_shape |
60 #define rdman_man_shape(x, y) | 60 #define rdman_man_shape(x, y) |
61 | 61 |
77 /* ============================================================ | 77 /* ============================================================ |
78 * Implement arc in path. | 78 * Implement arc in path. |
79 */ | 79 */ |
80 #if 1 | 80 #if 1 |
81 | 81 |
82 #include <stdint.h> | |
82 #include "precomputed.h" | 83 #include "precomputed.h" |
83 | 84 |
84 #define ABS(x) (((x) > 0)? (x): -(x)) | 85 #define ABS(x) (((x) > 0)? (x): -(x)) |
86 #define FRACTION_ONE (1 << FRACTION_SHIFT) | |
85 | 87 |
86 /*! \brief Compute the small slope of a vector. | 88 /*! \brief Compute the small slope of a vector. |
87 * | 89 * |
88 * A small slope is based on absolute value of x-axis and y-axis. | 90 * A small slope is based on absolute value of x-axis and y-axis. |
89 * And use smaller one of absolute values as divisor. | 91 * And use smaller one of absolute values as divisor. |
112 int left, right, v; | 114 int left, right, v; |
113 | 115 |
114 left = 0; | 116 left = 0; |
115 right = SLOPE_TAB_SZ - 1; | 117 right = SLOPE_TAB_SZ - 1; |
116 while(left <= right) { | 118 while(left <= right) { |
117 v = (left + right) >> 1; | 119 v = (left + right) / 2; |
118 if(slope < slope_tab[v]) | 120 if(slope < slope_tab[v]) |
119 right = v - 1; | 121 right = v - 1; |
120 else | 122 else |
121 left = v + 1; | 123 left = v + 1; |
122 } | 124 } |
124 return v; | 126 return v; |
125 } | 127 } |
126 | 128 |
127 static int | 129 static int |
128 _vector_len(int x, int y) { | 130 _vector_len(int x, int y) { |
129 int _x, _y; | 131 int64_t _x, _y; |
130 int slope; | 132 int64_t slope; |
131 int slope_index; | 133 int64_t slope_index; |
132 int radius; | 134 int64_t radius; |
133 | 135 |
134 _x = ABS(x); | 136 _x = ABS(x); |
135 _y = ABS(y); | 137 _y = ABS(y); |
136 | 138 |
137 if(_x > _y) { | 139 if(_x > _y) { |
141 } else { | 143 } else { |
142 slope = (_x << FRACTION_SHIFT) / _y; | 144 slope = (_x << FRACTION_SHIFT) / _y; |
143 slope_index = _find_slope_index(slope); | 145 slope_index = _find_slope_index(slope); |
144 radius = _y * vector_len_factor_tab[slope_index]; | 146 radius = _y * vector_len_factor_tab[slope_index]; |
145 } | 147 } |
148 radius = radius / FRACTION_ONE; | |
146 | 149 |
147 return radius; | 150 return radius; |
148 } | 151 } |
149 | 152 |
150 /*! \brief Find index of an arc-to-radius ratio in arc_radius_ratio_tab. | 153 /*! \brief Find index of an arc-to-radius ratio in arc_radius_ratio_tab. |
156 int left, right, v; | 159 int left, right, v; |
157 | 160 |
158 left = 0; | 161 left = 0; |
159 right = ARC_RADIUS_RATIO_TAB_SZ - 1; | 162 right = ARC_RADIUS_RATIO_TAB_SZ - 1; |
160 while(left <= right) { | 163 while(left <= right) { |
161 v = (left + right) >> 1; | 164 v = (left + right) / 2; |
162 if(arc_radius_ratio < arc_radius_ratio_tab[v]) | 165 if(arc_radius_ratio < arc_radius_ratio_tab[v]) |
163 right = v - 1; | 166 right = v - 1; |
164 else | 167 else |
165 left = v + 1; | 168 left = v + 1; |
166 } | 169 } |
192 * radius of rx direction equivlant to ry direction. It extends the | 195 * radius of rx direction equivlant to ry direction. It extends the |
193 * direction of short one. | 196 * direction of short one. |
194 */ | 197 */ |
195 static void | 198 static void |
196 _compute_extend_unit_vector(int rx, int ry, int x_rotate, | 199 _compute_extend_unit_vector(int rx, int ry, int x_rotate, |
197 int *ext_unit_x, int *ext_unit_y) { | 200 int64_t *ext_unit_x, int64_t *ext_unit_y) { |
198 int extend_dir; | 201 int extend_dir; |
199 int extend_phase; | 202 int extend_phase; |
200 int extend_index; | 203 int extend_index; |
201 int extend_sin, extend_cos; | 204 int extend_sin, extend_cos; |
202 /* Change sign of x, y values accroding phase of the vector. */ | 205 /* Change sign of x, y values accroding phase of the vector. */ |
210 else | 213 else |
211 extend_dir = x_rotate; | 214 extend_dir = x_rotate; |
212 extend_dir %= FRAC_PI * 2; | 215 extend_dir %= FRAC_PI * 2; |
213 extend_phase = extend_dir / (FRAC_PI >> 1); | 216 extend_phase = extend_dir / (FRAC_PI >> 1); |
214 | 217 |
215 extend_index = (extend_dir % (FRAC_PI >> 4)) * SIN_TAB_SZ / | 218 extend_index = (extend_dir % (FRAC_PI >> 1)) * SIN_TAB_SZ / |
216 (FRAC_PI >> 4); | 219 (FRAC_PI >> 1); |
217 if(extend_phase & 0x1) /* half-phases 1,3 */ | 220 if(extend_phase & 0x1) /* half-phases 1,3 */ |
218 extend_index = SIN_TAB_SZ - extend_index - 1; | 221 extend_index = SIN_TAB_SZ - extend_index - 1; |
219 | 222 |
220 extend_sin = sin_tab[extend_index]; | 223 extend_sin = sin_tab[extend_index]; |
221 extend_cos = sin_tab[SIN_TAB_SZ - extend_index - 1]; | 224 extend_cos = sin_tab[SIN_TAB_SZ - extend_index - 1]; |
223 signs = sin_cos_signs_tab[extend_phase]; | 226 signs = sin_cos_signs_tab[extend_phase]; |
224 *ext_unit_x = signs[0]? -extend_cos: extend_cos; | 227 *ext_unit_x = signs[0]? -extend_cos: extend_cos; |
225 *ext_unit_y = signs[1]? -extend_sin: extend_sin; | 228 *ext_unit_y = signs[1]? -extend_sin: extend_sin; |
226 } | 229 } |
227 | 230 |
228 static int | 231 static void |
229 _calc_center_i(int x0, int y0, | 232 _get_center_ref_shift(int arc_x, int arc_y, int large, int sweep, |
230 int x, int y, | 233 int slope_index, |
231 int rx, int ry, | 234 int64_t *shift_cx, int64_t *shift_cy) { |
232 int x_rotate, | 235 int _shift_cx, _shift_cy; |
233 int large, int sweep, | |
234 int *cx, int *cy) { | |
235 int radius; | |
236 int ext_unit_y, ext_unit_x; /* x and y value of unit vector on | |
237 * extend direction */ | |
238 int arc_x, arc_y; | |
239 int radius_ref_ratio; | |
240 int arc_radius_factor; | |
241 int stat = 0; | 236 int stat = 0; |
242 int slope, slope_index; | |
243 int shift_cx, shift_cy; | |
244 int center_shift_factor; | |
245 static int negatives[4] = {0, 1, 1, 0}; | |
246 /* Change sign of shift-x/y accroding sign of arc_x, arc_y, | 237 /* Change sign of shift-x/y accroding sign of arc_x, arc_y, |
247 * large and sweep. | 238 * large and sweep. |
248 */ | 239 */ |
249 static int shift_signs_tab[16][2] = { | 240 static int shift_signs_tab[16][2] = { |
250 /* -x,-y +x,-y -x,+y +x,+y */ | 241 /* +x,+y -x,+y +x,-y -x,-y */ |
251 {0, 0}, {0, 1}, {1, 0}, {1, 1}, /* small, negative-angle */ | 242 {1, 1}, {0, 1}, {1, 0}, {0, 0}, /* small, negative-angle */ |
252 {1, 1}, {1, 0}, {0, 1}, {0, 0}, /* large, negative-angle */ | 243 {0, 0}, {1, 0}, {0, 1}, {1, 1}, /* large, negative-angle */ |
253 {1, 1}, {1, 0}, {0, 1}, {0, 0}, /* small, positive-angle */ | 244 {0, 0}, {1, 0}, {0, 1}, {1, 1}, /* small, positive-angle */ |
254 {0, 0}, {0, 1}, {1, 0}, {1, 1} /* large, positive-angle */ | 245 {1, 1}, {0, 1}, {1, 0}, {0, 0} /* large, positive-angle */ |
255 }; | 246 }; |
256 int extend_len; | 247 |
257 int extend_x, extend_y; | 248 _shift_cx = center_shift_tab[slope_index][0]; |
258 | 249 _shift_cy = center_shift_tab[slope_index][1]; |
259 arc_x = x - x0; | 250 if(ABS(arc_x) <= ABS(arc_y)) { |
260 arc_y = y - y0; | 251 SWAP(_shift_cx, _shift_cy); |
261 | 252 _shift_cx = -_shift_cx; |
262 if(arc_x == 0 && arc_y == 0) { | 253 _shift_cy = -_shift_cy; |
263 *cx = x0; | |
264 *cy = y0; | |
265 return OK; | |
266 } | 254 } |
267 | |
268 /* Translate arc to the coordinate that extend rx or ry to the | |
269 * equivlant size as another. It translate the ellipse to a | |
270 * circle. | |
271 */ | |
272 radius = MAX(rx, ry); | |
273 _compute_extend_unit_vector(rx, ry, x_rotate, &ext_unit_x, &ext_unit_y); | |
274 | |
275 extend_len = (arc_x * ext_unit_x + arc_y * ext_unit_y) >> FRACTION_SHIFT; | |
276 extend_len = extend_len * MAX(rx, ry) / MIN(rx, ry) - | |
277 (1 << FRACTION_SHIFT); | |
278 extend_x = ext_unit_x * extend_len; | |
279 extend_y = ext_unit_y * extend_len; | |
280 | |
281 arc_x += extend_x; | |
282 arc_y += extend_y; | |
283 | |
284 /* Find range index of slope. */ | |
285 slope = _small_slope(arc_x, arc_y); | |
286 slope_index = _find_slope_index(slope); | |
287 | |
288 /* Compute shift factor for the ratio of arc to radius */ | |
289 arc_radius_factor = _get_arc_radius_shift_factor(arc_x, arc_y, radius); | |
290 | |
291 /* Compute ratio of radius to reference radius */ | |
292 radius_ref_ratio = radius >> REF_RADIUS_SHIFT; | |
293 | |
294 /* Compute x/y-shift of center range index according | |
295 * slope_index, radius_ref_ratio and arc_radius_factor. | |
296 */ | |
297 center_shift_factor = radius_ref_ratio * arc_radius_factor; | |
298 center_shift_factor = center_shift_factor >> FRACTION_SHIFT; | |
299 shift_cx = (center_shift_tab[slope_index][0] * center_shift_factor) >> | |
300 FRACTION_SHIFT; | |
301 shift_cy = (center_shift_tab[slope_index][1] * center_shift_factor) >> | |
302 FRACTION_SHIFT; | |
303 if(ABS(arc_x) <= ABS(arc_y)) | |
304 SWAP(shift_cx, shift_cy); | |
305 | 255 |
306 if(IS_NEGATIVE(arc_x)) | 256 if(IS_NEGATIVE(arc_x)) |
307 stat |= 0x1; | 257 stat |= 0x1; |
308 if(IS_NEGATIVE(arc_y)) | 258 if(IS_NEGATIVE(arc_y)) |
309 stat |= 0x2; | 259 stat |= 0x2; |
310 if(large) | 260 if(large) |
311 stat |= 0x4; | 261 stat |= 0x4; |
312 if(sweep) | 262 if(sweep) |
313 stat |= 0x8; | 263 stat |= 0x8; |
314 if(shift_signs_tab[stat][0]) | 264 if(shift_signs_tab[stat][0]) |
315 shift_cx = -shift_cx; | 265 _shift_cx = -_shift_cx; |
316 if(shift_signs_tab[stat][1]) | 266 if(shift_signs_tab[stat][1]) |
317 shift_cy = -shift_cy; | 267 _shift_cy = -_shift_cy; |
318 | 268 |
319 shift_cx += arc_x >> 2; | 269 *shift_cx = _shift_cx; |
320 shift_cy += arc_y >> 2; | 270 *shift_cy = _shift_cy; |
271 } | |
272 | |
273 static int | |
274 _calc_center_i(int x0, int y0, | |
275 int x, int y, | |
276 int rx, int ry, | |
277 int x_rotate, | |
278 int large, int sweep, | |
279 int *cx, int *cy) { | |
280 int64_t radius; | |
281 int64_t ext_unit_y, ext_unit_x; /* x and y value of unit vector on | |
282 * extend direction */ | |
283 int64_t arc_x, arc_y; | |
284 int64_t radius_ref_ratio; | |
285 int64_t arc_radius_factor; | |
286 int64_t slope, slope_index; | |
287 int64_t shift_cx, shift_cy; | |
288 int64_t center_shift_factor; | |
289 static int negatives[4] = {0, 1, 1, 0}; | |
290 int64_t extend_len; | |
291 int64_t extend_x, extend_y; | |
292 | |
293 ASSERT(rx >= 0 && ry >= 0); | |
294 | |
295 arc_x = x - x0; | |
296 arc_y = y - y0; | |
297 | |
298 if(arc_x == 0 && arc_y == 0) { | |
299 *cx = x0; | |
300 *cy = y0; | |
301 return OK; | |
302 } | |
303 | |
304 /* Translate arc to the coordinate that extend rx or ry to the | |
305 * equivlant size as another. It translate the ellipse to a | |
306 * circle. | |
307 */ | |
308 radius = MAX(rx, ry); | |
309 _compute_extend_unit_vector(rx, ry, x_rotate, &ext_unit_x, &ext_unit_y); | |
310 | |
311 extend_len = (arc_x * ext_unit_x + arc_y * ext_unit_y) / FRACTION_ONE; | |
312 extend_len = extend_len * (MAX(rx, ry) - MIN(rx, ry)) / MIN(rx, ry); | |
313 extend_x = ext_unit_x * extend_len / FRACTION_ONE; | |
314 extend_y = ext_unit_y * extend_len / FRACTION_ONE; | |
315 | |
316 arc_x += extend_x; | |
317 arc_y += extend_y; | |
318 | |
319 /* Find range index of slope. */ | |
320 slope = _small_slope(arc_x, arc_y); | |
321 slope_index = _find_slope_index(slope); | |
322 | |
323 /* Compute shift factor for the ratio of arc to radius */ | |
324 arc_radius_factor = _get_arc_radius_shift_factor(arc_x, arc_y, radius); | |
325 | |
326 /* Compute ratio of radius to reference radius */ | |
327 radius_ref_ratio = radius >> REF_RADIUS_SHIFT; | |
328 | |
329 /* Compute x/y-shift of center range index according | |
330 * slope_index, radius_ref_ratio and arc_radius_factor. | |
331 */ | |
332 _get_center_ref_shift(arc_x, arc_y, large, sweep, slope_index, | |
333 &shift_cx, &shift_cy); | |
334 center_shift_factor = radius_ref_ratio * arc_radius_factor; | |
335 center_shift_factor = center_shift_factor / FRACTION_ONE; | |
336 shift_cx = shift_cx * center_shift_factor / FRACTION_ONE; | |
337 shift_cy = shift_cy * center_shift_factor / FRACTION_ONE; | |
338 | |
339 shift_cx += arc_x / 2; | |
340 shift_cy += arc_y / 2; | |
321 | 341 |
322 /* translate shift_cx/cy back to original coordinate */ | 342 /* translate shift_cx/cy back to original coordinate */ |
323 extend_len = (shift_cx * ext_unit_x + shift_cy * ext_unit_y) | 343 extend_len = (shift_cx * ext_unit_x + shift_cy * ext_unit_y) / |
324 >> FRACTION_SHIFT; | 344 FRACTION_ONE; |
325 extend_len = extend_len - extend_len * MIN(rx, ry) / MAX(rx, ry); | 345 extend_len = extend_len * (MAX(rx, ry) - MIN(rx, ry)) / MAX(rx, ry); |
326 extend_x = (ext_unit_x * extend_len) >> FRACTION_SHIFT; | 346 extend_x = ext_unit_x * extend_len / FRACTION_ONE; |
327 extend_y = (ext_unit_y * extend_len) >> FRACTION_SHIFT; | 347 extend_y = ext_unit_y * extend_len / FRACTION_ONE; |
328 shift_cx = shift_cx - extend_x; | 348 shift_cx = shift_cx - extend_x; |
329 shift_cy = shift_cy - extend_y; | 349 shift_cy = shift_cy - extend_y; |
330 | 350 |
331 /* get center */ | 351 /* get center */ |
332 *cx = x0 + shift_cx; | 352 *cx = x0 + shift_cx; |
342 int large, int sweep, | 362 int large, int sweep, |
343 co_aix *cx, co_aix *cy) { | 363 co_aix *cx, co_aix *cy) { |
344 int cx_i, cy_i; | 364 int cx_i, cy_i; |
345 int r; | 365 int r; |
346 | 366 |
347 r = _calc_center_i(x0 * (1 << FRACTION_SHIFT), y0 * (1 << FRACTION_SHIFT), | 367 r = _calc_center_i(x0 * FRACTION_ONE, y0 * FRACTION_ONE, |
348 x * (1 << FRACTION_SHIFT), y * (1 << FRACTION_SHIFT), | 368 x * FRACTION_ONE, y * FRACTION_ONE, |
349 rx * (1 << FRACTION_SHIFT), ry * (1 << FRACTION_SHIFT), | 369 rx * FRACTION_ONE, ry * FRACTION_ONE, |
350 x_rotate * (1 << FRACTION_SHIFT), | 370 x_rotate * FRACTION_ONE, |
351 large, sweep, &cx_i, &cy_i); | 371 large, sweep, &cx_i, &cy_i); |
352 *cx = cx_i; | 372 *cx = (co_aix)cx_i / FRACTION_ONE; |
353 *cy = cy_i; | 373 *cy = (co_aix)cy_i / FRACTION_ONE; |
354 return r; | 374 return r; |
355 } | 375 } |
356 | 376 |
357 #else | 377 #else |
358 /*! \brief Calculate center of the ellipse of an arc. | 378 /*! \brief Calculate center of the ellipse of an arc. |
1381 CU_ASSERT(pnts[11] == 154); | 1401 CU_ASSERT(pnts[11] == 154); |
1382 | 1402 |
1383 sh_path_free((shape_t *)path); | 1403 sh_path_free((shape_t *)path); |
1384 } | 1404 } |
1385 | 1405 |
1406 void test_small_slope(void) { | |
1407 co_aix x, y; | |
1408 co_aix slope; | |
1409 co_aix r; | |
1410 | |
1411 x = 135.3; | |
1412 y = 149.6; | |
1413 r = (co_aix)_small_slope(x * FRACTION_ONE, | |
1414 y * FRACTION_ONE) / | |
1415 FRACTION_ONE; | |
1416 | |
1417 slope = MIN(x, y) / MAX(x, y); | |
1418 CU_ASSERT(((r - slope) / slope) < 0.01 && | |
1419 ((r - slope) / slope) > -0.01); | |
1420 } | |
1421 | |
1422 void test_find_slope_index(void) { | |
1423 co_aix slope; | |
1424 int idx; | |
1425 co_aix r; | |
1426 | |
1427 slope = 0.754; | |
1428 idx = _find_slope_index(slope * FRACTION_ONE); | |
1429 r = (co_aix)slope_tab[idx] / FRACTION_ONE; | |
1430 CU_ASSERT((r / slope) < 1.01 && | |
1431 (r / slope) > 0.99); | |
1432 } | |
1433 | |
1434 void test_vector_len(void) { | |
1435 co_aix x, y; | |
1436 co_aix len; | |
1437 co_aix r; | |
1438 int rlen; | |
1439 | |
1440 x = 397; | |
1441 y = 449; | |
1442 len = sqrt(x * x + y * y); | |
1443 rlen = _vector_len(x * FRACTION_ONE, | |
1444 y * FRACTION_ONE); | |
1445 r = (co_aix)rlen / (1 <<FRACTION_SHIFT); | |
1446 CU_ASSERT((r / len) < 1.01 && | |
1447 (r / len) > 0.99); | |
1448 | |
1449 x = 357; | |
1450 y = 224; | |
1451 len = sqrt(x * x + y * y); | |
1452 rlen = _vector_len(x * FRACTION_ONE, | |
1453 y * FRACTION_ONE); | |
1454 r = (co_aix)rlen / FRACTION_ONE; | |
1455 CU_ASSERT((r / len) < 1.01 && | |
1456 (r / len) > 0.99); | |
1457 } | |
1458 | |
1459 void test_find_arc_radius(void) { | |
1460 co_aix ratio; | |
1461 int idx; | |
1462 co_aix r; | |
1463 | |
1464 ratio = 0.732; | |
1465 idx = _find_arc_radius(ratio * FRACTION_ONE); | |
1466 r = (co_aix)arc_radius_ratio_tab[idx] / FRACTION_ONE; | |
1467 CU_ASSERT((r / ratio) < 1.01 && | |
1468 (r / ratio) > 0.99); | |
1469 } | |
1470 | |
1471 void test_get_arc_radius_shift_factor(void) { | |
1472 co_aix arc_x, arc_y, radius; | |
1473 co_aix factor; | |
1474 int rfactor; | |
1475 co_aix r; | |
1476 | |
1477 arc_x = 30.5; | |
1478 arc_y = 10.3; | |
1479 radius = 90.3; | |
1480 factor = sqrt(radius * radius - (arc_x * arc_x + arc_y * arc_y) / 4) / | |
1481 radius; | |
1482 rfactor = _get_arc_radius_shift_factor(arc_x * FRACTION_ONE, | |
1483 arc_y * FRACTION_ONE, | |
1484 radius * FRACTION_ONE); | |
1485 r = (co_aix)rfactor / FRACTION_ONE; | |
1486 CU_ASSERT((r / factor) < 1.01 && | |
1487 (r / factor) > 0.99); | |
1488 | |
1489 arc_x = 30.5; | |
1490 arc_y = 70.3; | |
1491 radius = 190.3; | |
1492 factor = sqrt(radius * radius - (arc_x * arc_x + arc_y * arc_y) / 4) / | |
1493 radius; | |
1494 rfactor = _get_arc_radius_shift_factor(arc_x * FRACTION_ONE, | |
1495 arc_y * FRACTION_ONE, | |
1496 radius * FRACTION_ONE); | |
1497 r = (co_aix)rfactor / FRACTION_ONE; | |
1498 CU_ASSERT((r / factor) < 1.01 && | |
1499 (r / factor) > 0.99); | |
1500 } | |
1501 | |
1502 void test_compute_extend_unit_vector(void) { | |
1503 co_aix rx, ry; | |
1504 co_aix x_rotate; | |
1505 co_aix unit_x, unit_y; | |
1506 co_aix runit_x, runit_y; | |
1507 int64_t ext_unit_x, ext_unit_y; | |
1508 | |
1509 rx = 200; | |
1510 ry = 153; | |
1511 x_rotate = PI * 30 / 180; | |
1512 unit_x = cos(PI * 90 / 180 + x_rotate); | |
1513 unit_y = sin(PI * 90 / 180 + x_rotate); | |
1514 _compute_extend_unit_vector(rx * FRACTION_ONE, ry * FRACTION_ONE, | |
1515 x_rotate * FRACTION_ONE, | |
1516 &ext_unit_x, &ext_unit_y); | |
1517 runit_x = (co_aix)ext_unit_x / FRACTION_ONE; | |
1518 runit_y = (co_aix)ext_unit_y / FRACTION_ONE; | |
1519 CU_ASSERT((runit_x / unit_x) < 1.01 && | |
1520 (runit_x / unit_x) > 0.99); | |
1521 CU_ASSERT((runit_y / unit_y) < 1.01 && | |
1522 (runit_y / unit_y) > 0.99); | |
1523 | |
1524 rx = 200; | |
1525 ry = 153; | |
1526 x_rotate = PI * 158 / 180; | |
1527 unit_x = cos(PI * 90 / 180 + x_rotate); | |
1528 unit_y = sin(PI * 90 / 180 + x_rotate); | |
1529 _compute_extend_unit_vector(rx * FRACTION_ONE, ry * FRACTION_ONE, | |
1530 x_rotate * FRACTION_ONE, | |
1531 &ext_unit_x, &ext_unit_y); | |
1532 runit_x = (co_aix)ext_unit_x / FRACTION_ONE; | |
1533 runit_y = (co_aix)ext_unit_y / FRACTION_ONE; | |
1534 CU_ASSERT((runit_x / unit_x) < 1.01 && | |
1535 (runit_x / unit_x) > 0.99); | |
1536 CU_ASSERT((runit_y / unit_y) < 1.01 && | |
1537 (runit_y / unit_y) > 0.99); | |
1538 | |
1539 rx = 100; | |
1540 ry = 153; | |
1541 x_rotate = PI * 158 / 180; | |
1542 unit_x = cos(x_rotate); | |
1543 unit_y = sin(x_rotate); | |
1544 _compute_extend_unit_vector(rx * FRACTION_ONE, ry * FRACTION_ONE, | |
1545 x_rotate * FRACTION_ONE, | |
1546 &ext_unit_x, &ext_unit_y); | |
1547 runit_x = (co_aix)ext_unit_x / FRACTION_ONE; | |
1548 runit_y = (co_aix)ext_unit_y / FRACTION_ONE; | |
1549 CU_ASSERT((runit_x / unit_x) < 1.01 && | |
1550 (runit_x / unit_x) > 0.99); | |
1551 CU_ASSERT((runit_y / unit_y) < 1.01 && | |
1552 (runit_y / unit_y) > 0.99); | |
1553 } | |
1554 | |
1555 void test_get_center_ref_shift(void) { | |
1556 co_aix slope; | |
1557 int slope_index; | |
1558 co_aix arc_len; | |
1559 co_aix arc_x, arc_y; | |
1560 int large, sweep; | |
1561 co_aix shift_x, shift_y; | |
1562 co_aix r_x, r_y; | |
1563 int64_t rshift_x, rshift_y; | |
1564 | |
1565 arc_x = 311; | |
1566 arc_y = 210; | |
1567 large = 0; /* small arc */ | |
1568 sweep = 1; /* positive sweep */ | |
1569 arc_len = sqrt(arc_x * arc_x + arc_y * arc_y); | |
1570 shift_x = arc_y / arc_len * (1 << REF_RADIUS_SHIFT); | |
1571 shift_y = arc_x / arc_len * (1 << REF_RADIUS_SHIFT); | |
1572 if((arc_x < 0) ^ (arc_y < 0)) | |
1573 /* exactly one of arc_x and arc_y is negative */ | |
1574 shift_y = -shift_y; | |
1575 else | |
1576 shift_x = -shift_x; | |
1577 slope = MIN(ABS(arc_x), ABS(arc_y)) / MAX(ABS(arc_x), ABS(arc_y)); | |
1578 slope_index = _find_slope_index(slope * FRACTION_ONE); | |
1579 _get_center_ref_shift(arc_x * FRACTION_ONE, arc_y * FRACTION_ONE, | |
1580 large, sweep, | |
1581 slope_index, | |
1582 &rshift_x, &rshift_y); | |
1583 r_x = (co_aix)rshift_x / FRACTION_ONE; | |
1584 r_y = (co_aix)rshift_y / FRACTION_ONE; | |
1585 CU_ASSERT((r_x / shift_x) < 1.01 && | |
1586 (r_x / shift_x) > 0.99); | |
1587 CU_ASSERT((r_y / shift_y) < 1.01 && | |
1588 (r_y / shift_y) > 0.99); | |
1589 | |
1590 arc_x = 311; | |
1591 arc_y = 210; | |
1592 large = 1; /* small arc */ | |
1593 sweep = 1; /* positive sweep */ | |
1594 arc_len = sqrt(arc_x * arc_x + arc_y * arc_y); | |
1595 shift_x = -arc_y / arc_len * (1 << REF_RADIUS_SHIFT); | |
1596 shift_y = -arc_x / arc_len * (1 << REF_RADIUS_SHIFT); | |
1597 if((arc_x < 0) ^ (arc_y < 0)) | |
1598 /* exactly one of arc_x and arc_y is negative */ | |
1599 shift_y = -shift_y; | |
1600 else | |
1601 shift_x = -shift_x; | |
1602 slope = MIN(ABS(arc_x), ABS(arc_y)) / MAX(ABS(arc_x), ABS(arc_y)); | |
1603 slope_index = _find_slope_index(slope * FRACTION_ONE); | |
1604 _get_center_ref_shift(arc_x * FRACTION_ONE, arc_y * FRACTION_ONE, | |
1605 large, sweep, | |
1606 slope_index, | |
1607 &rshift_x, &rshift_y); | |
1608 r_x = (co_aix)rshift_x / FRACTION_ONE; | |
1609 r_y = (co_aix)rshift_y / FRACTION_ONE; | |
1610 CU_ASSERT((r_x / shift_x) < 1.01 && | |
1611 (r_x / shift_x) > 0.99); | |
1612 CU_ASSERT((r_y / shift_y) < 1.01 && | |
1613 (r_y / shift_y) > 0.99); | |
1614 } | |
1615 | |
1386 void test_calc_center(void) { | 1616 void test_calc_center(void) { |
1617 co_aix x0, y0, x, y; | |
1618 co_aix rx, ry, x_rotate; | |
1619 int large, sweep; | |
1620 co_aix cx, cy; | |
1621 co_aix angle_start, angle_stop; | |
1622 co_aix rcx, rcy; | |
1623 co_aix _x, _y; | |
1624 | |
1625 #define ELLIPSE_POINT(angle, point_x, point_y) \ | |
1626 do { \ | |
1627 _x = rx * cos(angle); \ | |
1628 _y = ry * sin(angle); \ | |
1629 point_x = _x * cos(x_rotate) - _y * sin(x_rotate) + cx; \ | |
1630 point_y = _x * sin(x_rotate) + _y * cos(x_rotate) + cy; \ | |
1631 } while(0) | |
1632 #define CENTER_TEST() \ | |
1633 do { \ | |
1634 _calc_center(x0, y0, x, y, rx, ry, x_rotate, \ | |
1635 0, 1, &rcx, &rcy); \ | |
1636 CU_ASSERT((cx - rcx) <= 2 && (cx - rcx) >= -2); \ | |
1637 CU_ASSERT((cy - rcy) <= 2 && (cy - rcy) >= -2); \ | |
1638 _calc_center(x0, y0, x, y, rx, ry, x_rotate, \ | |
1639 1, 0, &rcx, &rcy); \ | |
1640 CU_ASSERT((cx - rcx) <= 2 && (cx - rcx) >= -2); \ | |
1641 CU_ASSERT((cy - rcy) <= 2 && (cy - rcy) >= -2); \ | |
1642 _calc_center(x, y, x0, y0, rx, ry, x_rotate, \ | |
1643 0, 0, &rcx, &rcy); \ | |
1644 CU_ASSERT((cx - rcx) <= 2 && (cx - rcx) >= -2); \ | |
1645 CU_ASSERT((cy - rcy) <= 2 && (cy - rcy) >= -2); \ | |
1646 _calc_center(x, y, x0, y0, rx, ry, x_rotate, \ | |
1647 1, 1, &rcx, &rcy); \ | |
1648 CU_ASSERT((cx - rcx) <= 2 && (cx - rcx) >= -2); \ | |
1649 CU_ASSERT((cy - rcy) <= 2 && (cy - rcy) >= -2); \ | |
1650 } while(0) | |
1651 | |
1652 cx = 135; | |
1653 cy = 254; | |
1654 rx = 200; | |
1655 ry = 170; | |
1656 x_rotate = PI * 20 / 180; | |
1657 angle_start = PI * 55 / 180; | |
1658 angle_stop = PI * 97 / 180; | |
1659 | |
1660 ELLIPSE_POINT(angle_start, x0, y0); | |
1661 ELLIPSE_POINT(angle_stop, x, y); | |
1662 CENTER_TEST(); | |
1387 } | 1663 } |
1388 | 1664 |
1389 void test_spaces_head_tail(void) { | 1665 void test_spaces_head_tail(void) { |
1390 sh_path_t *path; | 1666 sh_path_t *path; |
1391 redraw_man_t rdman; | 1667 redraw_man_t rdman; |
1401 CU_pSuite suite; | 1677 CU_pSuite suite; |
1402 | 1678 |
1403 suite = CU_add_suite("Suite_shape_path", NULL, NULL); | 1679 suite = CU_add_suite("Suite_shape_path", NULL, NULL); |
1404 CU_ADD_TEST(suite, test_rdman_shape_path_new); | 1680 CU_ADD_TEST(suite, test_rdman_shape_path_new); |
1405 CU_ADD_TEST(suite, test_path_transform); | 1681 CU_ADD_TEST(suite, test_path_transform); |
1682 CU_ADD_TEST(suite, test_small_slope); | |
1683 CU_ADD_TEST(suite, test_find_slope_index); | |
1684 CU_ADD_TEST(suite, test_vector_len); | |
1685 CU_ADD_TEST(suite, test_find_arc_radius); | |
1686 CU_ADD_TEST(suite, test_get_arc_radius_shift_factor); | |
1687 CU_ADD_TEST(suite, test_compute_extend_unit_vector); | |
1688 CU_ADD_TEST(suite, test_get_center_ref_shift); | |
1406 CU_ADD_TEST(suite, test_calc_center); | 1689 CU_ADD_TEST(suite, test_calc_center); |
1407 | 1690 |
1408 return suite; | 1691 return suite; |
1409 } | 1692 } |
1410 | 1693 |