#include <stdio.h>
#include <vector>
using namespace std;
typedef vector<double> TDoubleArray;
//Вычисление значений, на которых должны проставляться метки на координатных осях.
static TDoubleArray & CalcGridLabels(double xmin, //минимальное значение.
double xmax, //максимальное значение.
int N) //количество меток в указанном интервале +/-2
{
#define MANT_NUM 5
double mant[MANT_NUM] = {0.1, 0.2, 0.25, 0.5, 1.0},
dx = xmax-xmin;
int i;
//Подбираем значение мантиссы, близким к величине dx:
while(dx < mant[0])
for(i=0; i < MANT_NUM; i++)
mant[i] /= 10.0;
while(dx > mant[MANT_NUM-1])
for(i=0; i < MANT_NUM; i++)
mant[i] *= 10.0;
//Если количество меток > 10:
while(1)
{//Первый проход:
for(i=MANT_NUM-1; i >=0 ; i--)
if(dx/mant[i] >= N )
break;
if(i >= 0)
break;//все хорошо, N меток будет.
//Умножаем метки на 2:
for(i=0; i < MANT_NUM; i++)
mant[i] /= 2;
//Второй проход:
for(i=MANT_NUM-1; i >=0 ; i--)
if(dx/mant[i] >= N )
break;
if(i >= 0)
break;//Все хорошо, N меток будет.
//Умножаем метки на 5:
for(i=0; i < MANT_NUM; i++)
mant[i] /= 5;
}
//2)Ищем наименьшую разницу между требуемым количеством меток и
//тем количеством меток, которое можно получить:
int min_diff = (int)(dx/mant[0]), md_ind = 0;
for(i = 0; i < MANT_NUM; i++)
{ int diff = abs((int)(dx*1.00000001/mant[i])-N);
if(diff < min_diff)
{ min_diff = diff;
md_ind = i;
}
}
//Рассчитываем значения меток:
double dm = mant[md_ind];
double start = dm*(int)(xmin*1.00000001/dm);
if(start < xmin)
start += dm;
static TDoubleArray values;
values.resize(1);
values[0] = start;
values.reserve(N+1);
while(start+dm < xmax)
{ start += dm;
values.push_back(start);
}
return values;
#undef MANT_NUM
}
Блог csgpblog
месяц назад
2 коммент.:
У меня небольшой вопрос. В приведенном примере почему шаг был выбран 0.02, а не 0.01, например.
Если можно, напишите полное условие задачи. Заинтересовала она меня )
Я сначала тоже хотел условия задачи полностью расписать, но это оказалось сложновато, и мне стало лень :) Но если интересно - то попытаюсь :)
Полное условие задачи можно сформулировать так: нужно проставить N меток на координатной оси в заданном интервале (x1, x2), x1 < x2. Мантисса всех меток должна быть кратна какому-то одному значению из данного набора величин (в приведенном коде это набор из 4-х значений: {0.1, 0.2, 0.25, 0.5} ). Если в интервале (x1, x2) невозможно проставить именно N меток, используя предложенный набор, то из набора берется то значение, с которым количество проставляемых меток получается максимально близким к N. Уфф, кажется, все.
Отправить комментарий