我正在使用Nice Numbers for Graph Labels算法(由Andrew S. Glassner提供),但在某些数字上,例如:(min:-206.13 max:729.02),它返回的刻度比{{1}更多}:
MAX_TICKS
在此示例中#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#define MARGIN " "
#define MARGIN_LEN 10
#define MAX_TICKS 10
#define NVALUES 10
#define WIDTH 70
static double nice(double range, int round)
{
double exponent;
double fraction;
double nicefrac;
exponent = floor(log10(range));
fraction = range / pow(10, exponent);
if (round) {
if (fraction < 1.5)
nicefrac = 1.0;
else
if (fraction < 3.0)
nicefrac = 2.0;
else
if (fraction < 7.0)
nicefrac = 5.0;
else
nicefrac = 10.0;
} else {
if (fraction <= 1.0)
nicefrac = 1.0;
else
if (fraction <= 2.0)
nicefrac = 2.0;
else
if (fraction <= 5.0)
nicefrac = 5.0;
else
nicefrac = 10.0;
}
return nicefrac * pow(10, exponent);
}
static double calc(double range, int ticks)
{
double tick;
range = nice(fabs(range), 0);
tick = nice(range / (ticks - 1), 1);
return tick;
}
int main(void)
{
double value[NVALUES], min, max, tick, sum;
int ticks, width, wtick, wzero, wcurr;
int i, j;
srand(time(NULL));
for (i = 0; i < NVALUES; i++) {
value[i] = (rand() % 100000) / 100.0 - 250.0;
}
min = max = value[0];
for (i = 0; i < NVALUES; i++) {
if (value[i] < min) min = value[i];
if (value[i] > max) max = value[i];
}
printf("MIN = %.2f | MAX = %.2f\n", min, max);
if (min > 0.0) min = 0.0;
if (max < 0.0) max = 0.0;
tick = calc(max - min, MAX_TICKS);
min = floor(min / tick) * tick;
max = ceil(max / tick) * tick;
ticks = (int)((max - min) / tick);
width = (int)(floor(WIDTH / ticks) * ticks);
wtick = (int)(width / ticks);
wzero = (int)ceil(((0.0 - min) / (max - min)) * width);
printf("MIN = %.2f | MAX = %.2f | TICK = %.2f | TICKS = %d\n", min, max, tick, ticks);
printf("\n" MARGIN);
sum = min;
for (i = 0; i <= ticks; i++) {
printf("%-*.*f", wtick, tick == (int)tick ? 0 : 2, sum);
sum += tick;
}
printf("\n" MARGIN);
for (i = 0; i <= ticks; i++) {
printf("%-*s", wtick, "|");
}
printf("\n");
for (i = 0; i < NVALUES; i++) {
printf("%*.2f ", MARGIN_LEN - 1, value[i]);
wcurr = (int)round(((value[i] - min) / (max - min)) * width);
if (value[i] < 0.0) {
for (j = 0; j < wzero; j++)
printf("%c", j < wcurr ? ' ' : '*');
} else {
for (j = 0; j < wcurr; j++)
printf("%c", j < wzero ? ' ' : '*');
}
printf("\n");
}
return 0;
}
,但我得到MAX_TICKS = 10
刻度:
11
MIN = -206.13 | MAX = 729.02
MIN = -300.00 | MAX = 800.00 | TICK = 100.00 | TICKS = 11
-300 -200 -100 0 100 200 300 400 500 600 700 800
| | | | | | | | | | | |
729.02 ********************************************
701.07 ******************************************
-84.62 *****
462.44 ****************************
387.91 ***********************
683.73 *****************************************
631.30 **************************************
146.09 *********
663.66 ****************************************
-206.13 ************
= MAX_TICKS
(10
滴答)时所需的输出:
如何调整算法以获得7
?
答案 0 :(得分:1)
对于min
和max
具体值-206.13和729.02范围计算为1000.00并且勾选为100.00。但在此之后min
和max
设置为-300和800,范围扩大到1100.00。你得到11个10个滴答声。解决方案是在设置tick
和min
时再次计算max
:
...
if (min > 0.0) min = 0.0;
if (max < 0.0) max = 0.0;
tick = calc(max - min, MAX_TICKS);
min = floor(min / tick) * tick;
max = ceil(max / tick) * tick;
if ( ((max - min) / tick) > MAX_TICKS) {
tick = calc(max - min, MAX_TICKS);
min = floor(min / tick) * tick;
max = ceil(max / tick) * tick;
}
ticks = (int)((max - min) / tick);
...