From: Jean-Philippe Bruyère Date: Mon, 29 Nov 2021 05:07:16 +0000 (+0100) Subject: dynamic distanceTolerance in _recursive_bezier X-Git-Tag: v0.2.0~49 X-Git-Url: https://git.osiis.dedyn.io/?a=commitdiff_plain;h=bd4255a6a92d251d81fc672ee6d5468477753f0e;p=jp%2Fvkvg.git dynamic distanceTolerance in _recursive_bezier --- diff --git a/src/vkvg_context.c b/src/vkvg_context.c index 5f912e6..c53369c 100644 --- a/src/vkvg_context.c +++ b/src/vkvg_context.c @@ -496,7 +496,12 @@ void vkvg_curve_to (VkvgContext ctx, float x1, float y1, float x2, float y2, flo vec2 cp = _get_current_position(ctx); - _recursive_bezier (ctx, cp.x, cp.y, x1, y1, x2, y2, x3, y3, 0); + //compute dyn distanceTolerance depending on current transform + float dx = 1, dy = 1; + vkvg_matrix_transform_distance (&ctx->pushConsts.mat, &dx, &dy); + float distanceTolerance = 0.02f / fmaxf(dx,dy); + + _recursive_bezier (ctx, distanceTolerance, cp.x, cp.y, x1, y1, x2, y2, x3, y3, 0); /*cp.x = x3; cp.y = y3; if (!vec2_equ(ctx->points[ctx->pointCount-1],cp))*/ diff --git a/src/vkvg_context_internal.c b/src/vkvg_context_internal.c index d5be84a..a1a634c 100644 --- a/src/vkvg_context_internal.c +++ b/src/vkvg_context_internal.c @@ -880,14 +880,13 @@ void _free_ctx_save (vkvg_context_save_t* sav){ #define M_APPROXIMATION_SCALE 1.0 #define M_ANGLE_TOLERANCE 0.01 -#define M_DISTANCE_TOLERANCE 1.0 #define M_CUSP_LIMIT 0.01 -#define CURVE_RECURSION_LIMIT 10 +#define CURVE_RECURSION_LIMIT 100 #define CURVE_COLLINEARITY_EPSILON 1.7 #define CURVE_ANGLE_TOLERANCE_EPSILON 0.001 //no floating point arithmetic operation allowed in macro. #pragma warning(disable:4127) -void _recursive_bezier (VkvgContext ctx, +void _recursive_bezier (VkvgContext ctx, float distanceTolerance, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, unsigned level) { @@ -927,7 +926,7 @@ void _recursive_bezier (VkvgContext ctx, { // Regular care //----------------- - if((d2 + d3)*(d2 + d3) <= (dx*dx + dy*dy) * (float)M_DISTANCE_TOLERANCE) + if((d2 + d3)*(d2 + d3) <= (dx*dx + dy*dy) * distanceTolerance) { // If the curvature doesn't exceed the distance_tolerance value // we tend to finish subdivisions. @@ -973,7 +972,7 @@ void _recursive_bezier (VkvgContext ctx, { // p1,p3,p4 are collinear, p2 is considerable //---------------------- - if(d2 * d2 <= (float)M_DISTANCE_TOLERANCE * (dx*dx + dy*dy)) + if(d2 * d2 <= distanceTolerance * (dx*dx + dy*dy)) { if(M_ANGLE_TOLERANCE < CURVE_ANGLE_TOLERANCE_EPSILON) { @@ -1005,7 +1004,7 @@ void _recursive_bezier (VkvgContext ctx, } else if(d3 > CURVE_COLLINEARITY_EPSILON) { // p1,p2,p4 are collinear, p3 is considerable //---------------------- - if(d3 * d3 <= (float)M_DISTANCE_TOLERANCE * (dx*dx + dy*dy)) + if(d3 * d3 <= distanceTolerance* (dx*dx + dy*dy)) { if(M_ANGLE_TOLERANCE < CURVE_ANGLE_TOLERANCE_EPSILON) { @@ -1041,7 +1040,7 @@ void _recursive_bezier (VkvgContext ctx, //----------------- dx = x1234 - (x1 + x4) / 2; dy = y1234 - (y1 + y4) / 2; - if(dx*dx + dy*dy <= (float)M_DISTANCE_TOLERANCE) + if(dx*dx + dy*dy <= distanceTolerance) { _add_point (ctx, x1234, y1234); return; @@ -1052,8 +1051,8 @@ void _recursive_bezier (VkvgContext ctx, // Continue subdivision //---------------------- - _recursive_bezier (ctx, x1, y1, x12, y12, x123, y123, x1234, y1234, level + 1); - _recursive_bezier (ctx, x1234, y1234, x234, y234, x34, y34, x4, y4, level + 1); + _recursive_bezier (ctx, distanceTolerance, x1, y1, x12, y12, x123, y123, x1234, y1234, level + 1); + _recursive_bezier (ctx, distanceTolerance,x1234, y1234, x234, y234, x34, y34, x4, y4, level + 1); } #pragma warning(default:4127) diff --git a/src/vkvg_context_internal.h b/src/vkvg_context_internal.h index 7013690..9c6f962 100644 --- a/src/vkvg_context_internal.h +++ b/src/vkvg_context_internal.h @@ -254,7 +254,7 @@ static inline float vec2_zcross (vec2 v1, vec2 v2){ static inline float ecp_zcross (ear_clip_point* p0, ear_clip_point* p1, ear_clip_point* p2){ return vec2_zcross (vec2_sub (p1->pos, p0->pos), vec2_sub (p2->pos, p0->pos)); } -void _recursive_bezier(VkvgContext ctx, +void _recursive_bezier(VkvgContext ctx, float distanceTolerance, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, unsigned level);