Раздел «Язык Си».PythonFractal:

Фракталы

Рекурсивный вызов функций

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

Пример 1: Рисуем дерево

Нарисуем дерево с помощью рекурсивного вызова. Пусть дерево каждый год вырастает на 1 уровень, каждая ветка дает 2 новые веточки, отклоняющиеся на угол +ang и -ang от направления роста ветки. Размер ветки size, а веточки меньше ее на d.

Функция tree(size, d, ang, n) будет рисовать дерево, которое росло n лет.

Функция tree нарисует ветку, вызовет саму себя 2 раза, чтобы нарисовать веточки, и вернется в точку, где начинала рисовать.

n - сколько лет дереву осталось расти.

tree(100, 20, 30, 1) tree(100, 20, 30, 3) tree(100, 20, 30, 5)

# -*- coding: utf-8 -*-
import turtle           
import time

'''
tree(size, d, ang, n) - рисовать дерево, которое росло n лет.
Пусть дерево каждый год вырастает на 1 уровень, 
каждая ветка дает 2 новые веточки, 
отклоняющиеся на угол +ang и -ang от направления роста ветки. 
Размер ветки size, а веточки меньше ее на d.
'''
def tree(size, d, ang, n):
  if n == 0:                  # дерево закончило расти, возвращаемся
    return
  
  t.fd(size)                  # рисуем ветку
  t.left(ang)                 # поворачиваемся рисовать левую веточку
  tree(size-d, d, ang, n-1)   # рисуем левое поддерево (веточку и дальше)
                              # после этой функции черепаха будет в том же месте
                              # и повернута на тот же угол
  t.left(-2*ang)              # поворачиваемся рисовать правую веточку
  tree(size-d, d, ang,  n-1)  # рисуем правое поддерево (веточку и дальше)
                              # после этой функции черепаха будет в том же месте
  t.left(ang)                 # возвращаем направление ветки
  t.fd(-size)                 # возвращаемся в начало ветки
                              # конец функции

t = turtle.Turtle()
t.shape("turtle")
t.width(3)
t.speed(0)

t.seth(90)
t.up()
t.bk(200)
t.down()
t.color('brown')

tree(100, 20, 30, 1)

turtle.done() 

Задача 1: Нарисовать дерево с зелеными листьями

Ветки последнего года у дерева нарисовать зелеными (green). Старые ветки рисовать коричневыми (brown).

tree(100, 20, 30, 1) tree(100, 20, 30, 3) tree(100, 20, 30, 5)

Фракталы (теория)

Фракта́л (лат. fractus — дроблёный, сломанный, разбитый) — математическое множество, обладающее свойством самоподобия (объект, в точности или приближённо совпадающий с частью себя самого, то есть целое имеет ту же форму, что и одна или более частей)

Один из способов нарисовать фрактальную кривую - рисовать заменяя отрезок на набор отрезков.

Список фракталов на английском языке

Пример 2: Кривая Коха

Кривая Коха - на каждой итерации каждый отрезок заменяется на такой набор отрезков:

Koch_curve_construction.png

Функция koch_line(size, n) рисует на отрезке длины size кривую Коха и делает n итераций (рисует кривую Коха глубины n)

koch_line(200, 0) koch_line(200, 1) koch_line(200, 3)

# -*- coding: utf-8 -*-
import turtle           
import time

def koch_line(size, n):
  if n == 0:        # рисуем линию и дальше не идем
    t.fd(size)
    return
    
  a = size/3        # иначе разбиваем отрезок 
                    # и вместо него делаем набор отрезков  
  koch_line(a, n-1)
  t.left(60)
  koch_line(a, n-1)
  t.right(120)
  koch_line(a, n-1)
  t.left(60)
  koch_line(a, n-1)
                    # конец функции

t = turtle.Turtle()
t.shape("turtle")
t.width(3)
t.speed(0)

t.color('blue')
koch_line(200, 3)

turtle.done()    

Можем нарисовать итерацию одну за другой разным цветом:

e12_2_all.png

# -*- coding: utf-8 -*-
import turtle           
import time

tones = [
  'yellow',   # tones[0]
  'gold',     # tones[1]
  'orange',   # tones[2]
  'red',      # tones[3]
  'violet',   # tones[4]
  'blue',     # tones[5]
  'green'     # tones[6]
  ]

def koch_line(size, n):
  if n == 0:        # рисуем линию и дальше не идем
    t.fd(size)
    return
    
  a = size/3        # иначе разбиваем отрезок 
                    # и вместо него делаем набор отрезков  
  koch_line(a, n-1)
  t.left(60)
  koch_line(a, n-1)
  t.right(120)
  koch_line(a, n-1)
  t.left(60)
  koch_line(a, n-1)
                    # конец функции

t = turtle.Turtle()
t.shape("turtle")
t.width(3)
t.speed(0)

for i in range(5):    # i = 0..4
  p0 = t.pos()           # запомнили начальную позицию в p0
  t.color(tones[i])      # новой итерации - новый цвет
  koch_line(300, i)      # нарисовали кривую Коха глубины i
  
  t.up()                 # вернулись на начальную позицию
  t.goto(p0)
  t.down()
  time.sleep(1)          # ждем 1 секунду

turtle.done()    

Задача 2: Снежинка Коха

Снежинка Коха (при увеличении глубины):

Von_Koch_curve.gif

Написать функцию koch_tri(size, n), которая рисует снежинку Коха глубины n, у которой сторона первого треугольника size.

Результаты вызовов функции:

KochFlake.png

Задача 3а: Построить кубическую кривую 1 типа

Итерации разной глубины:

koch_1_iter.png

Конечный результат:

koch_1_res.png

Вызов функции для разных глубин и цветов:

Задача 3b: Построить кубическую кривую 2 типа (кривая Минковского)

Итерации разной глубины:

koch_2_iter.png

Конечный результат:

koch_2_res.png

Еще одна картинка, где показывают как получается кривая:

Minkowsky01.gif

Вызов функции для разных глубин и цветов:

Задача 3c: Кривая Леви

Написать функцию levy_line(size, n), которая рисует кривую Леви глубины n, при длине отрезка size.

При увеличении глубины форма кривой меняется так:

levi_iter.png

levi_res.gif

koch_line(320, 4)
koch_line(320, 7)
koch_line(320, 10)

Кресты Висека

Теория

cross_iter.png

Задача 4a: Крест-1

Написать функцию, которая рисует крест глубины n.

Пример вызова функции для глубины 3

Задача 4b: Крест-2

Написать функцию, которая рисует крест глубины n.

Пример вызова функции для глубины 3

Ковер и треугольник Серпинского

Задача 4c: Ковер Серпинского

Ковер Серпинского

Написать функцию, которая рисует ковер Серпинского глубины n.

Ковер Серпинского с увеличением глубины выглядит так:

Animated_Sierpinski_carpet.gif

Ковер Серпинского глубины 3:

t12_carpet_sq.png

Задача 4d: Треугольник Серпинского

Треугольник Серпинского

Написать функцию, которая рисует треугольник Серпинского глубины n.

Треугольник Серпинского с увеличением глубины выглядит так:

Sierpinsky_triangle.png

Animated_construction_of_Sierpinski_Triangle.gif

Треугольник Серпинского глубины 3:

t12_carpet_tr.png

Дерево Пифагора

Дерево Пифагора основано на построении "Пифагоровы штаны", которое используется для доказательства теоремы Пифагора (квадрат гипотенузы равен сумме квадратов катетов).

Классическое дерево строится на прямоугольном треугольнике с углами в 45o. Можно построить дерево на непрямоугольном треугольнике. Или взять не равнобедренный треугольник ("дерево, обдуваемое ветром").

PythagorasTree.gif

Задача 5а: Классическое дерево Пифагора

Написать функцию, которая строит дерево Пифагора глубины n.

На квадрате построен равнобедренный треугольник с углом при основании 45o.

Построенное дерево глубины 7.

t12_pitree0.png

Задача 5b: Дерево Пифагора с равнобедренным треугольником и углом при основании 30o

Написать функцию, которая строит дерево Пифагора глубины n.

На квадрате построен равнобедренный треугольник с углом при основании 30o.

Построенное дерево глубины 7.

t12_pitree30s.png

Задача 5c: Дерево Пифагора, обдуваемое ветром

Написать функцию, которая строит дерево Пифагора глубины n.

На квадрате построен прямоугольный треугольник с углом при основании 30o.

Построенное дерево глубины 7.

t12_pitree30r.png

Задача 5d: Обобщенное дерево Пифагора, обдуваемое ветром

Написать функцию, которая строит дерево Пифагора глубины n.

На квадрате построен прямоугольный треугольник с углом при основании ang градусов.

Построенное дерево для угла ang=30 и глубины 7.

t12_pitree30r.png

Создание последовательностей

Пример: Кривая дракона (генерация последовательностей)

Написать функцию, которая строит кривую дракона глубины n.

t12_dragon_iter.png

Можно подойти к построению кривой по-другому. Запишем правила создания кривой как "что-то заменить на другое"

# -*- coding: utf-8 -*-
import turtle           
import time
import math

def gen(size, n):   # Первый отрезок обозначим как АF
  t.fd(size)
  A(size, n-1)
  
def A(size, n):
  if n==0:          # A не рисуем никак
    return
                    # из А получаем A+BF+
  A(size, n-1)      # A
  t.right(90)       # +
  B(size, n-1)      # B
  t.fd(size)        # F
  t.right(90)       # +
    
def B(size, n):
  if n==0:          # B не рисуем никак
    return
                    # из В получаем −FA−B
  t.left(90)        # -
  t.fd(size)        # F
  A(size, n-1)      # A
  t.left(90)        # -
  B(size, n-1)      # B
  
t = turtle.Turtle()
t.shape("turtle")
t.width(3)
t.speed(0)
t.color('blue')

gen(10, 10)     # правила применили глубиной 10

t.hideturtle()
turtle.done()

Задача 6. Кривая Гильберта

Написать функцию, которая строит кривую Гильберта глубины n.

Кривую Гильберта можно задать разными способами:

Hilbert_curve.png

Или можно записать правила:

t12_hilbert.png

Задача 7: Треугольник Серпинского через порождающие правила

Треугольник Серпинского можно задать через порождающие правила:

t12_7.png

Задача 8: Наконечник Серпинского

Треугольник Серпинского можно задать через порождающие правила:

Arrowhead_curve_1_through_6.png

t12_8.png

Задача:

Напишите для кривой правила создания и напишите функцию через эти правила. Кривая:

koch_1_iter.png

В разработке

Крест (3 варианта)

220px-Q_Cross_Fractal_Generator.jpg

Attachment sort Action Size Date Who Comment
e12_1_1.png manage 0.4 K 13 May 2017 - 11:49 TatyanaDerbysheva  
e12_1_3.png manage 2.3 K 13 May 2017 - 11:50 TatyanaDerbysheva  
e12_1_5.png manage 4.1 K 13 May 2017 - 11:50 TatyanaDerbysheva  
t12_1_1.png manage 0.4 K 13 May 2017 - 12:07 TatyanaDerbysheva  
t12_1_3.png manage 2.2 K 13 May 2017 - 12:07 TatyanaDerbysheva  
t12_1_5.png manage 4.1 K 13 May 2017 - 12:07 TatyanaDerbysheva  
Koch_curve_construction.png manage 6.3 K 13 May 2017 - 14:12 TatyanaDerbysheva  
KochFlake.png manage 6.9 K 13 May 2017 - 14:13 TatyanaDerbysheva  
e12_2_0.png manage 0.4 K 13 May 2017 - 14:34 TatyanaDerbysheva  
e12_2_1.png manage 0.8 K 13 May 2017 - 14:35 TatyanaDerbysheva  
e12_2_3.png manage 1.2 K 13 May 2017 - 14:35 TatyanaDerbysheva  
e12_2_all.png manage 2.7 K 13 May 2017 - 14:35 TatyanaDerbysheva  
Von_Koch_curve.gif manage 12.7 K 13 May 2017 - 14:38 TatyanaDerbysheva  
Minkowsky01.gif manage 770.5 K 13 May 2017 - 14:56 TatyanaDerbysheva  
koch_1_iter.png manage 10.8 K 13 May 2017 - 15:02 TatyanaDerbysheva  
koch_1_res.png manage 3.5 K 13 May 2017 - 15:02 TatyanaDerbysheva  
koch_2_iter.png manage 8.5 K 13 May 2017 - 15:02 TatyanaDerbysheva  
koch_2_res.png manage 3.2 K 13 May 2017 - 15:02 TatyanaDerbysheva  
t12_2a.png manage 2.8 K 13 May 2017 - 15:55 TatyanaDerbysheva  
t12_2b.png manage 9.6 K 13 May 2017 - 15:55 TatyanaDerbysheva