Path: utzoo!utgpu!watmath!clyde!att!rutgers!mailrus!ncar!ames!pasteur!miro.Berkeley.EDU!ph
From: ph@miro.Berkeley.EDU (Paul Heckbert)
Newsgroups: comp.graphics
Subject: Re: I need a wheel...
Message-ID: <7945@pasteur.Berkeley.EDU>
Date: 2 Dec 88 22:34:51 GMT
References: <3343@ucdavis.ucdavis.edu>
Sender: news@pasteur.Berkeley.EDU
Reply-To: ph@miro.Berkeley.EDU (Paul Heckbert)
Organization: University of California at Berkeley
Lines: 108
Keywords:

In article <3343@ucdavis.ucdavis.edu> vmrad@deneb.ucdavis.edu
asked for code to label axes with pleasing numbers and place tick marks
at pleasing intervals.

Here is some code I've used.
The heart of it is a simple little routine called "nicenum" that picks
"nice-looking" numbers.

The below is geared toward y axis labeling but of course it could
work equally well for the x axis.

Paul Heckbert, CS grad student
508-7 Evans Hall, UC Berkeley		UUCP: ucbvax!miro.berkeley.edu!ph
Berkeley, CA 94720			ARPA: ph@miro.berkeley.edu

/*
 * label: test program to demonstrate nice graph axis labeling
 *
 * Paul Heckbert, 2 Dec 88
 */

#include 
#include 
double expt(), tick(), nicenum();

#define NTICK 5			/* desired number of tick marks */

main(ac, av)
int ac;
char **av;
{
    double ymin, ymax;

    if (ac!=3) {
	fprintf(stderr, "Usage: label  \n");
	exit(1);
    }
    ymin = atof(av[1]);
    ymax = atof(av[2]);

    ylabel(ymin, ymax);
}

ylabel(ymin, ymax)
double ymin, ymax;
{
    char str[6], temp[20];
    int exp;
    double graphymin, graphymax, range, d, y;

    /* we expect ymin!=ymax */
    range = nicenum(ymax-ymin, 0);
    d = nicenum(range/(NTICK-1), 1);		/* tick mark spacing */
    graphymin = floor(ymin/d)*d;
    graphymax = ceil(ymax/d)*d;
    exp = floor(log10(d));
    sprintf(str, "%%.%df", exp<0 ? -exp : 0);	/* simplest axis labels */

    printf("graphymin=%g graphymax=%g increment=%g\n", graphymin, graphymax, d);
    for (y=graphymin; y0) for (; n>0; n--) x *= a;
    else for (; n<0; n++) x /= a;
    return x;
}