Пример #1
0
static real SplineFindMinXAtY(Spline *spline,real y,real min) {
    extended t,t1,t2,tbase,val;
    Spline1D *xsp;

    if ( y>spline->from->me.y && y>spline->from->nextcp.y &&
	    y>spline->to->me.y && y>spline->to->prevcp.y )
return( min );
    if ( y<spline->from->me.y && y<spline->from->nextcp.y &&
	    y<spline->to->me.y && y<spline->to->prevcp.y )
return( min );
    if ( min!=NOTREACHED ) {
	if ( min<=spline->from->me.x && min<=spline->from->nextcp.x &&
		min<=spline->to->me.x && min<=spline->to->prevcp.x )
return( min );
    }

    xsp = &spline->splines[0];
    SplineFindExtrema(&spline->splines[1], &t1, &t2 );
    tbase = 0;
    if ( t1!=-1 ) {
	t = SplineSolve(&spline->splines[1],0,t1,y);
	if ( t>=0 && t<=1 ) {
	    val = ((xsp->a*t+xsp->b)*t+xsp->c)*t + xsp->d;
	    if ( min==NOTREACHED || val<min )
		min = val;
	}
	tbase = t1;
    }
    if ( t2!=-1 ) {
	t = SplineSolve(&spline->splines[1],tbase,t2,y);
	if ( t>=0 && t<=1 ) {
	    val = ((xsp->a*t+xsp->b)*t+xsp->c)*t + xsp->d;
	    if ( min==NOTREACHED || val<min )
		min = val;
	}
	tbase = t2;
    }
    t = SplineSolve(&spline->splines[1],tbase,1.0,y);
    if ( t>=0 && t<=1 ) {
	val = ((xsp->a*t+xsp->b)*t+xsp->c)*t + xsp->d;
	if ( min==NOTREACHED || val<min )
	    min = val;
    }
return( min );
}
Пример #2
0
static void SplineFindEdges(Spline *spline,struct charone *ch, WidthInfo *wi) {
    Spline1D *xsp, *ysp;
    extended t1, t2;
    double t, toff, ymin, ymax;

    /* first try the end points */
    PtFindEdges(spline->to->me.x,spline->to->me.y,ch,wi);
    PtFindEdges(spline->from->me.x,spline->from->me.y,ch,wi);

    /* then try the extrema of the spline (assuming they are between t=(0,1) */
    xsp = &spline->splines[0]; ysp = &spline->splines[1];
    SplineFindExtrema(xsp, &t1, &t2 );
    if ( t1!=-1 )
	PtFindEdges( ((xsp->a*t1+xsp->b)*t1+xsp->c)*t1+xsp->d,
		((ysp->a*t1+ysp->b)*t1+ysp->c)*t1+ysp->d,
		ch,wi);
    if ( t2!=-1 )
	PtFindEdges( ((xsp->a*t2+xsp->b)*t2+xsp->c)*t2+xsp->d,
		((ysp->a*t2+ysp->b)*t2+ysp->c)*t2+ysp->d,
		ch,wi);

    ymin = ymax = spline->from->me.y;
    if ( spline->from->nextcp.y > ymax ) ymax = spline->from->nextcp.y;
    if ( spline->from->nextcp.y < ymin ) ymin = spline->from->nextcp.y;
    if ( spline->to->prevcp.y > ymax ) ymax = spline->to->prevcp.y;
    if ( spline->to->prevcp.y < ymin ) ymin = spline->to->prevcp.y;
    if ( spline->to->me.y > ymax ) ymax = spline->to->me.y;
    if ( spline->to->me.y < ymin ) ymin = spline->to->me.y;

    if ( ymin!=ymax ) {
	toff = wi->decimation/(2*(ymax-ymin));
	for ( t=toff; t<1; t+=toff ) {
	    PtFindEdges( ((xsp->a*t+xsp->b)*t+xsp->c)*t+xsp->d,
		    ((ysp->a*t+ysp->b)*t+ysp->c)*t+ysp->d,
		    ch,wi);
	}
    }
}
Пример #3
0
static void AddSpline(EdgeList *es, Spline *sp ) {
    real t1=2, t2=2, t;
    real b2_fourac;
    real fm, tm;
    Spline1D *msp = &sp->splines[es->major], *osp = &sp->splines[es->other];

    /* Find the points of extrema on the curve discribing y behavior */
    if ( !RealNear(msp->a,0) ) {
	/* cubic, possibly 2 extrema (possibly none) */
	b2_fourac = 4*msp->b*msp->b - 12*msp->a*msp->c;
	if ( b2_fourac>=0 ) {
	    b2_fourac = sqrt(b2_fourac);
	    t1 = CheckExtremaForSingleBitErrors(msp,(-2*msp->b - b2_fourac) / (6*msp->a));
	    t2 = CheckExtremaForSingleBitErrors(msp,(-2*msp->b + b2_fourac) / (6*msp->a));
	    if ( t1>t2 ) { real temp = t1; t1 = t2; t2 = temp; }
	    else if ( t1==t2 ) t2 = 2.0;

	    /* check for curves which have such a small slope they might */
	    /*  as well be horizontal */
	    fm = es->major==1?sp->from->me.y:sp->from->me.x;
	    tm = es->major==1?sp->to->me.y:sp->to->me.x;
	    if ( fm==tm ) {
		real m1, m2, d1, d2;
		m1 = m2 = fm;
		if ( t1>0 && t1<1 )
		    m1 = ((msp->a*t1+msp->b)*t1+msp->c)*t1 + msp->d;
		if ( t2>0 && t2<1 )
		    m2 = ((msp->a*t2+msp->b)*t2+msp->c)*t2 + msp->d;
		d1 = (m1-fm)*es->scale;
		d2 = (m2-fm)*es->scale;
		if ( d1>-.5 && d1<.5 && d2>-.5 && d2<.5 ) {
		    sp->ishorvert = true;
		    if ( es->genmajoredges )
			AddMajorEdge(es,sp);
return;		/* Pretend it's horizontal, ignore it */
		}
	    }
	}
    } else if ( !RealNear(msp->b,0) ) {
	/* Quadratic, at most one extremum */
	t1 = -msp->c/(2.0*msp->b);
    } else if ( !RealNear(msp->c,0) ) {
	/* linear, no points of extrema */
    } else {
	sp->ishorvert = true;
	if ( es->genmajoredges )
	    AddMajorEdge(es,sp);
return;		/* Horizontal line, ignore it */
    }

    if ( RealNear(t1,0)) t1=0;
    if ( RealNear(t1,1)) t1=1;
    if ( RealNear(t2,0)) t2=0;
    if ( RealNear(t2,1)) t2=1;
    if ( RealNear(t1,t2)) t2=2;
    t=0;
    if ( t1>0 && t1<1 ) {
	AddEdge(es,sp,0,t1);
	t = t1;
    }
    if ( t2>0 && t2<1 ) {
	AddEdge(es,sp,t,t2);
	t = t2;
    }
    AddEdge(es,sp,t,1.0);
    if ( es->interesting ) {
	/* Also store up points of extrema in X as interesting (we got the endpoints, just internals now)*/
	extended ot1, ot2;
	int mpos;
	SplineFindExtrema(osp,&ot1,&ot2);
	if ( ot1>0 && ot1<1 ) {
	    mpos = (int) ceil( ( ((msp->a*ot1+msp->b)*ot1+msp->c)*ot1+msp->d )*es->scale-es->mmin );
	    es->interesting[mpos] = 1;
	}
	if ( ot2>0 && ot2<1 ) {
	    mpos = (int) ceil( ( ((msp->a*ot2+msp->b)*ot2+msp->c)*ot2+msp->d )*es->scale-es->mmin );
	    es->interesting[mpos] = 1;
	}
    }
}