henesyinit from p9fd787fda5 years agoHistory
701 lines · 12.0 KB · C
RawDownload
#include <u.h>#include <libc.h>#include <stdio.h>#include "iplot.h"#define	INF	1.e+37#define	F	.25 struct xy {	int	xlbf;		/*flag:explicit lower bound*/	int 	xubf;		/*flag:explicit upper bound*/	int	xqf;		/*flag:explicit quantum*/	double (*xf)(double);	/*transform function, e.g. log*/	float	xa,xb;		/*scaling coefficients*/	float	xlb,xub;	/*lower and upper bound*/	float	xquant;		/*quantum*/	float	xoff;		/*screen offset fraction*/	float	xsize;		/*screen fraction*/	int	xbot,xtop;	/*screen coords of border*/		float	xmult;		/*scaling constant*/} xd,yd;struct val {	float xv;	float yv;	int lblptr;} *xx; char *labels;int labelsiz; int tick = 50;int top = 4000;int bot = 200;float absbot;int	n;int	erasf = 1;int	gridf = 2;int	symbf = 0;int	absf = 0;int	transf;int	equf;int	brkf;int	ovlay = 1;float	dx;char	*plotsymb; #define BSIZ 80char	labbuf[BSIZ];char	titlebuf[BSIZ]; char *modes[] = {	"disconnected",	"solid",	"dotted",	"dotdashed",	"shortdashed",	"longdashed"};int mode = 1;double ident(double x){	return(x);} struct z {	float lb,ub,mult,quant;};void init(struct xy *);void setopt(int, char *[]);void readin(void);void transpose(void);void getlim(struct xy *, struct val *);void equilibrate(struct xy *, struct xy *);void scale(struct xy *);void limread(struct xy *, int *, char ***);numb(float *, int *, char ***);int copystring(int);struct z setloglim(int, int, float, float);struct z setlinlim(int, int, float, float);void axes(void);int setmark(int *, struct xy *);void submark(int *, int *, float, struct xy *);void plot(void);int getfloat(float *);int getstring(void);void title(void);void badarg(void);int conv(float, struct xy *, int *);int symbol(int, int, int);void axlab(char, struct xy *, char *); void main(int argc,char *argv[]){ 	openpl();	range(0,0,4096,4096);	init(&xd);	init(&yd);	xd.xsize = yd.xsize = 1.;	xx = (struct val *)malloc((unsigned)sizeof(struct val));	labels = malloc(1);	labels[labelsiz++] = 0;	setopt(argc,argv);	if(erasf)		erase();	readin();	transpose();	getlim(&xd,(struct val *)&xx->xv);	getlim(&yd,(struct val *)&xx->yv);	if(equf) {		equilibrate(&xd,&yd);		equilibrate(&yd,&xd);	}	scale(&xd);	scale(&yd);	axes();	title();	plot();	closepl();	exits(0);} void init(struct xy *p){	p->xf = ident;	p->xmult = 1;} void setopt(int argc, char *argv[]){	char *p1, *p2;	float temp; 	xd.xlb = yd.xlb = INF;	xd.xub = yd.xub = -INF;	while(--argc > 0) {		argv++;again:		switch(argv[0][0]) {		case '-':			argv[0]++;			goto again;		case 'l': /* label for plot */			p1 = titlebuf;			if (argc>=2) {				argv++;				argc--;				p2 = argv[0];				while (*p1++ = *p2++);			}			break; 		case 'd':	/*disconnected,obsolete option*/		case 'm': /*line mode*/			mode = 0;			if(!numb(&temp,&argc,&argv))				break;			if(temp>=sizeof(modes)/sizeof(*modes))				mode = 1;			else if(temp>=-1)				mode = temp;			break; 		case 'o':			if(numb(&temp,&argc,&argv) && temp>=1)				ovlay = temp;			break;		case 'a': /*automatic abscissas*/			absf = 1;			dx = 1;			if(!numb(&dx,&argc,&argv))				break;			if(numb(&absbot,&argc,&argv))				absf = 2;			break; 		case 's': /*save screen, overlay plot*/			erasf = 0;			break; 		case 'g': /*grid style 0 none, 1 ticks, 2 full*/			gridf = 0;			if(!numb(&temp,&argc,&argv))				temp = argv[0][1]-'0';	/*for caompatibility*/			if(temp>=0&&temp<=2)				gridf = temp;			break; 		case 'c': /*character(s) for plotting*/			if(argc >= 2) {				symbf = 1;				plotsymb = argv[1];				argv++;				argc--;			}			break; 		case 't':	/*transpose*/			transf = 1;			break;		case 'e':	/*equal scales*/			equf = 1;			break;		case 'b':	/*breaks*/			brkf = 1;			break;		case 'x':	/*x limits */			limread(&xd,&argc,&argv);			break;		case 'y':			limread(&yd,&argc,&argv);			break;		case 'h': /*set height of plot */			if(!numb(&yd.xsize, &argc,&argv))				badarg();			break;		case 'w': /*set width of plot */			if(!numb(&xd.xsize, &argc, &argv))				badarg();			break;		case 'r': /* set offset to right */			if(!numb(&xd.xoff, &argc, &argv))				badarg();			break;		case 'u': /*set offset up the screen*/			if(!numb(&yd.xoff,&argc,&argv))				badarg();			break;		default:			badarg();		}	}} void limread(struct xy *p, int *argcp, char ***argvp){	if(*argcp>1 && (*argvp)[1][0]=='l') {		(*argcp)--;		(*argvp)++;		p->xf = log10;	}	if(!numb(&p->xlb,argcp,argvp))		return;	p->xlbf = 1;	if(!numb(&p->xub,argcp,argvp))		return;	p->xubf = 1;	if(!numb(&p->xquant,argcp,argvp))		return;	p->xqf = 1;} isdigit(char c){	return '0'<=c && c<='9';}numb(float *np, int *argcp, char ***argvp){	char c; 	if(*argcp <= 1)		return(0);	while((c=(*argvp)[1][0]) == '+')		(*argvp)[1]++;	if(!(isdigit(c) || c=='-'&&(*argvp)[1][1]<'A' || c=='.'))		return(0);	*np = atof((*argvp)[1]);	(*argcp)--;	(*argvp)++;	return(1);} void readin(void){	int i, t;	struct val *temp; 	if(absf==1) {		if(xd.xlbf)			absbot = xd.xlb;		else if(xd.xf==log10)			absbot = 1;	}	for(;;) {		temp = (struct val *)realloc((char*)xx,			(unsigned)(n+ovlay)*sizeof(struct val));		if(temp==0)			return;		xx = temp;		if(absf)			xx[n].xv = n*dx/ovlay + absbot;		else			if(!getfloat(&xx[n].xv))				return;		t = 0;	/* silence compiler */		for(i=0;i<ovlay;i++) {			xx[n+i].xv = xx[n].xv;			if(!getfloat(&xx[n+i].yv))				return;			xx[n+i].lblptr = -1;			t = getstring();			if(t>0)				xx[n+i].lblptr = copystring(t);			if(t<0 && i+1<ovlay)				return;		}		n += ovlay;		if(t<0)			return;	}} void transpose(void){	int i;	float f;	struct xy t;	if(!transf)		return;	t = xd; xd = yd; yd = t;	for(i= 0;i<n;i++) {		f = xx[i].xv; xx[i].xv = xx[i].yv; xx[i].yv = f;	}} int copystring(int k){	char *temp;	int i;	int q; 	temp = realloc(labels,(unsigned)(labelsiz+1+k));	if(temp==0)		return(0);	labels = temp;	q = labelsiz;	for(i=0;i<=k;i++)		labels[labelsiz++] = labbuf[i];	return(q);} float modceil(float f, float t){ 	t = fabs(t);	return(ceil(f/t)*t);} floatmodfloor(float f, float t){	t = fabs(t);	return(floor(f/t)*t);} void getlim(struct xy *p, struct val *v){	int i; 	i = 0;	do {		if(!p->xlbf && p->xlb>v[i].xv)			p->xlb = v[i].xv;		if(!p->xubf && p->xub<v[i].xv)			p->xub = v[i].xv;		i++;	} while(i < n);} void setlim(struct xy *p){	float t,delta,sign;	struct z z;	int mark[50];	float lb,ub;	int lbf,ubf; 	lb = p->xlb;	ub = p->xub;	delta = ub-lb;	if(p->xqf) {		if(delta*p->xquant <=0 )			badarg();		return;	}	sign = 1;	lbf = p->xlbf;	ubf = p->xubf;	if(delta < 0) {		sign = -1;		t = lb;		lb = ub;		ub = t;		t = lbf;		lbf = ubf;		ubf = t;	}	else if(delta == 0) {		if(ub > 0) {			ub = 2*ub;			lb = 0;		} 		else			if(lb < 0) {				lb = 2*lb;				ub = 0;			} 			else {				ub = 1;				lb = -1;			}	}	if(p->xf==log10 && lb>0 && ub>lb) {		z = setloglim(lbf,ubf,lb,ub);		p->xlb = z.lb;		p->xub = z.ub;		p->xmult *= z.mult;		p->xquant = z.quant;		if(setmark(mark,p)<2) {			p->xqf = lbf = ubf = 1;			lb = z.lb; ub = z.ub;		} else			return;	}	z = setlinlim(lbf,ubf,lb,ub);	if(sign > 0) {		p->xlb = z.lb;		p->xub = z.ub;	} else {		p->xlb = z.ub;		p->xub = z.lb;	}	p->xmult *= z.mult;	p->xquant = sign*z.quant;} struct zsetloglim(int lbf, int ubf, float lb, float ub){	float r,s,t;	struct z z; 	for(s=1; lb*s<1; s*=10) ;	lb *= s;	ub *= s;	for(r=1; 10*r<=lb; r*=10) ;	for(t=1; t<ub; t*=10) ;	z.lb = !lbf ? r : lb;	z.ub = !ubf ? t : ub;	if(ub/lb<100) {		if(!lbf) {			if(lb >= 5*z.lb)				z.lb *= 5;			else if(lb >= 2*z.lb)				z.lb *= 2;		}		if(!ubf) {			if(ub*5 <= z.ub)				z.ub /= 5;			else if(ub*2 <= z.ub)				z.ub /= 2;		}	}	z.mult = s;	z.quant = r;	return(z);} struct zsetlinlim(int lbf, int ubf, float xlb, float xub){	struct z z;	float r,s,delta;	float ub,lb; loop:	ub = xub;	lb = xlb;	delta = ub - lb;	/*scale up by s, a power of 10, so range (delta) exceeds 1*/	/*find power of 10 quantum, r, such that delta/10<=r<delta*/	r = s = 1;	while(delta*s < 10)		s *= 10;	delta *= s;	while(10*r < delta)		r *= 10;	lb *= s;	ub *= s;	/*set r=(1,2,5)*10**n so that 3-5 quanta cover range*/	if(r>=delta/2)		r /= 2;	else if(r<delta/5)		r *= 2;	z.ub = ubf? ub: modceil(ub,r);	z.lb = lbf? lb: modfloor(lb,r);	if(!lbf && z.lb<=r && z.lb>0) {		xlb = 0;		goto loop;	}	else if(!ubf && z.ub>=-r && z.ub<0) {		xub = 0;		goto loop;	}	z.quant = r;	z.mult = s;	return(z);} void scale(struct xy *p){	float edge; 	setlim(p);	edge = top-bot;	p->xa = p->xsize*edge/((*p->xf)(p->xub) - (*p->xf)(p->xlb));	p->xbot = bot + edge*p->xoff;	p->xtop = p->xbot + (top-bot)*p->xsize;	p->xb = p->xbot - (*p->xf)(p->xlb)*p->xa + .5;

Lines 1–500 of 701.