home *** CD-ROM | disk | FTP | other *** search
- #include "all.h"
-
- #include "justify.h"
- #include "axis.h"
- #include <math.h>
- #include "mygraph.h"
- int start_subtick(double *tick1, double gmin, double dticks);
- int nice_ticks(double *dticks, double *gmin,double *gmax
- , double *t1,double *tn,int minset, int maxset);
- int numtrim(char **d,char *s, double dticks);
-
- int nice_log_ticks(double *start, double *last, double *gmin, double *gmax);
- double fnloglen(double v,struct axis_struct *ax);
- double fnlogx(double v,struct axis_struct *ax);
- int fnbig(double v);
-
- #define fnx(vv) (((vv-gmin)/(gmax-gmin)) * ax->length)
- #define fnlx(vv) fnlogx(vv,ax)
- #define true (!false)
- #define false 0
- struct axis_struct ax;
-
- #define kw(ss) if (strcmp(tok(ct),ss)==0)
-
- draw_axis(struct axis_struct *ax) /* Draws the axis */
- {
- double fi,x,y,gmin,gmax,dticks,tick1,tickn;
- int i,xax,n,savecap,dolittle;
- int isbig;
- double tlen,stlen,dsubticks,tt,t,start;
- double h,label_width,dist;
- double bl,br,bu,bd;
- double ox,oy,llen,maxd,maxwid,ty,tx;
- double th;
-
- if (ax->type==1 || ax->type==3) xax = true; else xax = false;
- g_source("BEGIN AXIS =====\n");
- /*! Return if side is turned OFF*/
- if (ax->off) return ;
- #define dont if (1==2)
- /*! Ok lets draw the side first. */
- g_get_line_cap(&savecap);
- g_get_xy(&ox,&oy);
- g_gsave();
- g_set_color(ax->side_color);
- g_set_line_width(ax->side_lwidth);
- g_set_line_style(ax->side_lstyle);
- if (!ax->side_off) {
- g_set_line_cap(1);
- g_get_xy(&x,&y);
- if (xax)
- g_line(x+ax->length,y);
- else
- g_line(x,y+ax->length);
- }
- g_grestore();
- g_set_line_cap(savecap);
-
- /*----------------------------- Generate the places for labels to go */
- gmin = ax->min;
- gmax = ax->max;
-
- if (ax->log) { /* generate places for log main ticks */
- if (!ax->lgset) {
- /* dist between 10^0 and 10^1 */
- dist = fnloglen(2,ax) - fnloglen(1,ax);
- if (dist > ax->base*4.5) ax->lg25 = true;
- if (dist > ax->base*22.0) ax->lg1 = true;
- }
- nice_log_ticks(&tick1,&tickn,&gmin,&gmax);
- if (ax->nplaces == 0) { /* haven't been set, so generate positions. */
- for (fi=tick1; fi<= tickn+(pow(10.0,floor(log10(fi)+.0001)))/100
- ; fi += pow(10.0,floor(log10(fi)+.0001))) {
- i = floor(.0001 + fi/pow(10.0,floor(log10(fi))));
- if (fnbig(fi) || (ax->lg1) || (ax->lg25 && ((i==2) || (i==5))) ) {
- if (++(ax->nplaces)>199) {gprint("Too many places\n");return;}
- ax->places[ax->nplaces] = fi;
- }
- }
- }
- } else {
- dticks = 0;
- if (ax->nticks!=0) dticks = (gmax - gmin)/ax->nticks;
- if (ax->dticks!=0) dticks = ax->dticks ;
- if (dticks>0) if ((gmax - gmin)/dticks>90) {gprint("too many ticks \n"); dticks = 0;}
-
- nice_ticks(&dticks, &gmin, &gmax, &tick1, &tickn,ax->minset,ax->maxset);
-
- if (ax->nofirst) tick1 = tick1 + dticks;
- if (ax->nolast) tickn = tickn - dticks;
- tickn = tickn + dticks/100; /* to avoid rounding errors */
- if (ax->nplaces == 0) { /* haven't been set, so generate positions. */
- { double end_tick = (tickn+dticks/100.0);
- for (fi=tick1; fi<=end_tick; fi += dticks) {
- if (++(ax->nplaces)>49) {gprint("Too many places\n");return;}
- ax->places[ax->nplaces] = fi;
- }
- }
- }
- }
-
- /*------------------------------ Now draw the ticks (subticks first) */
- g_gsave();
-
- tlen = ax->base/5;
- if (ax->ticks_length!=0) tlen = ax->ticks_length;
- /* first the subticks */
- stlen = tlen/2;
- if (ax->subticks_length!=0) stlen = ax->subticks_length;
- dsubticks = 0;
-
- if (!ax->log) { /* Draw little log ticks if enough space */
- if (ax->nsubticks!=0) dsubticks = (dticks)/(ax->nsubticks+1);
- if (ax->dsubticks!=0) dsubticks = ax->dsubticks;
- if (dsubticks==0) dsubticks = dticks / 2.0;
- if ((gmax - gmin)/dsubticks>2000) {gprint("too many subticks \n");
- dsubticks = dticks;}
-
- start_subtick(&tick1, gmin, dsubticks);
- g_set_color(ax->subticks_color);
- g_set_line_width(ax->subticks_lwidth);
- g_set_line_style(ax->subticks_lstyle);
- if (ax->type>2) t = -stlen; else t = stlen;
- if (!ax->subticks_off) {
- if (dsubticks==0) dsubticks = dticks / 2.0;
- for (fi=tick1; fi<=gmax; fi += dsubticks) {
- /* if (!fnbig(fi)) { */
- if (xax) {
- g_move(ox+fnx(fi),oy);
- g_line(ox+fnx(fi),oy+t);
- } else {
- g_move(ox,fnx(fi)+oy);
- g_line(ox+t,oy+fnx(fi));
- }
- /* } */
- }
- }
- }
-
- /*------------------------------ Now the main ticks */
- g_set_color(ax->ticks_color);
- g_set_line_width(ax->ticks_lwidth);
- g_set_line_style(ax->ticks_lstyle);
-
- if (ax->type>2) t = -tlen; else t = tlen;
- if (ax->type>2) tt = -stlen; else tt = stlen;
- if (!ax->ticks_off) {
- if (ax->log) { /* Draw log ticks */
- g_set_color(ax->subticks_color);
- g_set_line_width(ax->subticks_lwidth);
- g_set_line_style(ax->subticks_lstyle);
- nice_log_ticks(&tick1,&tickn,&gmin,&gmax);
- for (fi=tick1; fi<= tickn+(pow(10.0,floor(log10(fi)+.0001)))/100
- ; fi += pow(10.0,floor(log10(fi)+.0001))) {
- i = floor(fi/pow(10.0,floor(log10(fi))));
- isbig = (fnbig(fi));
- if (isbig) {
- x = t;
- g_set_color(ax->ticks_color);
- g_set_line_width(ax->ticks_lwidth);
- g_set_line_style(ax->ticks_lstyle);
- } else x = tt;
- if (xax) {
- g_move(ox+fnlx(fi),oy);
- g_line(ox+fnlx(fi),oy+x);
- } else {
- g_move(ox,fnlx(fi)+oy);
- g_line(ox+x,oy+fnlx(fi));
- }
- if (isbig) {
- g_set_color(ax->subticks_color);
- g_set_line_width(ax->subticks_lwidth);
- g_set_line_style(ax->subticks_lstyle);
- }
- }
- } else {
- for (i=1;i<=ax->nplaces; i++) {
- fi = ax->places[i];
- if (xax) {
- g_move(ox+fnx(fi),oy);
- g_line(ox+fnx(fi),oy+t);
- } else {
- g_move(ox,fnx(fi)+oy);
- g_line(ox+t,oy+fnx(fi));
- }
- }
- }
- }
- g_grestore();
- /*------------------------------ Now draw the labels */
- llen = 0;
- if (tlen<0) llen = -tlen;
- h = ax->label_hei;
- if (h==0) h = ax->base;
- llen = llen + h*.5;
- if (ax->label_dist!=0) llen = ax->label_dist;
-
- {char cbuff[100];
- if (ax->nnam==0) {
- if (ax->log) {
- if (log10(gmax)-log10(gmin) < 5) dolittle = true;
- else dolittle = false;
- for (i=1;i<=ax->nplaces; i++) {
- fi = ax->places[i];
- n = floor(.0001 + fi/pow(10.0,floor(log10(fi))));
- if (fnbig(fi)) {
- n = floor(log10(fi)+.5);
- sprintf(cbuff,"10\\sup {%d}",n);
- mystrcpy(&ax->names[i],cbuff);
- } else {
- if (dolittle) {
- n = floor(.0001 + fi/(pow(10.0,floor(log10(fi)))));
- sprintf(cbuff,"{\\sethei{%g}%d}",h*.7,n);
- mystrcpy(&ax->names[i],cbuff);
- }
- }
- }
- ax->nnam = ax->nplaces;
- } else {
- for (i=1;i<=ax->nplaces; i++) {
- fi = ax->places[i];
- x = fabs(fi);
- if (x<.00001*dticks) {fi = 0; x = 0;}
- if (ax->decimal>0) {
- sprintf(cbuff,"%.*f",ax->decimal,fi);
- ax->names[i] = myallocz(20);
- strncpy(ax->names[i],cbuff,19);
- } else {
- if (fi==0 || (x>1e-5 && x<1e6)) sprintf(cbuff,"%f",fi);
- else sprintf(cbuff,"%e",fi);
- numtrim(&ax->names[i],cbuff,dticks);
- }
- }
- ax->nnam = ax->nplaces;
- }
- }}
- g_set_color(ax->label_color);
- g_set_line_width(ax->label_lwidth);
- g_set_line_style(ax->label_lstyle);
- g_set_font(ax->label_font);
- g_set_hei(h);
- maxd = 0;
- maxwid = 0;
- tx = ox-.3*h; /* I wonder what tx should be set to ??? */
- if (ax->type==4) tx = ox + .3*h;
- if (ax->type==1) ty = oy-llen-.3*h;
- if (ax->type==3) ty = oy+llen;
- if (!ax->label_off) {
- for (i=1;i<=ax->nnam;i++) {
- g_measure(ax->names[i],&bl,&br,&bu,&bd);
- if (bd>maxd) maxd = bd;
- if (bl+br>maxwid) maxwid = bl+br;
- }
- for (i=1;i<=ax->nnam;i++) {
- g_measure(ax->names[i], &bl, &br,&bu,&bd);
- fi = fnx(ax->places[i]);
- if (ax->log) fi = fnlx(ax->places[i]);
- switch (ax->type) {
- case 1: /* xaxis */
- y = oy-llen-bu+bd-.3*h;
- if (y<ty) ty = y;
- g_move(ox+fi+ax->shift,oy-llen-(.7*h) );
- g_jtext(JUST_CENTRE);
- break;
- case 2: /* yaxis */
- x = ox-br+bl-llen-.3*h;
- /* bug here with axis labels 0 10 20, nofirst */
- if (i!=1 && i!=ax->nnam) if (x<tx) tx = x;
- g_move(ox -llen ,oy+fi+ax->shift);
- g_jtext(JUST_RC);
- break;
- case 3: /* x2axis */
- y = oy+llen+maxd+bu;
- if (y>ty) ty = y;
- g_move(ox+fi+ax->shift,oy+llen+maxd);
- g_jtext(JUST_CENTRE);
- break;
- case 4: /* y2axis */
- x = ox+br-bl+llen+.3*h;
- if (i!=1 && i!=ax->nnam) if (x>tx) tx = x;
- g_move(ox+llen ,oy + fi +ax->shift);
- g_jtext(JUST_LC);
- break;
- }
- if (bd>maxd) maxd = bd;
- if (bl+br>maxwid) maxwid = bl+br;
- }
- }
- /*---------------------------------- Now the axis title. */
-
- if (ax->title==NULL) return;
- g_gsave();
- th = h * 1.3;
- if (ax->title_scale!=0) th = th*ax->title_scale ;
- if (ax->title_hei!=0) th = ax->title_hei ;
- g_set_color(ax->title_color);
- g_set_font(ax->title_font);
- g_set_hei(th);
- g_measure(ax->title,&bl,&br,&bu,&bd);
- if (!ax->title_off) {
- switch (ax->type) {
- case 1: /* xaxis */
- g_move(ox+ax->length/2,ty - ax->title_dist);
- g_jtext(JUST_TC);
- break;
- case 2: /* yaxis */
- g_move(tx - ax->title_dist,oy + ax->length/2);
- g_rotate(90.0);
- g_jtext(JUST_BC);
- g_rotate(-90.0);
- break;
- case 3: /* x2axis */
- g_move(ox+ax->length/2,ty + ax->title_dist);
- g_jtext(JUST_BC);
- break;
- case 4: /* y2axis */
- g_move(tx + ax->title_dist,oy + ax->length/2);
- if (ax->title_rot) {
- g_rotate(-90.0);
- g_jtext(JUST_BC);
- g_rotate(90.0);
- } else {
- g_rotate(90.0);
- g_jtext(JUST_TC);
- g_rotate(-90.0);
- }
- break;
- }
- }
- g_grestore();
- g_move(ox,oy);
- g_source("END AXIS ===== \n");
- }
- /*-------------------------------------------------------------------------*/
- nice_ticks(double *dticks, double *gmin,double *gmax
- , double *t1,double *tn,int minset, int maxset)
- {
- double delta,st,expnt,n;
- int ni;
-
- /* GMIN AND GMAX are set in GRAPH2.C in setrange() */
- /* printf("nice %g %g %g \n",*gmin,*gmax,*dticks); */
- delta = *gmax-*gmin;
- if (delta==0) {gprint("Axis range error min=%g max=%g \n",*gmin,*gmax);
- *gmax = *gmin+10;
- delta = 10;
- }
- st = delta/10;
- expnt = floor(log10(st));
- n = st/pow(10,expnt);
- if (n>5)
- ni = 10;
- else if (n>2)
- ni = 5;
- else if (n>1)
- ni = 2;
- else
- ni = 1;
- if (*dticks==0) *dticks = ni * pow(10,expnt);
- if (*gmin - (delta/1000) <= floor( *gmin/ *dticks) * *dticks)
- *t1 = *gmin;
- else
- *t1 = (floor(*gmin/ *dticks) * *dticks ) + *dticks;
-
- *tn = *gmax;
- if (( floor( *gmax/ *dticks) * *dticks) < (*gmax - (delta/1000) ))
- *tn = floor(*gmax/ *dticks ) * *dticks;
- }
- /*-------------------------------------------------------------------------*/
- double chop(double f);
- double chop(double f)
- {
- return (double) (long) f;
- }
- /*-------------------------------------------------------------------------*/
- start_subtick(double *tick1, double gmin, double dticks)
- {
- if (gmin == chop(gmin/dticks) * dticks)
- *tick1 = gmin;
- else
- *tick1 = chop(gmin/dticks) * dticks + dticks;
- }
- /*-------------------------------------------------------------------------*/
- numtrime(char *o,char *s)
- {
- char *nonzero;
- char *e,*f;
-
- strcpy(o,s);
-
- e = strchr(s,'e');
- if (e==NULL) return;
-
- e--;
- for (; *e=='0'; e--) ;
-
- f = strchr(s,'e');
- strcpy(e+1,f);
- strcpy(o,s);
-
- }
- /*-------------------------------------------------------------------------*/
- numtrim(char **d,char *s,double dticks)
- {
- char *o,*nonzero=0;
-
- if (*d==0) *d = myallocz(20);
- o = *d;
- nonzero = 0;
- if (strchr(s,'e')!=NULL) {
- numtrime(o,s);
- return;
- }
- while (*s==' ' && *s!=0) s++;
- while (*s!=0) {
- *(o++) = *(s++);
- if (*s=='.') {
- nonzero = o-1;
- if (dticks!=floor(dticks)) nonzero = o+1;
- while (*s!=0) {
- *(o++) = *(s++);
- if ((*s!='0') && (*s!=0))
- if (o>nonzero) nonzero = o;
- }
- }
- }
- *(o++) = 0;
- if (nonzero!=NULL) *(nonzero+1) = 0;
- }
- /*-------------------------------------------------------------------------*/
- nice_log_ticks(double *start, double *last, double *gmin, double *gmax)
- {
- double sz;
-
- if (*gmin<=0) {
- gprint("FATAL ERROR, LOG AXIS WITH MIN OF ZERO***\n");
- *gmin = 1;
- }
- if (*gmax<=0) *gmax = 10;
- *start = pow(10.0,floor(log10(*gmin)));
-
- if (floor(log10(*gmin)) != log10(*gmin)) {
- sz = pow(10.0,floor(log10(*gmin)));
- *start = floor((*gmin)/sz)*sz + sz;
- if (*start>(*gmin+sz-sz/100)) *start = *start - sz;
- }
- *last = floor(log10(*gmax))+1;
- if (floor(log10(*gmax))==log10(*gmax)) {
- --*last;
- *last = pow(10.0,*last);
- } else {
- *last = pow(10.0,*last-1);
- *last = floor((*gmax) / *last) * *last;
- }
- }
- double fnloglen(double v,struct axis_struct *ax) /* Dist in cm in log axis */
- {
- return ((v-log10(ax->min))/(log10(ax->max)-log10(ax->min))) * ax->length;
- }
- double fnlogx(double v,struct axis_struct *ax)
- {
- return fnloglen(log10(v),ax);
- }
- fnbig(double v)
- {
- if (fabs(log10(v)-floor(log10(v)+.5)) < .001)
- return true;
- else return false;
- }
-
-
-
-
-