double delta = max - min;
double deltalog = floor(logarithm(delta,type));
/* power of the floor of the log of delta
... e.g. 4000 -> 1000, 323 -> 100 */
double biggeststep = power(deltalog,type);
/* round down the minmum to a multiple of biggeststep */
double minround = min - fmod(min,biggeststep);
/* round min down */
double nicenumber = minround;
/* increase nicenumber by one step */
if (min > nicenumber) {
nicenumber += biggeststep;
}
(the logarithm-/power-wrapper-thing deals with BI- and SI-values separately
It produces results. Relatively good ones.
flaws:
- does not prefere .5-values and even values over others
- does sometimes not produce a zero, but the interval is [-x,+y]
Any ideas to improve this?
Thanks in advance
Algorithm to find the roundest/most beautiful number in a given interval
As the heading says.
Intervals are arbitrarily, positive, negative, huge numbers, very very small numbers.
That's what I am doing at the moment
I've done something like that for a dynamic time scale display. I don't have the code right now, but from the top of my head, it was something like this:
Take the floor of the logarithm of your interval, eg.
then calculate the factor this number has to the obtained next smaller logarithmic whole:
and finally choose the nice number based on where you want to divide a decade:
This should round any given interval into numbers like 0.25, 0.50, 1.00, 2.50, 5.00, 10.00, 25.00, 50.00, 100.00, ...
As I said, I'm not quite sure that's the actual code I used, but maybe it does give you an idea about how to proceed.
-Markus-
EDIT: Fixed a stupid spelling error ;)
[Edited by - Cygon on February 22, 2008 12:39:56 AM]
Take the floor of the logarithm of your interval, eg.
double nextSmallerLog = floor(log10(interval));
then calculate the factor this number has to the obtained next smaller logarithmic whole:
double factor = interval / exp10(nextSmallerLog);
and finally choose the nice number based on where you want to divide a decade:
if(factor < 2.5) niceNumber = exp10(nextSmallerLog) * 2.5;else if(factor < 5.0) niceNumber = exp10(nextSmallerLog) * 5.0;else niceNumber = exp10(nextSmallerLog) * 10;
This should round any given interval into numbers like 0.25, 0.50, 1.00, 2.50, 5.00, 10.00, 25.00, 50.00, 100.00, ...
As I said, I'm not quite sure that's the actual code I used, but maybe it does give you an idea about how to proceed.
-Markus-
EDIT: Fixed a stupid spelling error ;)
[Edited by - Cygon on February 22, 2008 12:39:56 AM]
Thanks for your input.
I adopted your idea, and changed the big if into something better imho.
This rounds the factor to 10,5.0,2.5,1.25,0.625, ... which produces kick-ass values :).
Thanks a lot.
@Antheus:
"Human preference". No periods, prefer .5 over even over odd values ... and and and.
I adopted your idea, and changed the big if into something better imho.
factor = pow(0.5,floor(log10(factor/20.0) / log10(0.5)))*20.0; nicestep = deltalogpower * factor;
This rounds the factor to 10,5.0,2.5,1.25,0.625, ... which produces kick-ass values :).
Thanks a lot.
@Antheus:
"Human preference". No periods, prefer .5 over even over odd values ... and and and.
This is an interesting little gem. Mind if I ask what you are using it for, and what the specific conditions are?
Thanks!
Thanks!
For a "performance"-visualization tool. I need a scales for various purposes.
One is displaying an arbitrary time slice of a program to analyze.
One is displaying an arbitrary time slice of a program to analyze.
Would you mind posting the entire algorithm and an example or two of how it is used? I think I might be able to apply it to some work that I am doing with psychological interpretations of numbers in the stock market...
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement