Кривая Гильберта

Материал из Википедии — свободной энциклопедии
Первые шаги создания кривой Гильберта

Кривая Гильберта (известная также как заполняющая пространство кривая Гильберта) — это непрерывная

заполняющая пространство кривая, впервые описанная немецким математиком Давидом Гильбертом в 1891 году[1], как вариант заполняющих пространство кривых Пеано, открытых итальянским математиком Джузеппе Пеано в 1890 году[2]
.

Поскольку кривая заполняет плоскость, её размерность Хаусдорфа равна (в точности, её образ является единичным квадратом, размерность которого равна 2 при любом определении размерности, а её граф является компактным множеством, гомеоморфным замкнутому единичному интервалу с хаусдорфовой размерностью 2).

является -м приближением к предельной кривой. Евклидова длина кривой равна , то есть растёт экспоненциально от , будучи в то же время всегда в пределах квадрата с конечной площадью.

Рисунки

  • Кривая Гильберта, первый шаг
    Кривая Гильберта, первый шаг
  • Кривые Гильберта, первый и второй шаги
    Кривые Гильберта, первый и второй шаги
  • Кривые Гильберта, с первого по третий шаги
    Кривые Гильберта, с первого по третий шаги
  • Ниточная графика
    Ниточная графика
  • Кривая Гильберта в цвете
    Кривая Гильберта в цвете
  • Трёхмерная кривая Гильберта
    Трёхмерная кривая Гильберта
  • Трёхмерная кривая Гильберта в цвете, указывающем последовательность
    Трёхмерная кривая Гильберта в цвете, указывающем последовательность
  • Анимационная иллюстрация, показывающая прохождение кружков по кривой.
    Анимационная иллюстрация, показывающая прохождение кружков по кривой.

Приложения и алгоритмы отображения

Как истинная кривая Гильберта, так и её дискретная аппроксимация дают отображение одномерного и двумерного пространств, довольно хорошо сохраняющих локальные свойства[3]. Если обозначить через (x, y) координаты точки в единичном квадрате, а через d расстояние вдоль кривой, на котором эта точка достигается, то точки, имеющие близкие к d значения, будут иметь также близкие значения и к (x, y). Обратное не всегда верно — некоторые точки, имеющие близкие координаты (x, y), имеют достаточно большую разницу в расстоянии d.

Ввиду этого свойства локальности кривая Гильберта широко применяется в компьютерных программах. Например, диапазон

R-дерева[4]. Кривые Гильберта использовались также для сжатия информационных баз данных[5][6]
.

Полезно иметь алгоритм, позволяющий делать преобразование в обоих направлениях (как из (x, y) в d, так и из d в (x, y)). Во многих языках программирования предпочтительнее использовать итерации, а не рекурсию. Следующая программа на языке C осуществляет отображение в обоих направлениях, используя итерации и битовые операции, а не рекурсию. Программа предполагает разбиение квадрата на n х n ячеек (квадратов со стороной 1), где n является степенью двойки. Координаты (0,0) принадлежат левому нижнему углу, а (n-1, n-1) — правому верхнему углу. Расстояние d отсчитывается от левого нижнего угла (расстояние 0) и растёт до в правом нижнем углу.

//Преобразовать (x,y) к d
int xy2d (int n, int x, int y) {
    int rx, ry, s, d=0;
    for (s=n/2; s>0; s/=2) {
        rx = (x & s) > 0;
        ry = (y & s) > 0;
        d += s * s * ((3 * rx) ^ ry);
        rot(s, &x, &y, rx, ry);
    }
    return d;
}

//Преобразовать d к (x,y)
void d2xy(int n, int d, int *x, int *y) {
    int rx, ry, s, t=d;
    *x = *y = 0;
    for (s=1; s<n; s*=2) {
        rx = 1 & (t/2);
        ry = 1 & (t ^ rx);
        rot(s, x, y, rx, ry);
        *x += s * rx;
        *y += s * ry;
        t /= 4;
    }
}

//вращаем/отражаем квадрант
void rot(int n, int *x, int *y, int rx, int ry) {
    if (ry == 0) {
        if (rx == 1) {
            *x = n-1 - *x;
            *y = n-1 - *y;
        }

        //Обмениваем x и y местами
        int t  = *x;
        *x = *y
        
        *y = t;
    }
}

Программа использует соглашения языка C: знак & означает побитную операцию AND (И), знак ^ — побитную XOR (ИЛИ), знак += означает оператор добавления к переменной, а знак /= — операцию деления переменной.

Функция xy2d работает сверху вниз, начиная со старших битов x и y, и начинает построение d со старших битов. Функция d2xy работает в противоположном направлении, начиная с младших битов d, и строит x и y с младших битов. Обе функции используют функцию вращения и отражения системы координат (x, y).

Оба алгоритма работают похожим образом. Весь квадрат рассматривается как 4 области 2 х 2. Каждая область состоит из 4 меньших областей и так далее до конечного уровня. На уровне s каждая область имеет s х s ячеек. Имеется единственный цикл FOR, пробегающий через уровни. На каждой итерации добавляется значение к d или к x и y, которое определяется областью (из четырёх), в которой находимся на данном уровне. Области задаются парой (rx, ry), где rx и ry принимают значение 0 или 1. Таким образом, область определяется 2 входными битами (либо двумя битами из d, либо по биту из x и y), и по ним образуется два выходных бита. Также вызывается функция вращения, чтобы (x, y) можно было использовать на следующем уровне на следующей итерации. Для xy2d она начинается с верхнего уровня всего квадрата и движется вниз до нижнего уровня до индивидуальных ячеек. Для d2xy процесс начинается снизу с ячеек и движется вверх до полного квадрата.

Можно реализовать эффективно кривые Гильберта, даже если область не образует квадрат[7]. Более того, существуют некоторые обобщения кривых Гильберта для более высоких размерностей[8][9].

Представление в системе Линденмайера

Создание кривой Гильберта можно переписать для L-системы.

Шестая итерация создания кривой Гильберта
Алфавит : A, B
Константы : F + −
Аксиома : A
Правила:
A → − B F + A F A + F B −
B → + A F − B F B − F A +

Здесь F означает «движение вперёд», «−» означает поворот влево на 90°, «+» означает поворот вправо на 90° (см. turtle graphics), а A и B игнорируются при рисовании.

Другие реализации

Arthur Butz[10] дал алгоритм вычисления кривой Гильберта в многомерных пространствах.

В книге Graphics Gems II[11] обсуждается кривая Гильберта и даётся реализация.

На основе кривой Гильберта могут быть реализованы вибраторные либо печатные конструкции антенн[12].

См. также

Примечания

  1. Hilbert, 1891, с. 459—460.
  2. Peano, 1890, с. 157—160.
  3. Moon, Jagadish, Faloutsos, Saltz, 2001, с. 124—141.
  4. Kamel, Faloutsos, 1994, с. 500—509.
  5. Eavis, Cueva, 2007, с. 1—12.
  6. Lemire, Kaser, 2011.
  7. Hamilton, Rau-Chaplin, 2007, с. 155—163.
  8. Alber, Niedermeier, 2000, с. 295—312.
  9. Haverkort, van Walderveen, 2009, с. 63—73.
  10. Butz, 1971, с. 424—42.
  11. Voorhies, 1991, с. 26—30.
  12. Слюсар, В. Фрактальные антенны. Принципиально новый тип «ломаных» антенн. Часть 2. Электроника: наука, технология, бизнес. — 2007. — № 6. С. 82—89. (2007). Дата обращения: 22 апреля 2020. Архивировано 3 апреля 2018 года.

Литература

Ссылки