Введение: визуализация рекурсии¶
В предыдущих разделах мы рассматривали задачи, которые могут быть легко решены с помощью рекурсии. Однако, найти ментальную модель или способ визуализации того, что происходит с рекурсивной функцией, по-прежнему непросто. Это делает рекурсию трудной для понимания. Поэтому в данной части мы рассмотрим несколько примеров использования рекурсии для рисования неких любопытных изображений. В процессе “прорисовки” этих картинок вы получите новое понимание рекурсивных процессов, что может быть полезным для закрепления вашего понимания рекурсии в целом.
Для наших иллюстраций мы воспользуемся графическим модулем Python под названием turtle . Он входит в стандартный набор модулей для всех версий Python и очень прост в применении. Метафора, объясняющее его название (turtle (англ.) — черепаха) крайне проста: вы можете создать черепаху, которая умеет двигаться вперёд-назад, поворачивать направо-налево и т.п. У неё есть хвост, который она может поднимать или опускать. Когда черепаший хвост опущен и она движется, то он рисует линию. Чтобы увеличить художественную ценность черепахи, вы можете менять толщину хвоста и цвет чернил, в которые он был окрашен.
Вот простой пример, показывающий основы “черепашьего рисования”. Мы используем модуль turtle , чтобы рекурсивно нарисовать спираль. ActiveCode 1 показывает, как это делается. После подключения модуля turtle создаётся черепаха, вместе с которой появляется и окно для рисования. Потом мы определяем функцию drawSpiral . Её базовым случаем будет момент, когда длина линии, которую мы хотим нарисовать (параметр len ), станет меньшей или равной нулю. Если же она больше нуля, то мы даём черепахе задание пройти len единиц, а затем повернуть на 90 градусов. Рекурсивным шагом будет вызов drawSpiral с уменьшенной длиной. В конце ActiveCode 1 вы увидитевызов функции myWin.exitonclick() . Она управляет маленьким оконным методом, который переводит черепаху в режим ожидания до тех пор, пока вы не кликните внутри окна. После этого программа очистит полотно и закроется.
Run Save Load Show in Codelens
Рекурсивное рисование спирали с использованием черепахи (lst_turt1)
Вот и всё о “черепашьей графике”, что вам нужно знать для рисования некоторых довольно впечатляющих картинок. В нашей следующей программе мы собираемся изобразить фрактальное дерево. Фракталы — это одна из ветвей математики, и они имеют с рекурсией много общего. Определение фрактала заключается в том, что вне зависимости от приближения он всегда содержит некоторую основную фигуру. Примерами из живой природы могут послужить береговые линии континентов, снежинки, горы и даже деревья или кустарники. Фрактальная природа этих объектов позволяет программистам генерировать очень реалистично выглядящие пейзажи для компьютерных изображений. Да и мы в следующем примере будем генерировать фрактальное дерево.
Чтобы понять, как всё это работает, полезно подумать над тем, как можно описать дерево, используя терминологию фракталов. Вспомните, что мы говорили выше: фрактал — это то, что выглядит одинаково на всех уровнях увеличения. Транслируя эту мысль на деревья и кустарники, можно сказать, что даже самая маленькая веточка имеет ту же форму и характеристики, что и целое дерево. Т.е. можно сказать, что дерево — это ствол от которого вправо и влево отходят меньшие деревья. Если вы подумете об этом определении, то поймёте, что его можно рекурсивно применить и для меньших правого и левого деревьев.
Давайте переведём эти мысли в код на Python. Листинг 1 демонстрирует, как можно использовать нашу черепаху для генерации фрактального дерева. Посмотрим на код поближе. Хорошо видно, что рекурсивные вызовы делаются в строках 5 и 7. В строке 5 сразу после него черепаха поворачивает вправо на 20 градусов — это правое дерево. Затем в строке 7 вновь делается рекурсивный вызов, но в этот раз с поворотом влево на 40 градусов. Выбор этого числа связан с необходимостью скомпенсировать уже сделанный поворот на 20 градусов, а затем повернуть ещё на 20 влево с целью нарисовать левое дерево. Также обратите внимание, что при каждом рекурсивном вызове tree мы вычитаем из параметра branchLen некую величину. Это делается для того, чтобы рекурсивные деревья становились всё меньше и меньше. Вы также можете разобраться, что первоначальный оператор if в строке 2 проверяет базовый случай: branchLen стала слишком маленькой.
Листинг 1
1 2 3 4 5 6 7 8 9
def tree(branchLen,t): if branchLen > 5: t.forward(branchLen) t.right(20) tree(branchLen-15,t) t.left(40) tree(branchLen-10,t) t.right(20) t.backward(branchLen)
Полностью программа для примера с деревом показана в ActiveCode 2. До того, как вы запустите её, подумайте: как должно выглядеть дерево? Посмотрите на рекурсивные вызовы и представьте, как оно будет разворачиваться. Будут ли его правая и левая части рисоваться симметрично и одновременно? Или сначала нарисуется правая, а затем левая половина?
Как нарисавать Архимедову спираль на Python?
Помогите с рисованием архимедовой спирали с помощью инструкции turtle в питоне. Какая там должна быть рекурсия?
- Вопрос задан более трёх лет назад
- 13314 просмотров
Комментировать
Решения вопроса 1

I need your traceback.
Ответ написан более трёх лет назад
Иван @IvanPsarev Автор вопроса
Большое спасибо!
Ответы на вопрос 2
Привет. Эту задачку я нашёл в курсе python от МФТИ. Сразу оговорюсь, учиться кодить я начал где-то с месяц назад.
Есть 2 варианта — непосредственное «рисование» спирали черепашкой:
import turtle
turtle.shape(‘turtle’)
k=1
fi_rad=0.1
fi_degr=fi_rad*(180/3.14)
for i in range (0,1000):
ro=k*fi_rad
turtle.forward(ro)
turtle.left(fi_degr)
fi_rad+=0.1
ro+=ro
или перемещение черепашки на спираль:
import turtle
turtle.shape(‘turtle’)
import math
k=1
fi_rad=0.1
for i in range (0,1000):
ro=k*fi_rad
x = math.cos(fi_rad)*ro
y = math.sin(fi_rad)*ro
turtle.goto(x,y)
fi_rad+=0.1
В любом случае, настоятельно рекомендую решить задачу самостоятельно, т.к. именно те муки, которые ты испытываешь при решении задачи — которые заставляют тебя гуглить твой запрос, генерируют новые нейроны в твоем мозгу и делают тебя умнее.
Рисование спирали Python turtle
Дальше приходит в голову только вручную менять значения угла поворота черепахи через определенные пройденные ей расстояния (четверти координат). А как можно написать правильный алгоритм для именно для спирали?
Отслеживать
задан 14 апр 2019 в 10:47
rootheaven rootheaven
65 1 1 золотой знак 1 1 серебряный знак 7 7 бронзовых знаков
Сомневаюсь, что черепашка — подходящий инструмент для рисования не симметричных кривых. Отклонения будут накапливаться и в итоге всё будет перекашиваться.
14 апр 2019 в 11:17
Это задание из курса МФТИ — рисование разных фигур с помощью turtle, спираль — одна из них. judge.mipt.ru/mipt_cs_on_python3/labs/lab1.html
14 апр 2019 в 11:22
6 ответов 6
Сортировка: Сброс на вариант по умолчанию
Нужно было подключить модуль math , а дальше уже математика.
from math import pi, sin, cos import turtle turtle.shape('turtle') for i in range(200): t = i / 10 * pi dx = t * cos(t) dy = t * sin(t) turtle.goto(dx, dy)
Отслеживать
ответ дан 14 апр 2019 в 14:13
rootheaven rootheaven
65 1 1 золотой знак 1 1 серебряный знак 7 7 бронзовых знаков
Найдено на просторах интернета
from turtle import Turtle, Screen from math import pi, sin, cos from random import randint, random RADIUS = 180 # roughly the radius of a completed spiral screen = Screen() WIDTH, HEIGHT = screen.window_width(), screen.window_height() turtle = Turtle(visible=False) turtle.speed('fastest') # because I have no patience turtle.up() for _ in range(3): x = randint(RADIUS - WIDTH//2, WIDTH//2 - RADIUS) y = randint(RADIUS - HEIGHT//2, HEIGHT//2 - RADIUS) turtle.goto(x, y) turtle.color(random(), random(), random()) turtle.down() for i in range(200): t = i / 20 * pi dx = (1 + 5 * t) * cos(t) dy = (1 + 5 * t) * sin(t) turtle.goto(x + dx, y + dy) turtle.up() screen.exitonclick()
Python-сообщество
![]()
- Начало
- » Python для новичков
- » Черепаха — спираль Архимеда.
#1 Дек. 20, 2020 12:32:51
0ppa Зарегистрирован: 2020-08-12 Сообщения: 18 Репутация: 1 Профиль Отправить e-mail
Черепаха — спираль Архимеда.
Добрый день всем.
Я нашел разные решения Архимедовой спирали, на это задание https://mipt-cs.github.io/python3-2017-2018/labs/lab1.html#o7
Вот пример кода, по формуле из википедии спираль:
import turtle import math turtle.shape('turtle') e=3.14159265358979 a=10 k=a/(2*e) g=0 while g3*(2*e): D=k*g x = D * math.cos(g) y = D * math.sin(g) turtle.goto(x,y) g=0.1+g
Вот отсюда взял другой код- код:
import turtle import math turtle.shape('turtle') e=3.14159265358979 a =- 2 b =- 3 theta=0 while theta10*e: theta=0.01+theta r =- a + b*theta x=r*math.cos(theta) y=r*math.sin(theta) turtle.goto(x, y)
Но тут используется уже другая формула, по факту уже из английской википедии: спираль_en
Несмотря на то что используются разные формулы, все равно получается спираль …
Я не могу понять почему так … В чем разница при использовании разных формул? Просто какая-то из них точнее?
Отредактировано 0ppa (Дек. 20, 2020 12:42:34)