Example #1
0
static void
spiro_seg_to_bpath(const double ks[4],
		   double x0, double y0, double x1, double y1,
		   bezctx *bc, int depth)
{
    double bend = fabs(ks[0]) + fabs(.5 * ks[1]) + fabs(.125 * ks[2]) +
	fabs((1./48) * ks[3]);

    if (!bend > 1e-8) {
	bezctx_lineto(bc, x1, y1);
    } else {
	double seg_ch = hypot(x1 - x0, y1 - y0);
	double seg_th = atan2(y1 - y0, x1 - x0);
	double xy[2];
	double ch, th;
	double scale, rot;
	double th_even, th_odd;
	double ul, vl;
	double ur, vr;

	integrate_spiro(ks, xy);
	ch = hypot(xy[0], xy[1]);
	th = atan2(xy[1], xy[0]);
	scale = seg_ch / ch;
	rot = seg_th - th;
	if (depth > 5 || bend < 1.) {
	    th_even = (1./384) * ks[3] + (1./8) * ks[1] + rot;
	    th_odd = (1./48) * ks[2] + .5 * ks[0];
	    ul = (scale * (1./3)) * cos(th_even - th_odd);
	    vl = (scale * (1./3)) * sin(th_even - th_odd);
	    ur = (scale * (1./3)) * cos(th_even + th_odd);
	    vr = (scale * (1./3)) * sin(th_even + th_odd);
	    bezctx_curveto(bc, x0 + ul, y0 + vl, x1 - ur, y1 - vr, x1, y1);
	} else {
	    /* subdivide */
	    double ksub[4];
	    double thsub;
	    double xysub[2];
	    double xmid, ymid;
	    double cth, sth;

	    ksub[0] = .5 * ks[0] - .125 * ks[1] + (1./64) * ks[2] - (1./768) * ks[3];
	    ksub[1] = .25 * ks[1] - (1./16) * ks[2] + (1./128) * ks[3];
	    ksub[2] = .125 * ks[2] - (1./32) * ks[3];
	    ksub[3] = (1./16) * ks[3];
	    thsub = rot - .25 * ks[0] + (1./32) * ks[1] - (1./384) * ks[2] + (1./6144) * ks[3];
	    cth = .5 * scale * cos(thsub);
	    sth = .5 * scale * sin(thsub);
	    integrate_spiro(ksub, xysub);
	    xmid = x0 + cth * xysub[0] - sth * xysub[1];
	    ymid = y0 + cth * xysub[1] + sth * xysub[0];
	    spiro_seg_to_bpath(ksub, x0, y0, xmid, ymid, bc, depth + 1);
	    ksub[0] += .25 * ks[1] + (1./384) * ks[3];
	    ksub[1] += .125 * ks[2];
	    ksub[2] += (1./16) * ks[3];
	    spiro_seg_to_bpath(ksub, xmid, ymid, x1, y1, bc, depth + 1);
	}
    }
}
Example #2
0
void
spiro_to_bpath(const spiro_seg *s, int n, bezctx *bc)
{
    int i;
    int nsegs = s[n - 1].ty == '}' ? n - 1 : n;

    for (i = 0; i < nsegs; i++) {
	double x0 = s[i].x;
	double y0 = s[i].y;
	double x1 = s[i + 1].x;
	double y1 = s[i + 1].y;

	if (i == 0)
	    bezctx_moveto(bc, x0, y0, s[0].ty == '{');
	bezctx_mark_knot(bc, i);
	spiro_seg_to_bpath(s[i].ks, x0, y0, x1, y1, bc, 0);
    }
}
Example #3
0
void
spiro_to_bpath(const spiro_seg *s, int n, bezctx *bc)
{
    int i, nsegs;
    double x0, y0, x1, y1;

    if (s==NULL || n <= 0 || bc==NULL) return;

    nsegs = s[n - 1].ty == '}' ? n - 1 : n;

    for (i = 0; i < nsegs; i++) {
	x0 = s[i].x; x1 = s[i + 1].x;
	y0 = s[i].y; y1 = s[i + 1].y;

	if (i == 0)
	    bezctx_moveto(bc, x0, y0, s[0].ty == '{');
	bezctx_mark_knot(bc, i);
	spiro_seg_to_bpath(s[i].ks, x0, y0, x1, y1, bc, 0);
    }
}