#ifndef NICE_TICKS #define NICE_TICKS #include #include inline double niceNumber(double x, bool round) { const double expv = std::floor(std::log10(x)); const double f = x / std::pow(10.0, expv); double nf; if (round) { if (f < 1.5) nf = 1.0; else if (f < 3.0) nf = 2.0; else if (f < 7.0) nf = 5.0; else nf = 10.0; } else { if (f <= 1.0) nf = 1.0; else if (f <= 2.0) nf = 2.0; else if (f <= 5.0) nf = 5.0; else nf = 10.0; } return nf * std::pow(10.0, expv); } struct NiceTicksResult { double niceMin = 0; double niceMax = 1; double step = 0.2; std::vector ticks; }; inline NiceTicksResult niceTicks(double minv, double maxv, int maxTicks = 5) { NiceTicksResult r; if (minv == maxv) { // 给一个小范围 minv -= 1.0; maxv += 1.0; } const double range = niceNumber(maxv - minv, false); const double step = niceNumber(range / (maxTicks - 1), true); const double niceMin = std::floor(minv / step) * step; const double niceMax = std::ceil(maxv / step) * step; r.niceMin = niceMin; r.niceMax = niceMax; r.step = step; for (double v = niceMin; v <= niceMax + 0.5 * step; v += step) { r.ticks.push_back(v); } return r; } #endif