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