9.2.2. Рисование кривых и снежинок Коха Можно взглянуть на кривые Коха иначе: каждое поколение состоит из четырех версий предыдущего поколения. Например, кривая К2, показанная на рис. 9.1, состоит из четырех кривых Kv соединенных своими концами под определенными углами между ними. Назовем п порядком (order) кривой Кя, тогда можно говорить, что кривая Коха и-го порядка состоит из четырех кривых Коха (я-1)-го порядка. Здесь естественно рассуждать в терминах черепашьей графики (вспомните главу 3): для того чтобы нарисовать кривую К2, нарисуем уменьшенную версию кривой Kv затем повернем влево на 60°, снова нарисуем Kit повернем вправо на 120°, нарисуем Kt в третий раз и т. д. Для снежинки эта процедура применяется трижды, с промежуточным поворотом в 120°.
9.2. Фракталы и самоподобие
S55
Таким образом, мы имеем естественный рекурсивный метод для рисования кривой Коха любого порядка; ниже приводится его псевдокод.
То draw Кп:
if (n equals 0) Draw a straight line: else{
Draw Kn-1 ; Turn left 60°: Draw Kn-1 ; Turn right 120°: Draw Kn-1 : Turn left 60°: Draw Kn-1 :
}
Подпрограмма drawKochO, приведенная в листинге 9.1, рисует кривую К на базе «родительской» прямой с длиной Теп, которая идет из текущей позиции в направлении dir. Можно представить подпрограмму КоспО как способ «усложнения» родительской прямой до кривой Коха, именно поэтому мы и назвали эту подпрограмму именем Коха. Для отслеживания направления каждого «дочернего» поколения в последовательные вызовы подпрограммы КоспО передается параметр направления dir.
Листинг 9.1. Рисование кривой Коха
void drawKoch(double dir. double len. int n) { // "Koch" to order n the line of length len // from CP in the direction dir // «кохируем» до n-го порядка прямую длины len // из точки CP в направлении dir
double dirRad = 0.0174533 * dir: // in radians // в радианах
1f(n == 0)
lineReKlen * cos(dirRad). Ten * sin(dirRad)):
else{
n--;
// reduce the order // уменьшаем порядок