53 lines
1.3 KiB
C++
53 lines
1.3 KiB
C++
#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 |