Nice标签算法超过MAX_TICKS

时间:2015-02-10 12:07:26

标签: c algorithm

我正在使用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_TICKS10滴答)时所需的输出:

enter image description here

如何调整算法以获得7

1 个答案:

答案 0 :(得分:1)

对于minmax具体值-206.13和729.02范围计算为1000.00并且勾选为100.00。但在此之后minmax设置为-300和800,范围扩大到1100.00。你得到11个10个滴答声。解决方案是在设置tickmin时再次计算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);
...