Пример #1
0
static int
psdist(Point p, Point a, Point b)
{
	int num, den;

	p = subpt(p, a);
	b = subpt(b, a);
	num = p.x*b.x + p.y*b.y;
	if(num <= 0)
		return normsq(p);
	den = normsq(b);
	if(num >= den)
		return normsq(subpt(b, p));
	return normsq(subpt(divpt(mulpt(b, num), den), p));
}
Пример #2
0
static void
_bezsplinepts(Plist *l, Point *pt, int npt)
{
	Point *p, *ep;
	Point a, b, c, d;
	int periodic;

	if(npt<3)
		return;
	ep = &pt[npt-3];
	periodic = eqpt(pt[0], ep[2]);
	if(periodic){
		a = divpt(addpt(ep[1], pt[0]), 2);
		b = divpt(addpt(ep[1], mulpt(pt[0], 5)), 6);
		c = divpt(addpt(mulpt(pt[0], 5), pt[1]), 6);
		d = divpt(addpt(pt[0], pt[1]), 2);
		bpts(l, a, b, c, d);
	}
	for(p=pt; p<=ep; p++){
		if(p==pt && !periodic){
			a = p[0];
			b = divpt(addpt(p[0], mulpt(p[1], 2)), 3);
		}
		else{
			a = divpt(addpt(p[0], p[1]), 2);
			b = divpt(addpt(p[0], mulpt(p[1], 5)), 6);
		}
		if(p==ep && !periodic){
			c = divpt(addpt(mulpt(p[1], 2), p[2]), 3);
			d = p[2];
		}
		else{
			c = divpt(addpt(mulpt(p[1], 5), p[2]), 6);
			d = divpt(addpt(p[1], p[2]), 2);
		}
		bpts(l, a, b, c, d);
	}
	appendpt(l, d);
}
Пример #3
0
/*
 * Convert cubic Bezier curve control points to polyline
 * vertices.  Leaves the last vertex off, so you can continue
 * with another curve.
 */
static void
bpts1(Plist *l, Point p0, Point p1, Point p2, Point p3, int scale)
{
	Point p01, p12, p23, p012, p123, p0123;
	Point tp0, tp1, tp2, tp3;
	tp0=divpt(p0, scale);
	tp1=divpt(p1, scale);
	tp2=divpt(p2, scale);
	tp3=divpt(p3, scale);
	if(psdist(tp1, tp0, tp3)<=1 && psdist(tp2, tp0, tp3)<=1){
		appendpt(l, tp0);
		appendpt(l, tp1);
		appendpt(l, tp2);
	}
	else{
		/*
		 * if scale factor is getting too big for comfort,
		 * rescale now & concede the rounding error
		 */
		if(scale>(1<<12)){
			p0=tp0;
			p1=tp1;
			p2=tp2;
			p3=tp3;
			scale=1;
		}
		p01=addpt(p0, p1);
		p12=addpt(p1, p2);
		p23=addpt(p2, p3);
		p012=addpt(p01, p12);
		p123=addpt(p12, p23);
		p0123=addpt(p012, p123);
		bpts1(l, mulpt(p0, 8), mulpt(p01, 4), mulpt(p012, 2), p0123, scale*8);
		bpts1(l, p0123, mulpt(p123, 2), mulpt(p23, 4), mulpt(p3, 8), scale*8);
	}
}
Пример #4
0
Файл: arc.c Проект: 0intro/vx32
/*
 * make a "wedge" mask covering the desired angle and contained in
 * a surrounding square; draw a full ellipse; intersect that with the
 * wedge to make a mask through which to copy src to dst.
 */
void
memarc(Memimage *dst, Point c, int a, int b, int t, Memimage *src, Point sp, int alpha, int phi, int op)
{
	int i, w, beta, tmp, c1, c2, m, m1;
	Rectangle rect;
	Point p,	bnd[8];
	Memimage *wedge, *figure, *mask;

	if(a < 0)
		a = -a;
	if(b < 0)
		b = -b;
	w = t;
	if(w < 0)
		w = 0;
	alpha = -alpha;		/* compensate for upside-down coords */
	phi = -phi;
	beta = alpha + phi;
	if(phi < 0){
		tmp = alpha;
		alpha = beta;
		beta = tmp;
		phi = -phi;
	}
	if(phi >= 360){
		memellipse(dst, c, a, b, t, src, sp, op);
		return;
	}
	while(alpha < 0)
		alpha += 360;
	while(beta < 0)
		beta += 360;
	c1 = alpha/90 & 3;	/* number of nearest corner */
	c2 = beta/90 & 3;
		/*
		 * icossin returns point at radius ICOSSCALE.
		 * multiplying by m1 moves it outside the ellipse
		*/
	rect = Rect(-a-w, -b-w, a+w+1, b+w+1);
	m = rect.max.x;	/* inradius of bounding square */
	if(m < rect.max.y)
		m = rect.max.y;
	m1 = (m+ICOSSCALE-1) >> 10;
	m = m1 << 10;		/* assure m1*cossin is inside */
	i = 0;
	bnd[i++] = Pt(0,0);
	icossin(alpha, &p.x, &p.y);
	bnd[i++] = mulpt(p, m1);
	for(;;) {
		bnd[i++] = mulpt(corners[c1], m);
		if(c1==c2 && phi<180)
			break;
		c1 = (c1+1) & 3;
		phi -= 90;
	}
	icossin(beta, &p.x, &p.y);
	bnd[i++] = mulpt(p, m1);

	figure = nil;
	mask = nil;
	wedge = allocmemimage(rect, GREY1);
	if(wedge == nil)
		goto Return;
	memfillcolor(wedge, DTransparent);
	memfillpoly(wedge, bnd, i, ~0, memopaque, p00, S);
	figure = allocmemimage(rect, GREY1);
	if(figure == nil)
		goto Return;
	memfillcolor(figure, DTransparent);
	memellipse(figure, p00, a, b, t, memopaque, p00, S);
	mask = allocmemimage(rect, GREY1);
	if(mask == nil)
		goto Return;
	memfillcolor(mask, DTransparent);
	memimagedraw(mask, rect, figure, rect.min, wedge, rect.min, S);
	c = subpt(c, dst->r.min);
	memdraw(dst, dst->r, src, subpt(sp, c), mask, subpt(p00, c), op);

    Return:
	freememimage(wedge);
	freememimage(figure);
	freememimage(mask);
}