| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Алгоритмы > Создание сетки на графике функции |
| Автор: ТРЕТЬ 19.12.2007, 17:57 |
| Задача в создании удобно читаемого графика функции. Т.е. требуется создать такую сетку с подписями, что бы смотрящий на график мог легко оценивать значение функции в каждой точке графика. По шагам я бы разбил задачу так. 1. Определяем максимальное значение функции. 2. Определяем максимальное значение сетки. (вот именно этот шаг меня интересует как сделать, комментарии ниже) 3. Определяем шаг сетки как частное максимального значения сетки и кол-ва шагов сетки. 4. Рисуем сетку, рисуем график. А вот теперь основная проблема. Как определить максимальное значение на сетке? Я так понимаю, должны выполнится следующие условия. 1. Должно быть больше максимального значения функции (что очевидно) 2. Должно быть не на много больше максимального значения (иначе график функции скучкуется внизу) 3. Должно быть каким-то образом кратно кол-ву шагов сетки (чтобы ширина шага не была каким-нить иррациональным числом и т.п.) 4. Должно быть "красивым" (другого слова не могу подобрать) 5. Частное его и числа шагов тоже должно быть "красивым". Попытаюсь пояснить какой я смысл вкладываю в слово "красивый". К сожалению, не получается придумать никакого толкового объяснения, поэтому попробую проиллюстрировать на примере. Пример "красивых" подписей на графике. 1 1.0 0.25 0.2 0.125 2 2.0 0.50 0.4 0.250 3 3.0 0.75 0.6 0.375 4 4.0 1.00 0.8 0.500 5 5.0 1.25 1.0 0.625 как видите, нельзя сказать просто, что это числа кратные 1, 10, 2, 5 и т.п. Тут что-то сложнее... Еще сложнее задача становится, если учесть, что мы не знаем в каком диапазоне вообще будут значения функции - это может быть [0; 4] а может быть [750; 30658]... У меня, честно говоря, нет толковых идей, как это сделать. В поисковике толкового совета тоже не нашел. Если вы не против, я бы сразу ввел обозначения переменных для упрощения обсуждения. Данные Fmin - минимальное значение функции (можно брать за 0, хотя если есть алгоритм, который оценивает и этот параметр, то было бы еще лучше) Fmax - максимальное значение функции (считайте уже определенной, не стоит писать куски кода по её определению N - кол-во шагов сетки (все-таки, лучше создать максимально универсальный алгоритм) Искомые Gmax - максимальное значение на сетке Gdelta - шаг сетки. Давайте искать решение)) |
| Автор: dereyly 20.12.2007, 01:23 | ||
Вопрос не совсем понял... точнее проблемы...
Если данные у вас распределены неравномерно пользуйтесь нелинейными осями координат... чаще всего используют логарифмические координаты... |
| Автор: baldina 20.12.2007, 02:03 |
| все "красивые", что ты привел, либо целые, либо содержат одну цифру после запятой, либо являются суммой степеней двойки (например 0.375 = 2^(-2) + 2^(-3)). вот это и есть критерий. только он не покрывает все случаи. например, если Fmin=0.21, Fmах=0.22, N=10, то хочется получить ряд 0.210 0.211 0.212 ... 0.219 0.220 так что основной критерий, мне кажется, должен быть "конечная десятичная дробь" а вот если Fmin=0.2111111 и Fmах=0.2297654, то при N=10 имеем Gdelta=0.00186543. Напрашивается решение округлять Gdelta до одной или двух значащих цифр и степень десяти младшего разряда результата использовать в качестве числа значащих цифр для значений сетки (обозначу его через M). для моего примера получаем: Gdelta=0.002 M = abs (floor (log10 (Gdelta)) = 3 ряд 0.211 0.213 0.215 0.217 0.219 0.221 0.223 0.225 0.227 0.229 0.231 |
| Автор: baldina 20.12.2007, 02:32 |
| поразмыслив, понял, что получилось частное решение. надо рассмотреть случаи а) Fmax-Fmin > 1, Gdelta > 1 б) Fmax-Fmin > 1, Gdelta < 1 в) Fmax-Fmin < 1 моё работает для в) |
| Автор: baldina 20.12.2007, 02:56 |
| Для a) IntPart=floor(Gdelta) M= abs(log10(IntPart) - floor(log10(abs(Gdelta-IntPart)))) для б) M=floor(log10(Fmax))+log10(Gdelta) вроде так |
| Автор: ТРЕТЬ 22.12.2007, 23:23 |
| dereyly, Представьте себе график продаж, представленный столбцами. Нужно чтобы по подписям на сетке можно было легко давать примерную оценку высоты каждого столбца. Т.е. если мы возьмем шаг сетки 24532 (пример), будет довольно тяжело оценить даже высоту столбца, который занимает полтора шага сетки. Да и выглядеть подписи будут кошмарно. baldina, А М - это что за переменная? M = abs(log10(IntPart) - floor(log10(abs(Gdelta-IntPart)))) - что по сути вычисляет эта операция? (Кстати, на все выражение модуль навешивать смысла по-моему смысла нету никакого floor(log10(abs(Gdelta-IntPart))) точно отрицательное число, log10(IntPart) - строго положительное) Кстати, очень понравилась идея про разность степеней двойки для шага меньше единицы)) |
| Автор: ТРЕТЬ 23.12.2007, 00:49 | ||
Тут у меня наклюнулась одна мысль. Вот как я её реализовал...
Функция пока поддерживает только числа >100, но при желании можно сделать модификацию для всех чисел (у меня просто нет времени сейчас это делать, а данного варианта мне вообщем-то достаточно). В целом решение проблемы: Gdelta = ceilSpecial((Fmin - Fmax) / N); Gmax = Fmin + Gdelta * N; |
| Автор: baldina 23.12.2007, 14:55 | ||
я же написал в первом посте - число значащих цифр, выводимых в узлах сетки |