我正在使用 Nice Numbers for Graph Labels算法(由 Andrew S. Glassner 编写),但在某些数字上,例如:(最小值:-206.13 最大值:729.02),它返回的 Ticks 多于 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
刻度):
如何调整算法以获得<= MAX_TICKS
?
最佳答案
对于 min
和 max
特定值 -206.13 和 729.02 范围计算为 1000.00,tick 为 100.00。但在那之后,min
和 max
被设置为 -300 和 800,从而将范围扩展到 1100.00。你得到了 11 次,共 10 次。解决方案是在设置了 min
和 max
时再次计算 tick
:
...
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);
...
关于c - Nicelabel 算法超过 MAX TICKS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28431265/