⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bezier.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include <u.h>#include <libc.h>#include <draw.h>#define	PINC	32		/* realloc granularity */typedef struct Plist Plist;struct Plist{	Point *p;	int np;			/* -1 if malloc/realloc failed */};static voidappendpt(Plist *l, Point p){	if(l->np == -1)		return;	if(l->np == 0)		l->p = malloc(PINC*sizeof(Point));	else if(l->np%PINC == 0)		l->p = realloc(l->p, (l->np+PINC)*sizeof(Point));	if(l->p == 0){		l->np = -1;		return;	}	l->p[l->np++] = p;}static intnormsq(Point p){	return p.x*p.x+p.y*p.y;}static intpsdist(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));}/* * Convert cubic Bezier curve control points to polyline * vertices.  Leaves the last vertex off, so you can continue * with another curve. */static voidbpts1(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);	}}static voidbpts(Plist *l, Point p0, Point p1, Point p2, Point p3){	bpts1(l, p0, p1, p2, p3, 1);}static voidbezierpts(Plist *l, Point p0, Point p1, Point p2, Point p3){	bpts(l, p0, p1, p2, p3);	appendpt(l, p3);}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);}intbezsplinepts(Point *pt, int npt, Point **pp){	Plist l;	l.np = 0;	l.p = nil;	_bezsplinepts(&l, pt, npt);	*pp  = l.p;	return l.np;}intbezier(Image *dst, Point p0, Point p1, Point p2, Point p3, int end0, int end1, int radius, Image *src, Point sp){	return bezierop(dst, p0, p1, p2, p3, end0, end1, radius, src, sp, SoverD);}intbezierop(Image *dst, Point p0, Point p1, Point p2, Point p3, int end0, int end1, int radius, Image *src, Point sp, Drawop op){	Plist l;	l.np = 0;	bezierpts(&l, p0, p1, p2, p3);	if(l.np == -1)		return 0;	if(l.np != 0){		polyop(dst, l.p, l.np, end0, end1, radius, src, addpt(subpt(sp, p0), l.p[0]), op);		free(l.p);	}	return 1;}intbezspline(Image *dst, Point *pt, int npt, int end0, int end1, int radius, Image *src, Point sp){	return bezsplineop(dst, pt, npt, end0, end1, radius, src, sp, SoverD);}intbezsplineop(Image *dst, Point *pt, int npt, int end0, int end1, int radius, Image *src, Point sp, Drawop op){	Plist l;	l.np = 0;	_bezsplinepts(&l, pt, npt);	if(l.np==-1)		return 0;	if(l.np != 0){		polyop(dst, l.p, l.np, end0, end1, radius, src, addpt(subpt(sp, pt[0]), l.p[0]), op);		free(l.p);	}	return 1;}intfillbezier(Image *dst, Point p0, Point p1, Point p2, Point p3, int w, Image *src, Point sp){	return fillbezierop(dst, p0, p1, p2, p3, w, src, sp, SoverD);}intfillbezierop(Image *dst, Point p0, Point p1, Point p2, Point p3, int w, Image *src, Point sp, Drawop op){	Plist l;	l.np = 0;	bezierpts(&l, p0, p1, p2, p3);	if(l.np == -1)		return 0;	if(l.np != 0){		fillpolyop(dst, l.p, l.np, w, src, addpt(subpt(sp, p0), l.p[0]), op);		free(l.p);	}	return 1;}intfillbezspline(Image *dst, Point *pt, int npt, int w, Image *src, Point sp){	return fillbezsplineop(dst, pt, npt, w, src, sp, SoverD);}intfillbezsplineop(Image *dst, Point *pt, int npt, int w, Image *src, Point sp, Drawop op){	Plist l;	l.np = 0;	_bezsplinepts(&l, pt, npt);	if(l.np == -1)		return 0;	if(l.np > 0){		fillpolyop(dst, l.p, l.np, w, src, addpt(subpt(sp, pt[0]), l.p[0]), op);		free(l.p);	}	return 1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -