Пусть у нас возникла следующая задача.
Дан набор точек (пока одномерный случай)
- - наблюдаемый набор координат
- величины фиксированы и неизвестны (смещение и шаг решетки)
- - неизвестные целочисленные координаты (на решетке)
- - неизвестная ошибка (предполагается малой)
Требуется найти
.
Ясно, что задача поставлена не вполне корректно, т.к. величина ошибки никак не контролируется. Но с этим ничего не поделать.
Для решения этой задачи предлагается использовать аппарат цепных дробей.
Прежде всего, избавимся от сдвига
. Для этого сортируем
и берем разности между соседними точками. Да, ошибка увеличится (в 1.5 раза), но теперь можно считать, что
. Снова сортируем. После этого можно считать, что последовательность
неубывает. Вот теперь рассматриваем дроби вида
В идеальном мире это были бы рациональные дроби. Но ошибки
портят картинку. Ну и ладно. Рассматриваем цепные дроби для наилучшего приближения и следим за знаменателями. Как только знаменатель СКАКНУЛ - все, нашли хорошего кандидата для рациональной дроби.
На практике этот метод работает прекрасно, но есть нюансы.
- дробь надо "парсить" руками. Попытка использовать простое деление данных типа "double" моментально заваливается. Так что надо использовать целочисленную арифметику с самого начала. Разбор экспоненты, мантиссы итд.
- Метод ловит лишь взаимно простые величины и не различает дроби вида 1/2 и 3/6. Так что надо это учитывать.
- Скачок в знаменателе - та еще вещь. Их может быть несколько. Какой лучше? Это и есть выбор размера решетки.
- Как всегда, много чего еще по мелочам. Все это всплывает в процессе использования.
(Оффтоп)
Между прочим, такой подход можно эффективно использовать для сжатия геометрии, если есть серьезные подозрения насчет существования такой решетки. Отдельно сжимаем целочисленные координаты (относительно простая задача) и отдельно вычисленные ошибки
(если вообще нужно). Для сжатия ошибок используем их "малость". Таким образом можно иногда получить сжатие без потерь с коэффициентом 4-5)
Ну, а теперь двумерные данные. Они еще и повернуты, но это ничего не меняет. Просто шаг решетки будет
. Дальше изучаем координаты
по-отдельности.