Продолжим тему бильярдных фракталов.

В статье присутствуют Gif (трафик!) и контрастные картинки. У эпилептиков может случиться эпилептический припадок.
Предыдущие части: 0, 1, 2.
Для начала вспомним, что за «бильярдные фракталы».
Есть у нас некоторая прямоугольная область («бильярд»), в которой движется бильярдный шар (или луч света).

Шар упруго отражается от стенок по законам оптики (угол отражения равен углу падения). При этом шар бесконечно мал (абстрактная «материальная точка» из физики) и при движении и отражении скорости не меняет (скорость нас вообще не интересует).
Когда шар касается одной из выбранных стенок (не важно, какую стенку выбирать, но для примера выберем верхнюю) — фиксируем, в какую сторону движется шар — в левую или в правую:


Для бильряда, соотношение сторон которого — иррациональное число, последовательность отражений — фрактальная (насколько этот термин применим к двоичным последовательностям). Или фракталообразующая. Если визуализировать такую последовательность с помощью черепашьей графики, мы получим фрактал.
В качестве примера можем использовать последовательность для бильярда, соотношение сторон которого равно
.
Строить такие последовательность очень легко:
Берем поочередно каждое целое число
, умножаем на
, отбрасываем дробную часть и отмечаем четные целые части единицами, а нечетные — нулями.
Первые 100 элементов этой последовательности:
0100110110010011001001101100110110010011011001101100100110010011011001001100100110110011011001001100
Визуализация этой последовательности с помощью черепашьей графики дает нам следующую фигуру:

Более подробно о том, откуда взялась эта формула и о визуализации последовательностей с помощью черепашьей графики, можно почитать во второй части — Фракталы в иррациональных числах
В реальном мире, такие последовательности встречаются гораздо чаще, чем может показаться на первый взгляд. Два примера.
Пример 1. Есть у нас два человека. Один побольше, второй — поменьше:

Эти два человека идут по улице. У высокого шире шаг, чем у низкого. Чтобы успевать за высоким, низкому приходится быстрее ногами двигать и больше шагов делать. В каждый момент времени, когда низкий ставит правую ногу на асфальт, фиксируем какая нога высокого находится в воздухе — левая или правая. Если частоты шагов низкого и высокого несинхронизированные — получим фрактальную последовательность.
Пример 2. Вокруг некоторой планеты вращается спутник:

Выбираем временной интервал
произвольной длинны. Фиксируем в каком полушарии находится спутник в момент времени
— в южном или северном. Последовательность этих положений будет фрактальной, если соотношение длинны выбранного интервала с длинной интервала, за который спутник совершает полный оборот вокруг оси — иррациональное число.
Для наглядности, посмотрим на геометрическую интерпретацию бильярдных последовательностей.

Для бильярда, соотношение сторон которого равно
, строим график функции
. Целые числа, отмеченные на оси
, делят плоскость на чередующиеся полосы (поочередно помечаем полосы единицами и нулями). Целыми числами на оси
отмечаем, через какую полосу проходит график функции — через полосу помеченную единицей или нулем.
Фактически, все что мы сделали, чтобы получить фрактальную последовательность — дискретизировали линейную функцию с иррациональным коэффициентом
. Если фрактальную последовательность можно получить дискретизацией линейной функции, первым делом напрашивается вопрос — а какую последовательность можно получить дискретизацией нелинейной функции?
Но прежде, чем переходить к нелинейным функциям, хотелось бы упомянуть об одном интересном наблюдении, сделанном в процессе написания статьи.
Вернемся к дискретизации нелинейных функций.
Например
, где
— действительное число. Самый простой пример — парабола (
).

Строим последовательность:
Для целых аргументов
, записываем четность целой части (отбросив дробную) значения функции.
Первые 100 элементов этой последовательности:
0110010100111110000011000100010100000001010011010110001100101001010011111000000000100110111111111000
Визуализация этой последовательности с помощью черепашьей графики дает такую кривую:

Эта последовательность выглядит немного более хаотичной, чем последовательность, полученная дискретизацией линейной функции. Но это не так. Если где-то не видим закономерность — значит плохо смотрим. Можем сделать очень простую визуализацию. Запишем первые 1000 элементов последовательности в блокнот, включим перенос строк.

Можно разглядеть паттерн.
Для того, чтобы лучше разглядеть, единички заменяем на █, нолики — на ░:

Построим двухмерный график этой последовательности. На каждой следующей строчке
последовательность сдвигается на
(где
— целое число, константа) позиций влево. Перепишем
как
.
Для некоторых
:
35:

661:

Для
можем раскрыть скобки, получим
. Получили уравнение поверхности.
Для дальнейших экспериментов запишем уравнение в более общем виде:
Точно так же, как мы дискретизировали линейную функцию, мы можем дискретизировать поверхности второго порядка. Для этого считаем
для каждого
и
, после чего умножаем
на иррациональное число, отбрасываем дробную часть, проверяем четность целой части — 
Для
наше уравнение принимает вид:
Это уравнение элиптического параболоида. Коэффициент
определяет, насколько параболоид вытянут по оси
. Для
:

Для
получаем такой паттерн:

Можем этот же паттерн нарисовать недискретным. Вместо
считаем
. Значение функции масштабируем (прибавляем 1, умножаем на 128) и используем в качестве яркости пикселя:

Для
, дискретный и недискретный варианты:


Коэффициент
сжимает или растягивает паттерн по оси
. Для
и
:


Коэффициент
сжимает или растягивает паттерн по диагонали. Для
и
:


Дальше. Для
наше уравнение принимает вид:
Это гиперболический параболоид — поверхность с отрицательной гауссовой кривизной:

Для
:

Для
:

Попробуем поменять степень
. Для
наше уравнение принимает вид:

Для
:

Для
:

Для
наше уравнение принимает вид:

Для
:

Для
:

Для
:

Самые интересные паттерны получаются, если взять такое
, которое незначительно отличается от 1. Например для
:
Для
паттерн похож на тот, что мы видели для элиптического параболоида:

Для
:

Еще несколько примеров:
:

:

:

:

:

:

Мы попробовали дискретизировать линейную функцию и получили фрактал. Если сделать срез трехмерной плоской волны поверхностью с ненулевой кривизной — получим голографический паттерн. Интересно, что мы получим, если сделаем срез четырехмерной плоской волны пространством с ненулевой кривизной? Об этом поговорим в другой раз.

В статье присутствуют Gif (трафик!) и контрастные картинки. У эпилептиков может случиться эпилептический припадок.
Предыдущие части: 0, 1, 2.
Для начала вспомним, что за «бильярдные фракталы».
Бильярдные фракталы.
Есть у нас некоторая прямоугольная область («бильярд»), в которой движется бильярдный шар (или луч света).

Шар упруго отражается от стенок по законам оптики (угол отражения равен углу падения). При этом шар бесконечно мал (абстрактная «материальная точка» из физики) и при движении и отражении скорости не меняет (скорость нас вообще не интересует).
Когда шар касается одной из выбранных стенок (не важно, какую стенку выбирать, но для примера выберем верхнюю) — фиксируем, в какую сторону движется шар — в левую или в правую:


Для бильряда, соотношение сторон которого — иррациональное число, последовательность отражений — фрактальная (насколько этот термин применим к двоичным последовательностям). Или фракталообразующая. Если визуализировать такую последовательность с помощью черепашьей графики, мы получим фрактал.
В качестве примера можем использовать последовательность для бильярда, соотношение сторон которого равно
Строить такие последовательность очень легко:
Берем поочередно каждое целое число
JavaScript
let a=[];
for(let x=0;x<100;x++) a[x]=Math.floor(x*Math.sqrt(2))%2;
console.log(a.join(''));
Первые 100 элементов этой последовательности:
0100110110010011001001101100110110010011011001101100100110010011011001001100100110110011011001001100
Визуализация этой последовательности с помощью черепашьей графики дает нам следующую фигуру:

Более подробно о том, откуда взялась эта формула и о визуализации последовательностей с помощью черепашьей графики, можно почитать во второй части — Фракталы в иррациональных числах
В реальном мире.
В реальном мире, такие последовательности встречаются гораздо чаще, чем может показаться на первый взгляд. Два примера.
Пример 1. Есть у нас два человека. Один побольше, второй — поменьше:

Эти два человека идут по улице. У высокого шире шаг, чем у низкого. Чтобы успевать за высоким, низкому приходится быстрее ногами двигать и больше шагов делать. В каждый момент времени, когда низкий ставит правую ногу на асфальт, фиксируем какая нога высокого находится в воздухе — левая или правая. Если частоты шагов низкого и высокого несинхронизированные — получим фрактальную последовательность.
Пример 2. Вокруг некоторой планеты вращается спутник:

Выбираем временной интервал
Для наглядности, посмотрим на геометрическую интерпретацию бильярдных последовательностей.
Дискретизация линейной функции.

Для бильярда, соотношение сторон которого равно
Фактически, все что мы сделали, чтобы получить фрактальную последовательность — дискретизировали линейную функцию с иррациональным коэффициентом
Но прежде, чем переходить к нелинейным функциям, хотелось бы упомянуть об одном интересном наблюдении, сделанном в процессе написания статьи.
Об одном интересном наблюдении.
Дабы не нарушать структуру статьи...
Черепашья графика — не единственный способ визуализации двоичных последовательностей. Существует еще один способ, которому посвящена отдельная статья Фракталы в иррациональных числах. Часть 2. Вспомним этот способ.
Возьмем нашу последовательность:
И построим из нее другую последовательность:
Первый элемент последовательности — произвольное число. Каждый следующий элемент — увеличиваем предыдущий элемент на 1, если соответствующий элемент первой последовательности (
) равен 1, или уменьшаем на 1 — если соответствующий элемент равен 0.
После чего можем построить фрактальную кривую, отметив на графике точки с координатами
:

Из этой же кривой можем получить фрактальную поверхность. Для каждой точки
считаем
.
Дальше можем сделать срез плоскости по оси
:

Или отметить такие точки, для которых
или 

Следующая картинка — чем больше
, тем ярче пиксель:

Можем немного изменить последовательность:
Раскрыв скобки, получим:
Здесь
— дробная часть, которую мы ранее отбрасывали.
Как это выглядит в бильярдной модели? Мы увеличиваем предыдущий элемент последовательности на расстояние (по оси
) между правой границей и точкой касания шара верхней границы, если шар двигался влево. Или же уменьшаем на расстояние между левой границей и точкой касания шара верхней границы, если шар двигался вправо:


Делаем визуализацию тем же способом, который использовали выше. Для каждой точки
считаем
. Получили поверхность. Раскрашиваем. Чем больше
, тем ярче пиксель:

До того, как мы изменили последовательность, все
были целыми числами. Теперь — иррациональные. Сделать
не получится. Но можем найти некоторую плоскость, которая находится на одинаковом расстоянии от максимальной и миниальной
и посмотреть на точки, которые лежат ниже и выше этой плоскости:

Самое интересное получится, если мы отметим пиксели, для которых
. Другими словами, отмасштабируем
, умножив на некоторое число
, после чего отбросим дробную часть и проверим четность целой части. Для некоторых
:
478:

338:

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

Для других
:
144:

354:

Замечательные круги не получаем.
Здесь можно посмотреть в динамике, поводив мышкой по экрану.
Возьмем нашу последовательность:
И построим из нее другую последовательность:
Первый элемент последовательности — произвольное число. Каждый следующий элемент — увеличиваем предыдущий элемент на 1, если соответствующий элемент первой последовательности (
JavaScript
let a=[50];
for(let x=1;x<size;x++){
if(Math.floor(x*Math.sqrt(2))%2==1)
a[x]=a[x-1]+1;
else
a[x]=a[x-1]-1;
}
После чего можем построить фрактальную кривую, отметив на графике точки с координатами
JavaScript
for(let x=0;x<size;x++){
context.fillRect(x, a[x], 1, 1);
}

Из этой же кривой можем получить фрактальную поверхность. Для каждой точки
Дальше можем сделать срез плоскости по оси

Или отметить такие точки, для которых

Следующая картинка — чем больше

Можем немного изменить последовательность:
Раскрыв скобки, получим:
Здесь
Как это выглядит в бильярдной модели? Мы увеличиваем предыдущий элемент последовательности на расстояние (по оси


JavaScript
После раскрытия скобок:
let c, arr=[0];
for(let i=1;i<size;i++){
c=i*Math.sqrt(2);
if(Math.floor(c)%2){
arr[i]=arr[i-1]+(c-Math.floor(c));
}else{
arr[i]=arr[i-1]-(1-(c-Math.floor(c)));
}
}
После раскрытия скобок:
let c, arr=[0];
for(let i=1;i<size;i++){
c=i*Math.sqrt(2);
arr[i]=arr[i-1]+(c-Math.floor(c));
if(Math.floor(c)%2!=1){
arr[i]--;
}
}
На самом деле...
Достаточно:
В этом случае поверхность получится гладкой, а не фрактальной.
let c, arr=[0];
for(let i=1;i<size;i++){
c=i*Math.sqrt(2);
arr[i]=arr[i-1]+(c-Math.floor(c));
}
В этом случае поверхность получится гладкой, а не фрактальной.
Делаем визуализацию тем же способом, который использовали выше. Для каждой точки

До того, как мы изменили последовательность, все

Самое интересное получится, если мы отметим пиксели, для которых
478:

338:

Получаем замечательные круги. Примечательно, что круги получаем для
Для других
144:

354:

Замечательные круги не получаем.
Здесь можно посмотреть в динамике, поводив мышкой по экрану.
Вернемся к дискретизации нелинейных функций.
Дискретизация нелинейной функции.
Например

Строим последовательность:
JavaScript
let a=[];
for(let x=0;x<100;x++) a[x]=Math.floor(x*x*Math.sqrt(2))%2;
console.log(a.join(''));
Для целых аргументов
Первые 100 элементов этой последовательности:
0110010100111110000011000100010100000001010011010110001100101001010011111000000000100110111111111000
Визуализация этой последовательности с помощью черепашьей графики дает такую кривую:

Эта последовательность выглядит немного более хаотичной, чем последовательность, полученная дискретизацией линейной функции. Но это не так. Если где-то не видим закономерность — значит плохо смотрим. Можем сделать очень простую визуализацию. Запишем первые 1000 элементов последовательности в блокнот, включим перенос строк.

Можно разглядеть паттерн.
Для того, чтобы лучше разглядеть, единички заменяем на █, нолики — на ░:

Построим двухмерный график этой последовательности. На каждой следующей строчке
Для некоторых
35:

661:

Больше примеров
Для
Дискретизация поверхностей с ненулевой кривизной.
Для дальнейших экспериментов запишем уравнение в более общем виде:
Точно так же, как мы дискретизировали линейную функцию, мы можем дискретизировать поверхности второго порядка. Для этого считаем
Для
Это уравнение элиптического параболоида. Коэффициент

JavaScript
for(var x=0;x<canvas.width;x++){
xx=x-canvas.width/2;
for(var y=0;y<canvas.height;y++){
yy=y-canvas.height/2;
z=a*(xx**2+b*xx*yy+c*(yy**2))**(d);
if(Math.floor(z*Math.sqrt(2))%2) context.fillRect(x, y, 1, 1);
}
}
Для

Можем этот же паттерн нарисовать недискретным. Вместо

Для


При чем тут голография?
Паттерн, который мы получили — самая простая голограмма. Такой же паттерн мы получим, если сделаем срез сферической волны плоскостью. Или же срез плоской волны сферической поверхностью.


Коэффициент


Коэффициент


Дальше. Для
Это гиперболический параболоид — поверхность с отрицательной гауссовой кривизной:

Для

Для

Попробуем поменять степень

Для

Для

Для

Для

Для

Для

Самые интересные паттерны получаются, если взять такое
Для

Для

Еще несколько примеров:






Поиграться
В динамике — дискретные паттерны. Двигаем мышкой по экрану. Параметры
вводим вручную. Параметр
вычисляется из координат мышки.
В статике — можем посмотреть дискретный и недискретный паттерны.
В статике — можем посмотреть дискретный и недискретный паттерны.
Подводя итоги...
Мы попробовали дискретизировать линейную функцию и получили фрактал. Если сделать срез трехмерной плоской волны поверхностью с ненулевой кривизной — получим голографический паттерн. Интересно, что мы получим, если сделаем срез четырехмерной плоской волны пространством с ненулевой кривизной? Об этом поговорим в другой раз.