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

📄 fill.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
/* * fill -- polygon tiler * Updating the edgelist from scanline to scanline could be quicker if no * edges cross:  we can just merge the incoming edges.  If the scan-line * filling routine were a parameter, we could do textured * polygons, polyblt, and other such stuff. */#include "mplot.h"typedef enum{	Odd=1,	Nonzero=~0}Windrule;typedef struct edge Edge;struct edge{	Point p;	/* point of crossing current scan-line */	int maxy;	/* scan line at which to discard edge */	int dx;		/* x increment if x fraction<1 */	int dx1;	/* x increment if x fraction>=1 */	int x;		/* x fraction, scaled by den */	int num;	/* x fraction increment for unit y change, scaled by den */	int den;	/* x fraction increment for unit x change, scaled by num */	int dwind;	/* increment of winding number on passing this edge */	Edge *next;	/* next edge on current scanline */	Edge *prev;	/* previous edge on current scanline */};static void insert(Edge *ep, Edge **yp){	while(*yp && (*yp)->p.x<ep->p.x) yp=&(*yp)->next;	ep->next=*yp;	*yp=ep;	if(ep->next){		ep->prev=ep->next->prev;		ep->next->prev=ep;		if(ep->prev)			ep->prev->next=ep;	}	else		ep->prev=0;}static void polygon(int cnt[], double *pts[], Windrule w, int v){	Edge *edges, *ep, *nextep, **ylist, **eylist, **yp;	Point p, q, p0, p1, p10;	int i, dy, nbig, y, left, right, wind, nwind, nvert;	int *cntp;	double **ptsp, *xp;	nvert=0;	for(cntp=cnt;*cntp;cntp++) nvert+=*cntp;	edges=(Edge *)malloc(nvert*sizeof(Edge));	if(edges==0){	NoSpace:		fprintf(stderr, "polygon: no space\n");		exits("malloc failed");	}	ylist=(Edge **)malloc(Dy(screen->r)*sizeof(Edge *));	if(ylist==0) goto NoSpace;	eylist=ylist+Dy(screen->r);	for(yp=ylist;yp!=eylist;yp++) *yp=0;	ep=edges;	for(cntp=cnt,ptsp=pts;*cntp;cntp++,ptsp++){		p.x=SCX((*ptsp)[*cntp*2-2]);		p.y=SCY((*ptsp)[*cntp*2-1]);		nvert=*cntp;		for(xp=*ptsp,i=0;i!=nvert;xp+=2,i++){			q=p;			p.x=SCX(xp[0]);			p.y=SCY(xp[1]);			if(p.y==q.y) continue;			if(p.y<q.y){				p0=p;				p1=q;				ep->dwind=1;			}			else{				p0=q;				p1=p;				ep->dwind=-1;			}			if(p1.y<=screen->r.min.y) continue;			if(p0.y>=screen->r.max.y) continue;			ep->p=p0;			if(p1.y>screen->r.max.y)				ep->maxy=screen->r.max.y;			else				ep->maxy=p1.y;			p10=subpt(p1, p0);			if(p10.x>=0){				ep->dx=p10.x/p10.y;				ep->dx1=ep->dx+1;			}			else{				p10.x=-p10.x;				ep->dx=-(p10.x/p10.y); /* this nonsense rounds toward zero */				ep->dx1=ep->dx-1;			}			ep->x=0;			ep->num=p10.x%p10.y;			ep->den=p10.y;			if(ep->p.y<screen->r.min.y){				dy=screen->r.min.y-ep->p.y;				ep->x+=dy*ep->num;				nbig=ep->x/ep->den;				ep->p.x+=ep->dx1*nbig+ep->dx*(dy-nbig);				ep->x%=ep->den;				ep->p.y=screen->r.min.y;			}			insert(ep, ylist+(ep->p.y-screen->r.min.y));			ep++;		}	}	left = 0;	for(yp=ylist,y=screen->r.min.y;yp!=eylist;yp++,y++){		wind=0;		for(ep=*yp;ep;ep=nextep){			nwind=wind+ep->dwind;			if(nwind&w){	/* inside */				if(!(wind&w)){					left=ep->p.x;					if(left<screen->r.min.x) left=screen->r.min.x;				}			}			else if(wind&w){				right=ep->p.x;				if(right>=screen->r.max.x) right=screen->r.max.x;#define BART_BUG_FIXED	/* what goes on here?? -rob */#ifdef BART_BUG_FIXED				if(right>left)					line(screen, Pt(left, y), Pt(right, y), Endsquare, Endsquare, 0, getcolor(v), ZP);#else				if(right>left){					switch(v){					default:						segment(&screen, Pt(left, y), Pt(right, y),							~0, D&~S);						segment(&screen, Pt(left, y), Pt(right, y),							v, f);						break;					case 0:						segment(&screen, Pt(left, y), Pt(right, y),							~0, D&~S);						break;					case 3:						segment(&screen, Pt(left, y), Pt(right, y),							v, f);						break;					}				}#endif			}			wind=nwind;			nextep=ep->next;			if(++ep->p.y!=ep->maxy){				ep->x+=ep->num;				if(ep->x>=ep->den){					ep->x-=ep->den;					ep->p.x+=ep->dx1;				}				else					ep->p.x+=ep->dx;				insert(ep, yp+1);			}		}	}	free((char *)edges);	free((char *)ylist);}void fill(int num[], double *ff[]){	polygon(num, ff, Odd, e1->foregr);}

⌨️ 快捷键说明

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