|
|
|
@ -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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* we can avoid subdivision if:
|
|
|
|
|
/* 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;
|
|
|
|
|
|
|
|
|
|
z1 has distance no more than flatness from the z0-z3 line
|
|
|
|
|
x3_0 = x3 - x0;
|
|
|
|
|
y3_0 = y3 - y0;
|
|
|
|
|
|
|
|
|
|
z1 is no more z0'ward than flatness past z0-z3
|
|
|
|
|
/* z3_0_dot is dist z0-z3 squared */
|
|
|
|
|
z3_0_dot = x3_0 * x3_0 + y3_0 * y3_0;
|
|
|
|
|
|
|
|
|
|
z1 is more z0'ward than z3'ward on the line traversing z0-z3
|
|
|
|
|
if (z3_0_dot > 0.001)
|
|
|
|
|
{
|
|
|
|
|
/* we can avoid subdivision if:
|
|
|
|
|
|
|
|
|
|
and correspondingly for z2 */
|
|
|
|
|
z1 has distance no more than flatness from the z0-z3 line
|
|
|
|
|
|
|
|
|
|
/* perp is distance from line, multiplied by dist z0-z3 */
|
|
|
|
|
max_perp_sq = flatness * flatness * z3_0_dot;
|
|
|
|
|
z1 is no more z0'ward than flatness past z0-z3
|
|
|
|
|
|
|
|
|
|
z1_perp = (y1 - y0) * x3_0 - (x1 - x0) * y3_0;
|
|
|
|
|
if (z1_perp * z1_perp > max_perp_sq)
|
|
|
|
|
goto subdivide;
|
|
|
|
|
z1 is more z0'ward than z3'ward on the line traversing z0-z3
|
|
|
|
|
|
|
|
|
|
z2_perp = (y3 - y2) * x3_0 - (x3 - x2) * y3_0;
|
|
|
|
|
if (z2_perp * z2_perp > max_perp_sq)
|
|
|
|
|
goto subdivide;
|
|
|
|
|
and correspondingly for z2 */
|
|
|
|
|
|
|
|
|
|
z1_dot = (x1 - x0) * x3_0 + (y1 - y0) * y3_0;
|
|
|
|
|
if (z1_dot < 0 && z1_dot * z1_dot > max_perp_sq)
|
|
|
|
|
goto subdivide;
|
|
|
|
|
/* perp is distance from line, multiplied by dist z0-z3 */
|
|
|
|
|
max_perp_sq = flatness * flatness * z3_0_dot;
|
|
|
|
|
|
|
|
|
|
z2_dot = (x3 - x2) * x3_0 + (y3 - y2) * y3_0;
|
|
|
|
|
if (z2_dot < 0 && z2_dot * z2_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;
|
|
|
|
|
|
|
|
|
|
if (z1_dot + z1_dot > z3_0_dot)
|
|
|
|
|
goto subdivide;
|
|
|
|
|
z2_perp = (y3 - y2) * x3_0 - (x3 - x2) * y3_0;
|
|
|
|
|
if (z2_perp * z2_perp > max_perp_sq)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
if (z2_dot + z2_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 (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;
|
|
|
|
|