БлогNot. Как посчитать ближайшую снизу натуральную степень десятки

Как посчитать ближайшую снизу натуральную степень десятки

Грубо говоря, нужна вот такая зависимость, которая может пригодиться, например, при масштабировании сетки графика. Картинка из Mathcad уже даёт ответ на вопрос (масштаб по обеим осям - логарифмический), а ниже напишем операторы на Visual C++.

ближайшая снизу степень 10, но не менее 1
ближайшая снизу степень 10, но не менее 1

Предполагается, что мы пользуемся средствами .NET в Studio 2015 или выше и применяем для построения графика компоненту Chart.

Допустим, у нас известен интервал [minX,maxX], в который попадают отображаемые значения оси X, для значений оси Y расчёт выполняется полностью по аналогии.

Назначим минимальное и максимальное значения как пределы по оси X:

chart1->ChartAreas["ChartArea1"]->AxisX->Minimum = minX;
chart1->ChartAreas["ChartArea1"]->AxisX->Maximum = maxX;

За интервал сетки по оси X отвечает свойство AxisX->Interval, мы хотим сделать интервал целым и не менее единицы, а затем увеличивать его пропорционально степени десятки, которой соответствует длина интервала [minX,maxX], то есть, шаг будет равен 1 при |maxX-minX|≤10, десяти при |maxX-minX|≤100 и т.д.

Поможет, как всегда, выражение, зависящее от логарифма, в нашем случае, десятичного:

double interval = Math::Pow(10,
  Math::Max( (double)Math::Ceiling(Math::Log10(maxX - minX)), (double)1) -1);

Если мы опасаемся, что полученный интервал в экранных пикселах окажется "слишком маленьким", например, меньше 10 пикселов, его всегда можно пересчитать, хотя мне эта проверка при "логарфимической" цене деления кажется излишней:

do {
 double inPixels = (interval * chart1->Width) / (maxX - minX);
 if (inPixels > 10) break;
 interval *= 2;
} while (1);

После этого остаётся выставить для оси нужный интервал:

chart1->ChartAreas["ChartArea1"]->AxisX->Interval = interval;

30.10.2017, 11:17 [2011 просмотров]


теги: c++ программирование графика studio mathcad

К этой статье пока нет комментариев, Ваш будет первым