В детстве мне крупно повезло. Когда я учился в восьмом классе, в нашем доме появился всамделишный компьютер ZX Spectrum 128, который подключался к нашему домашнему телевизору и позволял почувствовать себя программистом. После школы, кое-как разобравшись с уроками, я крепко залипал перед экраном и старался успеть до прихода родителей с работы (телевизор-то на всех один), сотворить что-нибудь сногсшибательное. Творил я тогда на неотъемлемом от компьютера, и даже от его клавиатуры, языке BASIC, а источником вдохновения служили журналы «Наука и жизнь», «Техника молодёжи» и «В мире науки» (перевод «Scientific American»), в которых к концу 80-х начали появляться регулярные рубрики для любителей ЭВМ. В результате многочасового сидения перед телевизором я ожидаемо приобрёл близорукость, однако вместе с очками пришла убеждённость в том, что математика, даже школьная, может быть безумно красивой и интересной!

В ноябрьском номере журнала «В мире науки» за 1986 год появилась статья, в которой рассказывалось, как с помощью очень простых вычислений можно генерировать на экране необычные, сложные и на удивление красивые картины. Речь в ней идёт о функциях на модулярных арифметиках, о динамических системах и клеточных автоматах. Среди прочих приводилась очень простая итерационная схема некоего Барри Мартина, опубликованная им ранее в статье «Graphic Potential of Recursive Functions»:

(x,y) \to \left( y - \mathrm{sign}(x)\sqrt{|b x+c|},a - x \right).

При многократном применении (итерациях) это преобразование из точки на плоскости порождает множество, обладающее причудливой и гармоничной структурой. Разнообразные картины можно получать, изменяя три параметра ab и c, начальную точку и масштаб изображения. Цвет точек определяется шагом итерации. Алгоритм предельно прост:

x = 0, y = 0
a = 1, b = 3, c = 0
col = 0
while true
  (x, y) = (y - sign(x)*sqrt(abs(b*x + c)), a - x)
  col = col + 1
  if col > 10000
    поменять цвет точки
    col = 0
  end
  нарисовать точку с координатами (x, y)
end
В детстве мне крупно повезло.-2
Тот самый номер журнала до сих пор хранится в домашней библиотеке.
В детстве мне крупно повезло.-2-2
В детстве мне крупно повезло.-2-3

Этот способ генерации сложных картин настолько прост, что я смог реализовать его даже на мучительно медленном Спектруме, получая обалденные изображения, которые называл «салфетками». Ну, а сейчас я за часик набросал для вас интерактивный рисователь «салфеток Мартина», с которым вы можете поиграть сами. А вот тут реализован эффектный «полёт» сквозь это множество.

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

Круто, а почему так?

Но что же такого таится в мартиновской формуле, что способно порождать эту красоту? Можно ли как-то объяснить все эти пузыри, ритмичные мотивы, перетекающие друг в друга симметрии? Как вообще анализируют подобные системы?

Занимается этим раздел математики, который называется теорией динамических систем, граничащий с теорией хаоса. Я не буду здесь глубоко влезать в теорию, сосредоточившись на объяснении основных структур, а больше даже — на красивых картинках.

Изобилие параметров в формуле Мартина излишне. Чтобы проявить все существенные свойства этого отображения, достаточно коэффициента b, при фиксированных значениях a = 1 и c = 0. Таким образом, мы рассмотрим упрощённое преобразование, которое обозначим как M:

 M : (x,y) \to \left( y - b\,\mathrm{sign}(x)\sqrt{|x|},1 - x \right).

Его, в свою очередь, можно представить композицией двух простых преобразований — нелинейного искажения F, которое, не меняя координат x, сдвигает точки вдоль y, как показано на картинке ниже, и поворота на 90° против часовой стрелки R:

\begin{eqnarray*}   &M = R \circ F\\   &R : (x,y) \to \left( y, 1 - x \right),\\   &F : (x,y) \to \left( x, y - b\, \mathrm{sign}(x)\sqrt{|x|} \right).\\ \end{eqnarray*}
Нелинейная трансформация и поворот, образующие преобразование M.
Нелинейная трансформация и поворот, образующие преобразование M.

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

Преобразования для b = 1
Преобразования для b = 1

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

Резонансы возникают между поворотом R, который имеет период 4 (через четыре поворота на 90 ° всё точки возвращаются на место) и смещениями нелинейного преобразования F. Из-за этого точки в разной степени недоворачиваются на положенные 90°, а поскольку смещение гладко и неравномерно, то большая часть точек никогда не вернётся на место, сколько их ни крути. Однако, каким-то точкам, всё-таки повезёт, и смещение с последующим поворотом сможет вернуть их через 2, 3, 5, 7 и более итераций. Это явление порождает точки, неподвижные для многократно применяемых преобразований, таких как M^2, M^3 и так далее.

Теперь мы можем детально разобрать происхождение основных элементов «салфетки Мартина», рождающихся из различных начальных точек.

Семейство траекторий для b = 1.
Семейство траекторий для b = 1.

Хаотические облака происходят в результате перемешивания пространства, а внутри них располагаются «пузыри», окружающие резонансы различного порядка. Эти пустоты на самом деле не пусты, они заполнены кольцевыми орбитами, демонстрирующими не перемешивание, а вращение пространства. Поскольку смещение F гладко, то соседи резонансных точек немного недоворачиваются на каждом цикле, и по мере накопления, результаты итераций заполняют замкнутую орбиту. Это недоворачивание окрестностей резонанса тоже может оказаться в резонансе с периодом преобразования R. В таком случае мы увидим, как овальная орбита сама распадается на цепочку полюсов более высокого порядка. Так на предыдущей картинке образовались симпатичные оранжевые колечки, четвёрками окружающие синие точки резонанса с периодом 17.

Между резонансами и хаотическими областями есть тесная связь. Резонансы порождаются так называемыми эллиптическими неподвижными точками преобразования M, или полюсами, именно они окружены овальными траекториями. Но полюсы не могут появляться сами по себе: окружающие их овальные орбиты неизбежно пересекутся, образуя неподвижные точки другого типа — седловые точки. Эти точки неустойчивы, и соседние с ними точки под действием отображения M экспоненциально разбегаются от седловых точек в разные стороны. Именно это разбегание и порождает хаотические области, которые заполняют пространство между упорядоченными областями, окружающими полюсы. Дело в том, что постоянно разбегаясь от седловых точек, их окресности обречены всё время оказываться замкнутыми в пределах одной сложной структуры: странного аттрактора. Подробнее об этом я рассказывал в серии статей, посвящённых динамическому хаосу.

Седловые точки соединяются особыми орбитами — инвариантными гетероклиническими многообразиями. Звучит, может быть, непонятно, но, согласитесь, красиво. А выглядят эти многообразия ещё красивее!

При любом значении параметра b преобразование F оставляет на месте линию x = 0. Именно она и является инвариантным многообразием этого преобразования. После поворота, она превращается в линию y = 1, и её отображение преобразованием M выявляет множество всех седловых точек и гетероклинических орбит, которые их соединяют. Смотрите, как красиво они выявляют тонкие структуры хаотических областей для различных значений параметра b:

В детстве мне крупно повезло.-8
В детстве мне крупно повезло.-8-2
В детстве мне крупно повезло.-8-3

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

Для полноты картины здесь можно полюбоваться тем, что происходит с этой красотой при плавном изменении параметра b (осторожно, тяжёлый GIF).

* * *

Ещё со времени моих экспериментов на Спектруме меня не переставало удивлять, как сухая математика позволяет получать элегантные и гармоничные картины, сравнимые по «креативности» с человеческой фантазией или творениями живой природы. Благодаря этому удивлению я и стал профессионально заниматься теорией динамического хаоса, которая помогает наслаждаться красотой не только внешней, но и внутренней — в логике и неожиданных взаимосвязях между разными объектами и концепциями.

Комментарии (75)


  1. Tyusha
    29.05.2024 06:55
    +6

    Немного не в тему. Но могу добавить восторженных впечатлений от журнала "В мире науке". Фантастически интересный журнал 80-х годов. Когда-то прочитала там про redcode. Настолько зацепило, что уже позже в 90-х написала собственный redcode c интерпретатором и средой выполнения. Дело было ещё на PC XT под DOS на С. Жаль, что с тех пор не осталось ни журналов, ни дискет. Всё как-то и куда-то складывалось, а потом перестало быть в неизвестном направлении.


    1. samsergey Автор
      29.05.2024 06:55

      А я помню статьи про бои в памяти! Целый цикл был, но для меня он оказался сложноват.


    1. kt97679
      29.05.2024 06:55

      Журналы можно найти в электронном виде: https://flibusta.site/sequence/30589


    1. IvanPetrof
      29.05.2024 06:55
      +3

      Писал "бой в памяти" на паскале в СЮТе.

      Там же писал игру NSW (network star war). Не знаю есть ли аналоги такой игры в "большом мире" но суть заключалась в том, что игра реализовывалась в виде сервера, который обслуживал игровой мир (в данном случае это была карта 150х150 точек, разбитая на сектора по 15х15. В каждой из координат карты могли находиться разные объекты (звёзды, базы игроков, корабли игроков и т.п.). Игровой сервер предоставлял сетевое api для кораблей игроков (по протоколу ipx), а клиентские части кораблей нужно было писать самому (мы писали на паскале). На перемещение по карте и выстрелы лазером тратилась энергия (пропорционально дальности). так же энергия тратилась на использование радара (чтобы получить снимок карты вокруг себя). Радар порождал события вспышек, которые могли Вас выдать, т.к. засекались противником. подзаряжаться энергией можно было у своих баз. Чужие базы нужно было уничтожать торпедами, запас которых тоже тратился. Летящие торпеды можно было сбивать лазером. И .т.д. Вобщем, было интересно))


  1. atues
    29.05.2024 06:55
    +7

    Вот тут еще масса идей и картинок


    1. eugenk
      29.05.2024 06:55
      +1

      Книга очень интересная, но она немного о другом. Точнее немного о другом типе картинок.


  1. kipar
    29.05.2024 06:55
    +1

    Я еще в универе случайно открыл похожую формулу в виде

          x := Frac(x+sin(y));
          y := Frac(y+cos(x));

    и все эти годы не мог найти упоминаний о ней и объяснения получающихся картинок. Спасибо за статью!


    1. voldemar_d
      29.05.2024 06:55

      Frac - что за функция? Возвращает дробную часть?


      1. kipar
        29.05.2024 06:55
        +1

        да. Ну и координаты соответственно получаются от 0 до 1, для рендера надо умножить на размер окна.


        1. voldemar_d
          29.05.2024 06:55

          А x и y в каком диапазоне должны быть?


          1. Deosis
            29.05.2024 06:55
            +1

            Со второй итерации они попадут в диапазон [0;1]


            1. voldemar_d
              29.05.2024 06:55

              А есть примеры картинок, полученных именно по Вашей формуле?


              1. samsergey Автор
                29.05.2024 06:55
                +2

                У меня так получилось.

                Прикольная абстракция! Здесь цвет отображает плотность аттрактора при 100 млн итерациях. Интересно, что от начальной точки итерации изображение не зависит -- оно является инвариантом указанного преобразования.


                1. voldemar_d
                  29.05.2024 06:55

                  Непонятно, по какой формуле цвет из плотности рассчитывается? В ч/б варианте (каждая точка просто черным цветом рисуется) у меня совершенно другая картинка получилась (см. ниже).

                  Можете полный псевдокод процедуры дать?


                1. kipar
                  29.05.2024 06:55

                  как я написал ниже, изначально я сделал с "ошибочной" формулой, и как раз с ней получаются резонансы похожие на картинки из статьи.


            1. voldemar_d
              29.05.2024 06:55
              +1

              Попробовал сделать несколько картинок по этой формуле. Начальные значения: x = 0.5, y = 0.3. При изменении количества итераций (в тысячах) 50 => 100 => 200 => 500 => 1000 картинка меняется так:

              Видно, что поле всё больше заполняется точками, но остаются пустые "дырки". Интересно, это следствие конечной точности вычислений? Я все вычисления делал в double (для получения координат, понятно, после умножения x на ширину и y на высоту приводил значения к int).


              1. samsergey Автор
                29.05.2024 06:55
                +2

                У нас разница в том, что в моём случае новые значения x и y вычисляются одновременно, а в вашем — последовательно. Мой алгоритм будет выглядеть так:

                z = x
                x = frac(z - sin(y))
                y = frac(y - cos(z))

                При этом старое значение x сохраняется после вычисления строки 2.

                А если просто вычислять

                x = frac(z - sin(y))
                y = frac(y - cos(z))

                То после выполнения строки 1 значение x уже изменится и это изменение пойдёт в строку 2


                1. voldemar_d
                  29.05.2024 06:55
                  +1

                  Я уже понял свою ошибку. В случае с формулой Мартина, если не сохранять x в промежуточную переменную, x и y очень быстро расходятся в бесконечность.

                  На мой взгляд, важное замечание: тому, кто решит реализовать подобный код сам, особенно на других языках программирования, стоит иметь ввиду, что здесь для рисования точек используется не просто setPixel(x, y, color). Я посмотрел Ваш код скрипта, и заметил следующие моменты:

                  ctx.globalAlpha = 0.1

                  Я не силен в JS - здесь устанавливается глобальная константа смешивания цветов точек при рисовании?

                  Ну и сама точка рисуется как прямоугольник:

                  ctx.fillRect(W/2+x*W/S,W/2+y*W/S,0.5,0.5)

                  Правильно ли я понимаю, что это прямоугольник с высотой и шириной 0.5 пиксела? Или с такой толщиной линии? Поясните, пожалуйста.

                  Я это к тому, что если такое делать на C++, как пытаюсь делать я, то нужно предпринимать какие-то ухищрения, чтобы так же рисовать. Например, формировать массив точек в памяти и там же смешивать цвета точек, если они попадают в одни и те же координаты.


                  1. samsergey Автор
                    29.05.2024 06:55
                    +1

                    Совершенно верно, на C++ надо делать тот или иной вид субпиксельного сглаживания. Именно такое смешивание, как вы описали, я и сделал для картинки выше: подсчитывал число попаданий точек в ячейку массива и отображал таким образом плотность.


                    1. voldemar_d
                      29.05.2024 06:55

                      Разные цвета при этом между собой тоже смешиваются? Или, если точка сменила цвет, то ее цвет полностью заменяется на другой?


                      1. samsergey Автор
                        29.05.2024 06:55
                        +1

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


              1. kipar
                29.05.2024 06:55

                в общем вот на паскале код:

                  RandSeed := 1;
                  for i := 1 to 100 do
                  begin
                    x := random;
                    y := random;
                    color := Random(MaxLongint);
                    for j := 1 to 1000 do
                    begin
                      pr2d_Pixel(x*1000,y*1000,color);
                      x := Frac(x+cos(y));
                      y := Frac(y+sin(x));
                    end;
                  end;
                

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


                1. findoff
                  29.05.2024 06:55

                  У вас как и выше в треде x,y последовательно друг друга портят... Надо z=x;x=...,y=...(z);


                  1. kipar
                    29.05.2024 06:55
                    +3

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

                    вот наугад добавил коэффициенты -

                          x := Frac(x+cos(1.5*y)-0.2);
                          y := Frac(y+sin(x));


                    1. voldemar_d
                      29.05.2024 06:55

                      Интересно, надо будет попробовать.


                      1. voldemar_d
                        29.05.2024 06:55
                        +2

                        Попробовал Ваш код, только увеличил число шагов во внешнем цикле до 500, а также цвет беру не совсем случайный, а случайный из фиксированного набора в несколько цветов. Также, при добавлении пиксела в точку смешиваю цвет с тем, что там уже есть, с весом 0.5.

                        ИМХО, довольно красиво получается:

                        Попробовал вариант и с дополнительными коэффициентами. В формуле Frac(x+cos(1.5*y)-0.2) вместо 1.5 генерирую случайное число в диапазоне от 0 до 1 и прибавляю 1, вместо 0.2 - еще одно случайное число от 0 до 1. Иногда интересные результаты получаются, например:

                        Надо еще какие-нибудь функции попробовать вместо sin/cos. В общем, бездна для творчества :-)


                      1. kipar
                        29.05.2024 06:55
                        +1

                        из функций я еще пробовал в свое время заменить синус и косинус на первые члены ряда тейлора (sin на x, cos на 1-x*x/2) и на (tan, 1-tan). Ну и да, коэффициенты. Моей мечтой было как-то сделать этот мир интерактивным, чтоб можно было "исследовать" отдельные области (как с фракталами), но каждая картинка на тогдашнем компе рисовалась секунды, так что далеко от этих картинок не ушел.

                        Из этой статьи я примерно понял хотя бы идею - должен быть поворот на 90 градусов+нелинейное искажение.


                      1. samsergey Автор
                        29.05.2024 06:55
                        +1

                        Анализируя вашу схему я бы тоже сначала рассмотрел первые члены рядов для синуса и косинуса.

                        Поворот не обязателен. В вашем случае роль складывания после искажения играет вычисление дробной части, то есть отображение всей плоскости на квадрат со стороной 1. Именно сочетание искажения и складывания обеспечивает перемешивание. А будут при этом неподвижные точки простых типов или странные аттракторы, конечно, зависит от конкретного преобразования.


                      1. voldemar_d
                        29.05.2024 06:55

                        Что-то мне подсказывает, что здесь периодичность функций ещё имеет значение.

                        Например, если заменить sin(x) на sin(x*x), картинка сразу в кашу превращается.

                        Ещё я попробовал заменить sin на функцию Бесселя, т.е. затухающую - то же самое. Явно должны быть периодически повторяющиеся значения, чтобы при отображении на квадрат возникали круги, а не просто каша из точек.

                        А какие ещё есть периодические функции, отличные от sin/cos?


                      1. kipar
                        29.05.2024 06:55

                        аргумент в синус приходит от 0 до 1, т.е. периодичность не провляется. И можно вообще заменить sin(x) на x - картинка принципиально не поменяется (станет чуть более скучной).


                      1. voldemar_d
                        29.05.2024 06:55

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


                      1. samsergey Автор
                        29.05.2024 06:55
                        +1

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

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

                        Переход от упорядоченных орбит к хаотическим может быть постепенным (через каскад удвоения периода) либо резким в случае развитого хаоса. Более или менее подробно я описывал это в статьях про прыгающий шарик (https://habr.com/ru/articles/750380/). В вашей схеме некоторые гиперболические точки выдают себя на картинках высокого разрешения крестообразными сгущениями орбит.


                      1. voldemar_d
                        29.05.2024 06:55

                        Не скажу, что я много что понял :) статью по ссылке почитаю, спасибо. А какая это область математики?


                      1. samsergey Автор
                        29.05.2024 06:55
                        +1

                        Теория динамических систем и теория хаоса.


                      1. voldemar_d
                        29.05.2024 06:55

                        А есть какие-то "жизненные" применения этих областей? Моделирование взрывов?


                      1. voldemar_d
                        29.05.2024 06:55

                        Моей мечтой было как-то сделать этот мир интерактивным

                        Тут есть ссылки на две реализации отрисовки в браузере на JS - подозреваю, если переписать отрисовку по sin/cos, должно работать и быстро, и интерактивно, как во втором примере с бегунками для параметров.


                    1. voldemar_d
                      29.05.2024 06:55

                      Попробовал с кое-какими изменениями, см. выше (сначала ответил не туда).


  1. Beholder
    29.05.2024 06:55

    Как в демке осуществлён переход от двумерной формулы к 3D? Какой-то параметр взят за третью координату?


    1. findoff
      29.05.2024 06:55

      Что-то вроде b=z


    1. samsergey Автор
      29.05.2024 06:55

      Я точно не скажу, это не моя программа, но думаю, что один или даже два параметра образуют пространство в котором "движется" наблюдатель, и на него уже проецируются фрагменты соответствующего этим параметрам аттрактора.


      1. voldemar_d
        29.05.2024 06:55

        Интересно, как это всё реализовано. Во время "полёта" заранее просчитывает сколько-то картинок? На каждую нужны десятки, а то и сотни тысяч итераций.


        1. findoff
          29.05.2024 06:55
          +2

          Ну мой не то что бы оптимизированный вариант на JS при определенных значениях генерит вполне похожую картинку за 20к итераций что занимает 11мс, при том что для 60фпс надо уложится в 16... Это если по картике на кадр, а там куда реже генерация, так что если еще и в веб поркере делать...


          1. voldemar_d
            29.05.2024 06:55

            Я так понимаю, алгоритм распараллелить не получится. Зато у современных процессоров есть много ядер. Можно в фоне несколько картинок генерировать в отдельных потоках, а показывать их, когда готовы.


            1. findoff
              29.05.2024 06:55

              Ну потому и сказал про WebWorker... Плюс даже на максимальной скорости полета там вроде не более 5ки картинок в секунду... Тут даже без многопоточности ресурсов достаточно.


              1. voldemar_d
                29.05.2024 06:55

                Глядя на то, с какой скоростью работает JS в браузере, сдается мне, что отрисовка использует аппаратные возможности GPU. Программно в памяти смешивание цветов с весом явно медленнее работает. Возможно, у меня руки кривые, но я реально тут вижу случай, когда что-то по-быстрому сделать на JS получается и проще, и быстрее, чем на C++.


                1. findoff
                  29.05.2024 06:55

                  Использует, но справедливости ради, хороший программный растиризатор тоже удивительно быстрым может быть.
                  Тот же хром если отключить апаратку даже 3д не так уж медленно рисует...
                  Те в плюсах и жсе сравнивать надо не их, а растеризатор в первую очередь.


            1. findoff
              29.05.2024 06:55

              А еще мне приходит в голову генерить это на шейдере, в том смысле что есть зависимость от сгенеренных, но в то же время сгенерив пару тысяч, мы можем шейдером каждым прогоном удваивать результат. А видеокарты щас быстрые.
              На самом деле это будет не полностью идентичный последовательной генерации результат, ибо погрешности попадения в пиксель будут, но близко думаю.
              Я проверил, если округлять границу пикселя, то все становится скучно, но если добавлять рандом после округления, то картинки визуально не отличимы от оригинала, не смотря на постоянное округление. (Тоже самое было бы с шейдером, но его я щас писать не готов)


            1. findoff
              29.05.2024 06:55

              Вообще может быть интересно рисовать на хосте, на который натравлять шейдер с инвертированной формулой. Те мы как бы будем своим рисованиям предоставлять x,y исходные...


  1. Imaginarium
    29.05.2024 06:55
    +3

    Спасибо за отличную статью и воспоминание о прекрасном журнале! В одном номере "В мире науки" я познакомился с петлевой квантовой гравитацией... Шикарный журнал)


  1. Dynasaur
    29.05.2024 06:55
    +2

    Похоже на множество Мандельброта. Там даже соревнования проводятся по рисованию :-)


    1. voldemar_d
      29.05.2024 06:55
      +1

      Кстати, в том же журнале, но в номере 10 за 1985 год, и про множество Мандельброта есть.


  1. findoff
    29.05.2024 06:55
    +4

    Чуть более удобная для игры с параметрами версия. ПыСы сделал на коленке.
    https://codepen.io/findoff/pen/rNgjVKY?editors=0010


    1. voldemar_d
      29.05.2024 06:55

      Жаль, значения параметров ограничены значением 10. В журнале, о котором идет речь, приведены интересные картинки, для получения некоторых используются значения a = 200, с = 80. А еще там есть пример с отрицательными значениями параметров.


      1. findoff
        29.05.2024 06:55

        Увеличил лимит до 200, но имхо тогда уже менее удобно прицеливатся ползунками.
        Ну и на отрицательных не вижу особого смысла, так как там в основном повторение, а прицеливатся еще сложнее...
        Upd: сделал таки отрицательные, но имхо интересный результат с ними только на c...


        1. voldemar_d
          29.05.2024 06:55

          В журнале пример a=-1000, b=0,1 и с=-10. Правда, картинка у меня получилась почему-то совсем не такая, как в журнале.

          Я думаю, вряд ли можно подобрать какой-то диапазон "на все случаи жизни".


          1. findoff
            29.05.2024 06:55
            +1

            Спорить не буду, но по мне так вообще не интересно, и +- вчера у меня на положительных что-то похожие было... А вот [-50,50,1000], 0.1, -10 выглядит куда интереснее. Но выставил +-2000, и scale от 0.1. Вообще если что на 24 строке исходника сами можете поправить лимиты, там без регистрации можно...


  1. playermet
    29.05.2024 06:55
    +3

    У меня аватарка похожим образом построена.

    Hidden text

    Код там правда был ужасный. Написано еще в студенчестве на редком диалекте паскаля Алго. А формулу вообще не помню откуда взял.


  1. stanislavskijvlad
    29.05.2024 06:55

    Красивый пледик, без шуток.

    Hidden text

    Я тут немного не в тему, вспомнился старый пост <<Логотип за три доллара>>. И там был пёс-арбуз с COM портом вместа рта. Что-то найти не могу.


  1. voldemar_d
    29.05.2024 06:55
    +1

    sign(x) - что за функция?


    1. paata
      29.05.2024 06:55
      +4

      Сигнум, он же знак. Может встретиться в виде sgn(x)


      1. voldemar_d
        29.05.2024 06:55
        +1

        Понял, так и думал, хотел уточнить.


  1. voldemar_d
    29.05.2024 06:55
    +1

    Есть где-нибудь более подробные статьи про данную тему? Попытался загуглить "итерационная схема Барри Мартина", ничего вразумительного не нашел.


    1. samsergey Автор
      29.05.2024 06:55
      +3

      Боюсь, что я создал нетленку -- то есть единственный на русском языке материал, посвящённый именно этой схеме. Если поискать в англоязычном сегменте (hopalong attractor, Martin's hopalong), то будет много этюдов по программированию на разных языках, демок или записей в блогах, а также несколько статей (https://jolinton.co.uk/Mathematics/Hopalong_Fractals/Text.pdf), посвящённых генеративному искусству, но не разбору динамики.

      Множество интересных схем есть здесь: https://paulbourke.net/fractals/


      1. voldemar_d
        29.05.2024 06:55

        Всё это очень интересно, спасибо. Помню, в 90-е годы на одном местном телеканале была заставка с подобными анимированными картинками.

        При многократном применении (итерациях) 

        Сколько итераций обычно требуется на построение одной картинки? Есть ли какой-то вычисляемый критерий, по которому программа сама может понять, что можно остановиться?


        1. findoff
          29.05.2024 06:55

          Все зависит от параметров, но ИМХО можно привязаться к дистанции от старта. Ибо точки обычно ложатся сериями в рамках старого рисунка.


      1. voldemar_d
        29.05.2024 06:55

        Нашел вот такой материал, скрипт для рисования тоже имеется. Но информация очень краткая. Там же есть целый большой раздел про фракталы.


    1. wert_lex
      29.05.2024 06:55

      Я мимо проходил, но кажется это фракталы.
      А по фракталам есть вузовские учебники. Как минимум нам откуда-то курс по ним читали


      1. voldemar_d
        29.05.2024 06:55
        +1

        Если я правильно помню, фракталы состоят из элементов, каждая часть которого рекурсивно заменяется на вложенный такой же элемент, и так до бесконечности. Здесь, вроде бы, не совсем такое. Если я не прав, пусть меня поправят.


        1. samsergey Автор
          29.05.2024 06:55
          +4

          Фрактальные объекты бывают самоподобны, но могут такими и не быть. Их главная особенность -- дробная размерность Хаусдорфа. Приведённый в статье объект фрактален, но не самоподобен.


  1. voldemar_d
    29.05.2024 06:55

    Интересно, с какими значениями параметров удается получить картинки с "пледиками", что в начале статьи? Или как на обложке журнала.


    1. voldemar_d
      29.05.2024 06:55
      +1

      Нашел скан журнала в PDF. Кое-какие интересные примеры значений параметров в нем приведены. Например, такие:

      Однако, по картинке пришлось изрядно покликать мышкой, чтобы такое получить.


  1. lrdprdx
    29.05.2024 06:55
    +1

    Круто ! Почему-то не могу плюсануть статью, хотя один голос за статью есть сегодня :) Напомнило кучки песчаные: https://math.stackexchange.com/q/2143728/383320


    1. voldemar_d
      29.05.2024 06:55

      Имхо, эти кучки чем-то на игру "жизнь" похожи, только не с полным уничтожением :)


  1. voldemar_d
    29.05.2024 06:55
    +1

    Попробовал алгоритм CIRCLE2 из статьи.

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


    1. samsergey Автор
      29.05.2024 06:55
      +1

      Про происхождение этих кругов я когда-то упоминал в небольшой статье о таблице умножения: https://dzen.ru/a/Y6KF_eLgZkAebaW9