Path: utzoo!utgpu!watmath!clyde!att!pacbell!ames!killer!rpp386!vector!gryphon!elroy!cit-vax!wetter From: wetter@cit-vax.Caltech.Edu (Pierce T. Wetter) Newsgroups: comp.graphics Subject: Re: I need a wheel... Message-ID: <8828@cit-vax.Caltech.Edu> Date: 6 Dec 88 02:59:24 GMT References: <3343@ucdavis.ucdavis.edu> Organization: California Institute of Technology Lines: 67 in article <3343@ucdavis.ucdavis.edu>, vmrad@deneb.ucdavis.edu (0048;0000008890;500;737;56;) says: > > I am currently creating a graph drawing package for our Sophy nuclear > medicine computer. Among the items I wish this package to do is label > the axis with pleasing numbers, and place tick marks at pleasing > intervals. I found that writing a function which produces such > pleasing numbers given the min and max as input is decidedly > non-trivial. Rather than re-invent a wheel, I thought I would try and > tap the collective expertise of comp.graphics. > Here are the two functions I use in a package I wrote about 3 yrs ago. Getdiv returns the spacing between ticks given their minimum and maximum values find start finds a good starting point to start placing ticks at (i.e. if your range is from -27 to 0 use -25. You can also use the value of getdiv to round your numbers. Remember .1 + .1 + .1 + .1 +.1 +.1+ .1 +.1 +.1 +.1 is not equal to 1. This isn't a problem generally, but it is at zero because you have to make sure you label that point 0 not 2e-26. double getdiv(xmn, xmx) double xmn, xmx; { double diff, lgdiff, div, temp; diff = xmx - xmn; diff = sqrt(diff*diff); temp = log10(diff); lgdiff = (double) ((int) (temp + 0.5)); lgdiff -= 1.0; div = 10.0 / wglobals.minorcount * pow(10.0, lgdiff); if ((diff/div) < (2.1*wglobals.minorcount)) div /= 10.0; return (div); } double findstart(xmn, xmx) double xmn; double xmx; { /* find starting point given min max majorspacing*/ double x, dv; int xi, between(); dv = wglobals.minorcount * getdiv(xmn, xmx); /*minorcount is the number of minor ticks per major tick*/ xi = (int) xmn / (dv); x = (xi + 1) * dv; if (between(x, xmn, xmx)) /* xmn<= x <=xmx */ return x; while (!between(x, xmn, xmx) && (x < xmx)) { x += dv; } if (between(x, xmn, xmx)) return x; else return xmn; } Pierce -- ____________________________________________________________________________ You can flame or laud me at: wetter@tybalt.caltech.edu or wetter@csvax.caltech.edu or pwetter@caltech.bitnet (There would be a witty saying here, but my signature has to be < 4lines)