#ifndef NICE_TICKS
#define NICE_TICKS

#include <cmath>
#include <vector>

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<double> 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