Кривая дракона — общее название для некоторых кривых фрактальных , которые могут быть аппроксимированы рекурсивными методами, такими как L-системы. Дракон Хартера, также известный как дракон Хартера — Хейтуэя, был впервые исследован физиками NASA — John Heighway, Bruce Banks, и William Harter. Он был описан в 1967 году Мартином Гарднером (Martin Gardner).
Естественно, рисовать буду на Canvas :3
L-системы, к слову, иначе называются переписываемыми алгоритмами генерации математических структур. Данный тип алгоритмов был предложен в 1904 году математиком Хельгой фон Кох (H. von Kokh) (снежинка Коха). В конце пятидесятых годов Хомский использовал эти алгоритмы для описания формальных грамматик. Кто изучал трансляторы, тот понимает о чём речь.
Кривая дракона
Кривая дракона — это кривая без самопересечений, которая определяется рекурсивно. Интересовал больше математический аспект. Ну, как обычно, используется формула для поворота точки относительно другой точки:
Когда начал реализовывать фрактал, то сначала хотел запоминать точки на каждой итерации. Затем хотел сделать рекурсию, для нахождения точки (то есть смотреть предыдущие итерации сначала). В итоге, реализовал так же как снежинку Коха.
Решил закономерность выявить, как же изгибается линия. Когда влево, а когда вправо. В итоге, закономерность была найдена. В зависимости от номера линии, определяем знак. Это потом необходимо для вычисления угла поворота следующей точки.
this.sign= function(i) { var j = i; while(true) { if ((j-1) % 4 == 0) return -1; else if ((j-3) % 4 == 0) return 1; else j=j/2; } }
Собственно, вот.
a =((a - 90*this.sign(i))+a)%360;
Уже после того, как допёр сам, нашёл в инете логику эту =_= Описать эту кривую можно, задавая поворот налево цифрой 1, а поворот направо — цифрой 0. Важно, что все повороты совершаются на один и тот же угол.
Порядком кривой дракона называется количество звеньев получающейся ломаной. Кривая первого порядка определяется просто как 1. Для кривых более высоких порядков справа приписываем 1, а затем дополняеся цифрами, которые стоят левее этой единицы справа налево, записывая их слева направо, но только заменяем нули на единицы, а единицы на нули.
Как пример, кривая второго порядка: сначала 1, приписываем справа 1: 11, а теперь справа добавляем единицу, замененную на нуль, получаем 110. Кривая третьего порядка: берем 110, приписываем справа единицу: 1101, а теперь добавляем число, которое стоит слева от последней единицы (это 110), записанное в обратном порядке (011), заменяя нули на единицы и обратно, т.е. число 100, получаем 1101100. Для четвёртого: 110110011100100.
Сам поворот:
this.pointRotation= function(x1,y1,x2,y2,a) { var resx = x1+(x2-x1)*Math.cos(a*Math.PI/180)-(y2-y1)*Math.sin(a*Math.PI/180); var resy = y1+ (x2 - x1)*Math.sin(a*Math.PI/180)+(y2-y1)*Math.cos(a*Math.PI/180); return {x:resx, y:resy}; }
В первом случае рисуются все итерации, и показано как изгибаются линии на следующей итерации.
Во втором случае рисуется только конечная итерация.
Если интересно, можете покопаться в исходнике.