changeset 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 bc619172bd2c
children 45fcbd54e873
files src/shape_path.c tools/gen_precomputed_tabs.py
diffstat 2 files changed, 358 insertions(+), 75 deletions(-) [+]
line wrap: on
line diff
--- a/src/shape_path.c	Sun Dec 19 00:02:31 2010 +0800
+++ b/src/shape_path.c	Sun Dec 19 17:56:23 2010 +0800
@@ -48,12 +48,12 @@
 #define OK 0
 #define ERR -1
 #define PI 3.1415926535897931
-#define FRAC_PI 51472
+#define FRAC_PI ((int)(PI * FRACTION_ONE))
 
 #define SWAP(x, y) do { x ^= y; y ^= x; x ^= y; } while(0)
 #define MAX(x, y) (((x) > (y))? (x): (y))
 #define MIN(x, y) (((x) > (y))? (y): (x))
-#define IS_NEGATIVE(x) ((x) & ~(-1 >> 1))
+#define IS_NEGATIVE(x) ((x) < 0)
 
 #ifdef UNITTEST
 #undef rdman_man_shape
@@ -79,9 +79,11 @@
  */
 #if 1
 
+#include <stdint.h>
 #include "precomputed.h"
 
 #define ABS(x) (((x) > 0)? (x): -(x))
+#define FRACTION_ONE (1 << FRACTION_SHIFT)
 
 /*! \brief Compute the small slope of a vector.
  *
@@ -114,7 +116,7 @@
     left = 0;
     right = SLOPE_TAB_SZ - 1;
     while(left <= right) {
-	v = (left + right) >> 1;
+	v = (left + right) / 2;
 	if(slope < slope_tab[v])
 	    right = v - 1;
 	else
@@ -126,10 +128,10 @@
 
 static int
 _vector_len(int x, int y) {
-    int _x, _y;
-    int slope;
-    int slope_index;
-    int radius;
+    int64_t _x, _y;
+    int64_t slope;
+    int64_t slope_index;
+    int64_t radius;
     
     _x = ABS(x);
     _y = ABS(y);
@@ -143,6 +145,7 @@
 	slope_index = _find_slope_index(slope);
 	radius = _y * vector_len_factor_tab[slope_index];
     }
+    radius = radius / FRACTION_ONE;
     
     return radius;
 }
@@ -158,7 +161,7 @@
     left = 0;
     right = ARC_RADIUS_RATIO_TAB_SZ - 1;
     while(left <= right) {
-	v = (left + right) >> 1;
+	v = (left + right) / 2;
 	if(arc_radius_ratio < arc_radius_ratio_tab[v])
 	    right = v - 1;
 	else
@@ -194,7 +197,7 @@
  */
 static void
 _compute_extend_unit_vector(int rx, int ry, int x_rotate,
-			    int *ext_unit_x, int *ext_unit_y) {
+			    int64_t *ext_unit_x, int64_t *ext_unit_y) {
     int extend_dir;
     int extend_phase;
     int extend_index;
@@ -212,8 +215,8 @@
     extend_dir %= FRAC_PI * 2;
     extend_phase = extend_dir / (FRAC_PI >> 1);
     
-    extend_index = (extend_dir % (FRAC_PI >> 4)) * SIN_TAB_SZ /
-	(FRAC_PI >> 4);
+    extend_index = (extend_dir % (FRAC_PI >> 1)) * SIN_TAB_SZ /
+	(FRAC_PI >> 1);
     if(extend_phase & 0x1)	/* half-phases 1,3 */
 	extend_index = SIN_TAB_SZ - extend_index - 1;
     
@@ -225,6 +228,48 @@
     *ext_unit_y = signs[1]? -extend_sin: extend_sin;
 }
 
+static void
+_get_center_ref_shift(int arc_x, int arc_y, int large, int sweep,
+		      int slope_index,
+		      int64_t *shift_cx, int64_t *shift_cy) {
+    int _shift_cx, _shift_cy;
+    int stat = 0;
+    /* Change sign of shift-x/y accroding sign of arc_x, arc_y,
+     * large and sweep.
+     */
+    static int shift_signs_tab[16][2] = {
+	/* +x,+y   -x,+y   +x,-y   -x,-y */
+	{1, 1}, {0, 1}, {1, 0}, {0, 0}, /* small, negative-angle */
+	{0, 0}, {1, 0}, {0, 1}, {1, 1}, /* large, negative-angle */
+	{0, 0}, {1, 0}, {0, 1}, {1, 1}, /* small, positive-angle */
+	{1, 1}, {0, 1}, {1, 0}, {0, 0}  /* large, positive-angle */
+    };
+    
+    _shift_cx = center_shift_tab[slope_index][0];
+    _shift_cy = center_shift_tab[slope_index][1];
+    if(ABS(arc_x) <= ABS(arc_y)) {
+	SWAP(_shift_cx, _shift_cy);
+	_shift_cx = -_shift_cx;
+	_shift_cy = -_shift_cy;
+    }
+    
+    if(IS_NEGATIVE(arc_x))
+	stat |= 0x1;
+    if(IS_NEGATIVE(arc_y))
+	stat |= 0x2;
+    if(large)
+	stat |= 0x4;
+    if(sweep)
+	stat |= 0x8;
+    if(shift_signs_tab[stat][0])
+	_shift_cx = -_shift_cx;
+    if(shift_signs_tab[stat][1])
+	_shift_cy = -_shift_cy;
+
+    *shift_cx = _shift_cx;
+    *shift_cy = _shift_cy;
+}
+
 static int
 _calc_center_i(int x0, int y0,
 	       int x, int y,
@@ -232,29 +277,20 @@
 	       int x_rotate,
 	       int large, int sweep,
 	       int *cx, int *cy) {
-    int radius;
-    int ext_unit_y, ext_unit_x;	/* x and y value of unit vector on
+    int64_t radius;
+    int64_t ext_unit_y, ext_unit_x;	/* x and y value of unit vector on
 				 * extend direction */
-    int arc_x, arc_y;
-    int radius_ref_ratio;
-    int arc_radius_factor;
-    int stat = 0;
-    int slope, slope_index;
-    int shift_cx, shift_cy;
-    int center_shift_factor;
+    int64_t arc_x, arc_y;
+    int64_t radius_ref_ratio;
+    int64_t arc_radius_factor;
+    int64_t slope, slope_index;
+    int64_t shift_cx, shift_cy;
+    int64_t center_shift_factor;
     static int negatives[4] = {0, 1, 1, 0};
-    /* Change sign of shift-x/y accroding sign of arc_x, arc_y,
-     * large and sweep.
-     */
-    static int shift_signs_tab[16][2] = {
-	/* -x,-y   +x,-y   -x,+y   +x,+y */
-	{0, 0}, {0, 1}, {1, 0}, {1, 1}, /* small, negative-angle */
-	{1, 1}, {1, 0}, {0, 1}, {0, 0}, /* large, negative-angle */
-	{1, 1}, {1, 0}, {0, 1}, {0, 0}, /* small, positive-angle */
-	{0, 0}, {0, 1}, {1, 0}, {1, 1}  /* large, positive-angle */
-    };
-    int extend_len;
-    int extend_x, extend_y;
+    int64_t extend_len;
+    int64_t extend_x, extend_y;
+    
+    ASSERT(rx >= 0 && ry >= 0);
     
     arc_x = x - x0;
     arc_y = y - y0;
@@ -272,11 +308,10 @@
     radius = MAX(rx, ry);
     _compute_extend_unit_vector(rx, ry, x_rotate, &ext_unit_x, &ext_unit_y);
     
-    extend_len = (arc_x * ext_unit_x + arc_y * ext_unit_y) >> FRACTION_SHIFT;
-    extend_len = extend_len * MAX(rx, ry) / MIN(rx, ry) -
-	(1 << FRACTION_SHIFT);
-    extend_x = ext_unit_x * extend_len;
-    extend_y = ext_unit_y * extend_len;
+    extend_len = (arc_x * ext_unit_x + arc_y * ext_unit_y) / FRACTION_ONE;
+    extend_len = extend_len * (MAX(rx, ry) - MIN(rx, ry)) / MIN(rx, ry);
+    extend_x = ext_unit_x * extend_len / FRACTION_ONE;
+    extend_y = ext_unit_y * extend_len / FRACTION_ONE;
     
     arc_x += extend_x;
     arc_y += extend_y;
@@ -294,37 +329,22 @@
     /* Compute x/y-shift of center range index according
      * slope_index, radius_ref_ratio and arc_radius_factor.
      */
+    _get_center_ref_shift(arc_x, arc_y, large, sweep, slope_index,
+			  &shift_cx, &shift_cy);
     center_shift_factor = radius_ref_ratio * arc_radius_factor;
-    center_shift_factor = center_shift_factor >> FRACTION_SHIFT;
-    shift_cx = (center_shift_tab[slope_index][0] * center_shift_factor) >>
-	FRACTION_SHIFT;
-    shift_cy = (center_shift_tab[slope_index][1] * center_shift_factor) >>
-	FRACTION_SHIFT;
-    if(ABS(arc_x) <= ABS(arc_y))
-	SWAP(shift_cx, shift_cy);
+    center_shift_factor = center_shift_factor / FRACTION_ONE;
+    shift_cx = shift_cx * center_shift_factor / FRACTION_ONE;
+    shift_cy = shift_cy * center_shift_factor / FRACTION_ONE;
     
-    if(IS_NEGATIVE(arc_x))
-	stat |= 0x1;
-    if(IS_NEGATIVE(arc_y))
-	stat |= 0x2;
-    if(large)
-	stat |= 0x4;
-    if(sweep)
-	stat |= 0x8;
-    if(shift_signs_tab[stat][0])
-	shift_cx = -shift_cx;
-    if(shift_signs_tab[stat][1])
-	shift_cy = -shift_cy;
-
-    shift_cx += arc_x >> 2;
-    shift_cy += arc_y >> 2;
+    shift_cx += arc_x / 2;
+    shift_cy += arc_y / 2;
 
     /* translate shift_cx/cy back to original coordinate */
-    extend_len = (shift_cx * ext_unit_x + shift_cy * ext_unit_y)
-	>> FRACTION_SHIFT;
-    extend_len = extend_len - extend_len * MIN(rx, ry) / MAX(rx, ry);
-    extend_x = (ext_unit_x * extend_len) >> FRACTION_SHIFT;
-    extend_y = (ext_unit_y * extend_len) >> FRACTION_SHIFT;
+    extend_len = (shift_cx * ext_unit_x + shift_cy * ext_unit_y) /
+	FRACTION_ONE;
+    extend_len = extend_len * (MAX(rx, ry) - MIN(rx, ry)) / MAX(rx, ry);
+    extend_x = ext_unit_x * extend_len / FRACTION_ONE;
+    extend_y = ext_unit_y * extend_len / FRACTION_ONE;
     shift_cx = shift_cx - extend_x;
     shift_cy = shift_cy - extend_y;
     
@@ -344,13 +364,13 @@
     int cx_i, cy_i;
     int r;
     
-    r = _calc_center_i(x0 * (1 << FRACTION_SHIFT), y0 * (1 << FRACTION_SHIFT),
-		       x * (1 << FRACTION_SHIFT), y * (1 << FRACTION_SHIFT),
-		       rx * (1 << FRACTION_SHIFT), ry * (1 << FRACTION_SHIFT),
-		       x_rotate * (1 << FRACTION_SHIFT),
+    r = _calc_center_i(x0 * FRACTION_ONE, y0 * FRACTION_ONE,
+		       x * FRACTION_ONE, y * FRACTION_ONE,
+		       rx * FRACTION_ONE, ry * FRACTION_ONE,
+		       x_rotate * FRACTION_ONE,
 		       large, sweep, &cx_i, &cy_i);
-    *cx = cx_i;
-    *cy = cy_i;
+    *cx = (co_aix)cx_i / FRACTION_ONE;
+    *cy = (co_aix)cy_i / FRACTION_ONE;
     return r;
 }
 
@@ -1383,7 +1403,263 @@
     sh_path_free((shape_t *)path);
 }
 
+void test_small_slope(void) {
+    co_aix x, y;
+    co_aix slope;
+    co_aix r;
+
+    x = 135.3;
+    y = 149.6;
+    r = (co_aix)_small_slope(x * FRACTION_ONE,
+			     y * FRACTION_ONE) /
+	FRACTION_ONE;
+
+    slope = MIN(x, y) / MAX(x, y);
+    CU_ASSERT(((r - slope) / slope) < 0.01 &&
+	      ((r - slope) / slope) > -0.01);
+}
+
+void test_find_slope_index(void) {
+    co_aix slope;
+    int idx;
+    co_aix r;
+
+    slope = 0.754;
+    idx = _find_slope_index(slope * FRACTION_ONE);
+    r = (co_aix)slope_tab[idx] / FRACTION_ONE;
+    CU_ASSERT((r / slope) < 1.01 &&
+	      (r / slope) > 0.99);
+}
+
+void test_vector_len(void) {
+    co_aix x, y;
+    co_aix len;
+    co_aix r;
+    int rlen;
+
+    x = 397;
+    y = 449;
+    len = sqrt(x * x + y * y);
+    rlen = _vector_len(x * FRACTION_ONE,
+		       y * FRACTION_ONE);
+    r = (co_aix)rlen / (1 <<FRACTION_SHIFT);
+    CU_ASSERT((r / len) < 1.01 &&
+	      (r / len) > 0.99);
+
+    x = 357;
+    y = 224;
+    len = sqrt(x * x + y * y);
+    rlen = _vector_len(x * FRACTION_ONE,
+		       y * FRACTION_ONE);
+    r = (co_aix)rlen / FRACTION_ONE;
+    CU_ASSERT((r / len) < 1.01 &&
+	      (r / len) > 0.99);
+}
+
+void test_find_arc_radius(void) {
+    co_aix ratio;
+    int idx;
+    co_aix r;
+
+    ratio = 0.732;
+    idx = _find_arc_radius(ratio * FRACTION_ONE);
+    r = (co_aix)arc_radius_ratio_tab[idx] / FRACTION_ONE;
+    CU_ASSERT((r / ratio) < 1.01 &&
+	      (r / ratio) > 0.99);
+}
+
+void test_get_arc_radius_shift_factor(void) {
+    co_aix arc_x, arc_y, radius;
+    co_aix factor;
+    int rfactor;
+    co_aix r;
+
+    arc_x = 30.5;
+    arc_y = 10.3;
+    radius = 90.3;
+    factor = sqrt(radius * radius - (arc_x * arc_x + arc_y * arc_y) / 4) /
+	radius;
+    rfactor = _get_arc_radius_shift_factor(arc_x * FRACTION_ONE,
+					   arc_y * FRACTION_ONE,
+					   radius * FRACTION_ONE);
+    r = (co_aix)rfactor / FRACTION_ONE;
+    CU_ASSERT((r / factor) < 1.01 &&
+	      (r / factor) > 0.99);
+
+    arc_x = 30.5;
+    arc_y = 70.3;
+    radius = 190.3;
+    factor = sqrt(radius * radius - (arc_x * arc_x + arc_y * arc_y) / 4) /
+	radius;
+    rfactor = _get_arc_radius_shift_factor(arc_x * FRACTION_ONE,
+					   arc_y * FRACTION_ONE,
+					   radius * FRACTION_ONE);
+    r = (co_aix)rfactor / FRACTION_ONE;
+    CU_ASSERT((r / factor) < 1.01 &&
+	      (r / factor) > 0.99);
+}
+
+void test_compute_extend_unit_vector(void) {
+    co_aix rx, ry;
+    co_aix x_rotate;
+    co_aix unit_x, unit_y;
+    co_aix runit_x, runit_y;
+    int64_t ext_unit_x, ext_unit_y;
+
+    rx = 200;
+    ry = 153;
+    x_rotate = PI * 30 / 180;
+    unit_x = cos(PI * 90 / 180 + x_rotate);
+    unit_y = sin(PI * 90 / 180 + x_rotate);
+    _compute_extend_unit_vector(rx * FRACTION_ONE, ry * FRACTION_ONE,
+				x_rotate * FRACTION_ONE,
+				&ext_unit_x, &ext_unit_y);
+    runit_x = (co_aix)ext_unit_x / FRACTION_ONE;
+    runit_y = (co_aix)ext_unit_y / FRACTION_ONE;
+    CU_ASSERT((runit_x / unit_x) < 1.01 &&
+	      (runit_x / unit_x) > 0.99);
+    CU_ASSERT((runit_y / unit_y) < 1.01 &&
+	      (runit_y / unit_y) > 0.99);
+
+    rx = 200;
+    ry = 153;
+    x_rotate = PI * 158 / 180;
+    unit_x = cos(PI * 90 / 180 + x_rotate);
+    unit_y = sin(PI * 90 / 180 + x_rotate);
+    _compute_extend_unit_vector(rx * FRACTION_ONE, ry * FRACTION_ONE,
+				x_rotate * FRACTION_ONE,
+				&ext_unit_x, &ext_unit_y);
+    runit_x = (co_aix)ext_unit_x / FRACTION_ONE;
+    runit_y = (co_aix)ext_unit_y / FRACTION_ONE;
+    CU_ASSERT((runit_x / unit_x) < 1.01 &&
+	      (runit_x / unit_x) > 0.99);
+    CU_ASSERT((runit_y / unit_y) < 1.01 &&
+	      (runit_y / unit_y) > 0.99);
+
+    rx = 100;
+    ry = 153;
+    x_rotate = PI * 158 / 180;
+    unit_x = cos(x_rotate);
+    unit_y = sin(x_rotate);
+    _compute_extend_unit_vector(rx * FRACTION_ONE, ry * FRACTION_ONE,
+				x_rotate * FRACTION_ONE,
+				&ext_unit_x, &ext_unit_y);
+    runit_x = (co_aix)ext_unit_x / FRACTION_ONE;
+    runit_y = (co_aix)ext_unit_y / FRACTION_ONE;
+    CU_ASSERT((runit_x / unit_x) < 1.01 &&
+	      (runit_x / unit_x) > 0.99);
+    CU_ASSERT((runit_y / unit_y) < 1.01 &&
+	      (runit_y / unit_y) > 0.99);
+}
+
+void test_get_center_ref_shift(void) {
+    co_aix slope;
+    int slope_index;
+    co_aix arc_len;
+    co_aix arc_x, arc_y;
+    int large, sweep;
+    co_aix shift_x, shift_y;
+    co_aix r_x, r_y;
+    int64_t rshift_x, rshift_y;
+
+    arc_x = 311;
+    arc_y = 210;
+    large = 0;			/* small arc */
+    sweep = 1;			/* positive sweep */
+    arc_len = sqrt(arc_x * arc_x + arc_y * arc_y);
+    shift_x = arc_y / arc_len * (1 << REF_RADIUS_SHIFT);
+    shift_y = arc_x / arc_len * (1 << REF_RADIUS_SHIFT);
+    if((arc_x < 0) ^ (arc_y < 0))
+	/* exactly one of arc_x and arc_y is negative */
+	shift_y = -shift_y;
+    else
+	shift_x = -shift_x;
+    slope = MIN(ABS(arc_x), ABS(arc_y)) /  MAX(ABS(arc_x), ABS(arc_y));
+    slope_index = _find_slope_index(slope * FRACTION_ONE);
+    _get_center_ref_shift(arc_x * FRACTION_ONE, arc_y * FRACTION_ONE,
+			  large, sweep,
+			  slope_index,
+			  &rshift_x, &rshift_y);
+    r_x = (co_aix)rshift_x / FRACTION_ONE;
+    r_y = (co_aix)rshift_y / FRACTION_ONE;
+    CU_ASSERT((r_x / shift_x) < 1.01 &&
+	      (r_x / shift_x) > 0.99);
+    CU_ASSERT((r_y / shift_y) < 1.01 &&
+	      (r_y / shift_y) > 0.99);
+
+    arc_x = 311;
+    arc_y = 210;
+    large = 1;			/* small arc */
+    sweep = 1;			/* positive sweep */
+    arc_len = sqrt(arc_x * arc_x + arc_y * arc_y);
+    shift_x = -arc_y / arc_len * (1 << REF_RADIUS_SHIFT);
+    shift_y = -arc_x / arc_len * (1 << REF_RADIUS_SHIFT);
+    if((arc_x < 0) ^ (arc_y < 0))
+	/* exactly one of arc_x and arc_y is negative */
+	shift_y = -shift_y;
+    else
+	shift_x = -shift_x;
+    slope = MIN(ABS(arc_x), ABS(arc_y)) /  MAX(ABS(arc_x), ABS(arc_y));
+    slope_index = _find_slope_index(slope * FRACTION_ONE);
+    _get_center_ref_shift(arc_x * FRACTION_ONE, arc_y * FRACTION_ONE,
+			  large, sweep,
+			  slope_index,
+			  &rshift_x, &rshift_y);
+    r_x = (co_aix)rshift_x / FRACTION_ONE;
+    r_y = (co_aix)rshift_y / FRACTION_ONE;
+    CU_ASSERT((r_x / shift_x) < 1.01 &&
+	      (r_x / shift_x) > 0.99);
+    CU_ASSERT((r_y / shift_y) < 1.01 &&
+	      (r_y / shift_y) > 0.99);
+}
+
 void test_calc_center(void) {
+    co_aix x0, y0, x, y;
+    co_aix rx, ry, x_rotate;
+    int large, sweep;
+    co_aix cx, cy;
+    co_aix angle_start, angle_stop;
+    co_aix rcx, rcy;
+    co_aix _x, _y;
+    
+#define ELLIPSE_POINT(angle, point_x, point_y)			\
+    do {							\
+	_x = rx * cos(angle);					\
+	_y = ry * sin(angle);					\
+	point_x = _x * cos(x_rotate) - _y * sin(x_rotate) + cx;	\
+	point_y = _x * sin(x_rotate) + _y * cos(x_rotate) + cy;	\
+    } while(0)
+#define CENTER_TEST()						\
+    do {							\
+	_calc_center(x0, y0, x, y, rx, ry, x_rotate,		\
+		     0, 1, &rcx, &rcy);				\
+	CU_ASSERT((cx - rcx) <= 2 && (cx - rcx) >= -2);		\
+	CU_ASSERT((cy - rcy) <= 2 && (cy - rcy) >= -2);		\
+	_calc_center(x0, y0, x, y, rx, ry, x_rotate,		\
+		     1, 0, &rcx, &rcy);				\
+	CU_ASSERT((cx - rcx) <= 2 && (cx - rcx) >= -2);		\
+	CU_ASSERT((cy - rcy) <= 2 && (cy - rcy) >= -2);		\
+	_calc_center(x, y, x0, y0, rx, ry, x_rotate,		\
+		     0, 0, &rcx, &rcy);				\
+	CU_ASSERT((cx - rcx) <= 2 && (cx - rcx) >= -2);		\
+	CU_ASSERT((cy - rcy) <= 2 && (cy - rcy) >= -2);		\
+	_calc_center(x, y, x0, y0, rx, ry, x_rotate,		\
+		     1, 1, &rcx, &rcy);				\
+	CU_ASSERT((cx - rcx) <= 2 && (cx - rcx) >= -2);		\
+	CU_ASSERT((cy - rcy) <= 2 && (cy - rcy) >= -2);		\
+    } while(0)
+
+    cx = 135;
+    cy = 254;
+    rx = 200;
+    ry = 170;
+    x_rotate = PI * 20 / 180;
+    angle_start = PI * 55 / 180;
+    angle_stop = PI * 97 / 180;
+    
+    ELLIPSE_POINT(angle_start, x0, y0);
+    ELLIPSE_POINT(angle_stop, x, y);
+    CENTER_TEST();
 }
 
 void test_spaces_head_tail(void) {
@@ -1403,6 +1679,13 @@
     suite = CU_add_suite("Suite_shape_path", NULL, NULL);
     CU_ADD_TEST(suite, test_rdman_shape_path_new);
     CU_ADD_TEST(suite, test_path_transform);
+    CU_ADD_TEST(suite, test_small_slope);
+    CU_ADD_TEST(suite, test_find_slope_index);
+    CU_ADD_TEST(suite, test_vector_len);
+    CU_ADD_TEST(suite, test_find_arc_radius);
+    CU_ADD_TEST(suite, test_get_arc_radius_shift_factor);
+    CU_ADD_TEST(suite, test_compute_extend_unit_vector);
+    CU_ADD_TEST(suite, test_get_center_ref_shift);
     CU_ADD_TEST(suite, test_calc_center);
 
     return suite;
--- a/tools/gen_precomputed_tabs.py	Sun Dec 19 00:02:31 2010 +0800
+++ b/tools/gen_precomputed_tabs.py	Sun Dec 19 17:56:23 2010 +0800
@@ -19,8 +19,8 @@
     _fraction_shift = 10
     _ref_radius_shift = 10
     _slope_tab_sz = 128
-    _arc_radius_ratio_tab_sz = 128
-    _arc_radius_factor_tab_sz = 128
+    _arc_radius_ratio_tab_sz = 256
+    _arc_radius_factor_tab_sz = 256
     _sin_tab_sz = 256
     
     def gen_slope_tab(self):
@@ -67,9 +67,9 @@
         radius = 1 << (self._ref_radius_shift + self._fraction_shift)
 
         for i in range(self._slope_tab_sz):
-            angle = pi / 4 * i / (self._slope_tab_sz - 1)
-            x = -int(cos(angle) * radius)
-            y = -int(sin(angle) * radius)
+            angle = pi / 4 * i / (self._slope_tab_sz - 1) + pi / 2
+            x = int(cos(angle) * radius)
+            y = int(sin(angle) * radius)
             line = '    {%d, %d},' % (x, y)
             lines.append(line)
             pass