diff options
Diffstat (limited to 'art_vpath_bpath.c')
-rw-r--r-- | art_vpath_bpath.c | 119 |
1 files changed, 58 insertions, 61 deletions
diff --git a/art_vpath_bpath.c b/art_vpath_bpath.c index 3f9afe7..2459f23 100644 --- a/art_vpath_bpath.c +++ b/art_vpath_bpath.c @@ -123,18 +123,6 @@ art_vpath_render_bez (ArtVpath **p_vpath, int *pn, int *pn_max, double x3, double y3, double flatness) { - double x3_0, y3_0; - double z3_0_dot; - double z1_dot, z2_dot; - double z1_perp, z2_perp; - double max_perp_sq; - - double x_m, y_m; - double xa1, ya1; - double xa2, ya2; - double xb1, yb1; - double xb2, yb2; - /* It's possible to optimize this routine a fair amount. First, once the _dot conditions are met, they will also be met in @@ -157,70 +145,79 @@ art_vpath_render_bez (ArtVpath **p_vpath, int *pn, int *pn_max, just that I have this undying quest for more speed... */ - - x3_0 = x3 - x0; - y3_0 = y3 - y0; - - /* z3_0_dot is dist z0-z3 squared */ - z3_0_dot = x3_0 * x3_0 + y3_0 * y3_0; - - if (z3_0_dot < 0.001) + do { - /* if start and end point are almost identical, the flatness tests - * don't work properly, so fall back on testing whether both of - * the other two control points are the same as the start point, - * too. - */ - if (hypot(x1 - x0, y1 - y0) < 0.001 - && hypot(x2 - x0, y2 - y0) < 0.001) - goto nosubdivide; - else - goto subdivide; - } + /* don't subdivide inside this */ + double x3_0, y3_0; + double z3_0_dot; + double z1_dot, z2_dot; + double z1_perp, z2_perp; + double max_perp_sq; - /* we can avoid subdivision if: + x3_0 = x3 - x0; + y3_0 = y3 - y0; - z1 has distance no more than flatness from the z0-z3 line + /* z3_0_dot is dist z0-z3 squared */ + z3_0_dot = x3_0 * x3_0 + y3_0 * y3_0; - z1 is no more z0'ward than flatness past z0-z3 + if (z3_0_dot > 0.001) + { + /* we can avoid subdivision if: - z1 is more z0'ward than z3'ward on the line traversing z0-z3 + z1 has distance no more than flatness from the z0-z3 line - and correspondingly for z2 */ + z1 is no more z0'ward than flatness past z0-z3 - /* perp is distance from line, multiplied by dist z0-z3 */ - max_perp_sq = flatness * flatness * z3_0_dot; + z1 is more z0'ward than z3'ward on the line traversing z0-z3 - z1_perp = (y1 - y0) * x3_0 - (x1 - x0) * y3_0; - if (z1_perp * z1_perp > max_perp_sq) - goto subdivide; + and correspondingly for z2 */ - z2_perp = (y3 - y2) * x3_0 - (x3 - x2) * y3_0; - if (z2_perp * z2_perp > max_perp_sq) - goto subdivide; + /* perp is distance from line, multiplied by dist z0-z3 */ + max_perp_sq = flatness * flatness * z3_0_dot; - z1_dot = (x1 - x0) * x3_0 + (y1 - y0) * y3_0; - if (z1_dot < 0 && z1_dot * z1_dot > max_perp_sq) - goto subdivide; + z1_perp = (y1 - y0) * x3_0 - (x1 - x0) * y3_0; + if (z1_perp * z1_perp > max_perp_sq) + break; - z2_dot = (x3 - x2) * x3_0 + (y3 - y2) * y3_0; - if (z2_dot < 0 && z2_dot * z2_dot > max_perp_sq) - goto subdivide; + z2_perp = (y3 - y2) * x3_0 - (x3 - x2) * y3_0; + if (z2_perp * z2_perp > max_perp_sq) + break; - if (z1_dot + z1_dot > z3_0_dot) - goto subdivide; + z1_dot = (x1 - x0) * x3_0 + (y1 - y0) * y3_0; + if (z1_dot < 0 && z1_dot * z1_dot > max_perp_sq) + break; - if (z2_dot + z2_dot > z3_0_dot) - goto subdivide; + if (z1_dot + z1_dot > z3_0_dot) + break; - - nosubdivide: - /* don't subdivide */ - art_vpath_add_point (p_vpath, pn, pn_max, - ART_LINETO, x3, y3); - return; + z2_dot = (x3 - x2) * x3_0 + (y3 - y2) * y3_0; + if (z2_dot < 0 && z2_dot * z2_dot > max_perp_sq) + break; - subdivide: + if (z2_dot + z2_dot > z3_0_dot) + break; + } + else + { + /* if start and end point are almost identical, the flatness tests + * don't work properly, so fall back on testing whether both of + * the other two control points are the same as the start point, + * too. + */ + if (hypot(x1 - x0, y1 - y0) > 0.001 + || hypot(x2 - x0, y2 - y0) > 0.001) + break; + } + + art_vpath_add_point (p_vpath, pn, pn_max, + ART_LINETO, x3, y3); + return; + } while (0); + double x_m, y_m; + double xa1, ya1; + double xa2, ya2; + double xb1, yb1; + double xb2, yb2; xa1 = (x0 + x1) * 0.5; ya1 = (y0 + y1) * 0.5; |