Автор Гілка: Трикутник Серпінського  (Прочитано 10447 раз)

Відсутній DrIgor

  • Дописувач
  • **
  • дописів: 53
  • Карма: +0/-0
  • Люблю пінгвінчиків
Шановні колеги, допоможіть правильно намалювати трикутник Серпінського на мові Python з використанням модуля Turtle. Я написав ось такий код:
from turtle import *
speed('fastest')
def recu(n,l):
    if n>1:
        forward(l/n)
        recu(n-1,l)
        left(60)
        forward(l)
        recu(n-1,l)
        left(60)
        forward(l)
        recu(n-1,l)
        right(60)
        forward(l)
        recu(n-1,l)
        right(60)
        forward(l)
        recu(n-1,l)
        right(60)
        forward(l)
        recu(n-1,l)
        right(60)
        forward(l)
        recu(n-1,l)
        left(60)
        forward(l)
        recu(n-1,l)
        left(60)
        forward(l)
        recu(n-1,l)
a=input()
l=5/a
recu(a,l)
a=input()
При цьому отримую зображення:

А повинно бути таке:

Але звичайно чорно-біле :)
Я розумію, що це відбувається через зсув при першому рекурсивному виклику, можливо рекурсія взагалі невдала. Але мене цікавить конкретний приклад програми.

Відсутній DrIgor

  • Дописувач
  • **
  • дописів: 53
  • Карма: +0/-0
  • Люблю пінгвінчиків
Re: Трикутник Серпінського
« Відповідей #1 : 2008-12-14 17:53:25 »
Розібрався, справа не в рекурсії, а в алгоритмі. Я будував один з різновидів сніжинки Коха, а не трикутник Серпінського.

Відсутній DrIgor

  • Дописувач
  • **
  • дописів: 53
  • Карма: +0/-0
  • Люблю пінгвінчиків
Re: Трикутник Серпінського
« Відповідей #2 : 2008-12-14 23:18:37 »
Вдалося самому розібратися з цим питанням. Якщо комусь цікаво, код трикутника:
from turtle import *
speed('fastest')
def recu(q,n):
    if n>2:
        left(q)
        recu(-q,n-1)
        right(q)
        recu(q,n-1)
        right(q)
        recu(-q,n-1)
        left(q)
    else:
        left(q)
        forward(n)
        right(q)
        forward(n)
        right(q)
        forward(n)
        left(q)
a=input()
recu(60,a)
a=input()
Черепаха при цьому "вишиває" такий малюнок

Заодно написав код на python, що малює "дракона"
from turtle import *
speed('fastest')
def recu(q,n):
    if n>3:
        left(q)
        if q>0:
            recu(q,n-1)
        else:
            recu(-q,n-1)
        right(q*2)
        if q>0:
            recu(-q,n-1)
        else:
            recu(q,n-1)
        left(q)
    else:
        forward(n)
a=input()
recu(45,a)
a=input()

А також при написанні дракона в процесі "виник", ще один цікавий фрактал, ось код:
from turtle import *
speed('fastest')
def recu(q,n):
    if n>3:
        left(q)
        recu(q,n-1)
        right(q*2)
        recu(-q,n-1)
        left(q)
    else:
        forward(n)
a=input()
recu(45,a)
a=input()

Відсутній Kovyar

  • Кореспондент
  • ***
  • дописів: 130
  • Карма: +0/-0
  • Студент
Re: Трикутник Серпінського
« Відповідей #3 : 2008-12-14 23:33:50 »
Класно намальовано [smiley=41.gif] [smiley=41.gif], але:
ви впевнені, що фігура, побудована таким чином, буде трикутником Серпінського?
[Fedora 10 Cambridge] [Debian Lenny] [GNOME user]

Відсутній DrIgor

  • Дописувач
  • **
  • дописів: 53
  • Карма: +0/-0
  • Люблю пінгвінчиків
Re: Трикутник Серпінського
« Відповідей #4 : 2008-12-14 23:44:00 »
Класно намальовано [smiley=41.gif] [smiley=41.gif], але:
ви впевнені, що фігура, побудована таким чином, буде трикутником Серпінського?
Звичайно впевнений :) Адже принцип побудови придумав не я. Я знав як ця фігура повинна утворюватися, залишалося лише придумати алгоритм і записати програму.

Відсутній Kovyar

  • Кореспондент
  • ***
  • дописів: 130
  • Карма: +0/-0
  • Студент
Re: Трикутник Серпінського
« Відповідей #5 : 2008-12-14 23:50:44 »
просто алгоритм побудови (наскільки я знаю) - викреслювання центральних трикутників.
при цьому фігура дещо інша виходить  :-/
[Fedora 10 Cambridge] [Debian Lenny] [GNOME user]

Відсутній DrIgor

  • Дописувач
  • **
  • дописів: 53
  • Карма: +0/-0
  • Люблю пінгвінчиків
Re: Трикутник Серпінського
« Відповідей #6 : 2008-12-15 00:18:12 »
просто алгоритм побудови (наскільки я знаю) - викреслювання центральних трикутників.
при цьому фігура дещо інша виходить  :-/
Якщо в програмі зменшити довжину відрізка та збільшити глибину рекурсії отримається малюнок більш наближений до граничного зображення трикутника Серпінського. Наприклад змінивши код так:
from turtle import *
speed('fastest')
def recu(q,n):
    if n>0.5:
        left(q)
        recu(-q,n-0.5)
        right(q)
        recu(q,n-0.5)
        right(q)
        recu(-q,n-0.5)
        left(q)
    else:
        left(q)
        forward(n)
        right(q)
        forward(n)
        right(q)
        forward(n)
        left(q)
a=input()
recu(60,a)
a=input()
Та задавши глибину рекурсії 10, отримується таке зображення:

Відсутній Kovyar

  • Кореспондент
  • ***
  • дописів: 130
  • Карма: +0/-0
  • Студент
Re: Трикутник Серпінського
« Відповідей #7 : 2008-12-15 00:35:49 »
згоден, виглядає набагато краще.
І дійсно, схоже, що в граничному випадку то буде той самий трикутник. Вибачте
[Fedora 10 Cambridge] [Debian Lenny] [GNOME user]

Praporshic

  • Гість
Re: Трикутник Серпінського
« Відповідей #8 : 2008-12-15 00:46:49 »
О, тепер я знаю чим зайняти процесор [smiley=35.gif]
Ще й привід Python вивчити....

Відсутній DrIgor

  • Дописувач
  • **
  • дописів: 53
  • Карма: +0/-0
  • Люблю пінгвінчиків
Re: Трикутник Серпінського
« Відповідей #9 : 2008-12-18 10:55:23 »
Вирішив спробувати будувати фрактали в пітоні використовуючи графічне полотно Tk. Для початку спробував розглянути множину Манделброта. Наприклад така програмка:
from Tkinter import *
from Canvas import *
from cmath import *
root=Tk()
cv=Canvas(root,width=400,height=400,background='black')
c=-0.5-0.6j
for m in range(2000,10000,20):
    for l in range(2000,10000,20):
        i=m/8000.0
        j=l/8000.0
        p=i+j*sqrt(-1)
        s='q'
        n=0
        for k in ("#000040","#000049","#000060","#000069"
                  ,"#000090","#000099","#004000","#0040AA"
                  ,"#0040FF","#007000","#007040","#007070"
                  ,"#009010","#009060","#009090","#0090FF"
                  ,"#000040","#000060","#000090","#0000AA"
                  ,"#001010","#0040AA","#0090FF","#00AAAA"
                  ,"#001000","#0000AA","#00A0A0","#00FF10"
                  ,"#00A010","#00F000","#0F00FF","#0FFF00"):
            n=k
            if abs(p)>4:
                s='w'
                break
            s='q'
            p=(p**2)+c
        if s=='q':
            Line(cv,m/20-100,l/20-100,m/20-100+1,l/20-100+1,fill='white')
        if s=='w':
            Line(cv,m/20-100,l/20-100,m/20-100+1,l/20-100+1,fill=n)          
cv.pack()
root.mainloop()

малює ось такий гарний фрактал:



Але ось в чому проблема, якщо хто уважно переглянув код, то напевно помітив, що я малював точки використовуючи малювання ліній. При цьому не можу знайти жодного посилання на малювання точки. Невже в цьому графічному модулі пітона немає такої дрібниці?

Praporshic

  • Гість
Re: Трикутник Серпінського
« Відповідей #10 : 2008-12-18 11:03:13 »
Але ось в чому проблема, якщо хто уважно переглянув код, то напевно помітив, що я малював точки використовуючи малювання ліній. При цьому не можу знайти жодного посилання на малювання точки. Невже в цьому графічному модулі пітона немає такої дрібниці?
Кастую у тред Raven`а.

Відсутній DrIgor

  • Дописувач
  • **
  • дописів: 53
  • Карма: +0/-0
  • Люблю пінгвінчиків
Re: Трикутник Серпінського
« Відповідей #11 : 2008-12-18 11:45:08 »
Але ось в чому проблема, якщо хто уважно переглянув код, то напевно помітив, що я малював точки використовуючи малювання ліній. При цьому не можу знайти жодного посилання на малювання точки. Невже в цьому графічному модулі пітона немає такої дрібниці?
Кастую у тред Raven`а.
Не розумію, що таке тред Raven`a ::)
Але схоже, що в Canvas немає метода який малює точку. Ось всі методи створення зображень на полотні:
create_arc(self, *args, **kw)
create_bitmap(self, *args, **kw)
create_image(self, *args, **kw)
create_line(self, *args, **kw)
create_oval(self, *args, **kw)
create_polygon(self, *args, **kw)
create_rectangle(self, *args, **kw)
create_text(self, *args, **kw)
create_window(self, *args, **kw)
Серед них немає того, що я шукав :(. Прийдеться замість ложки використовувати ополоник :o

Praporshic

  • Гість
Re: Трикутник Серпінського
« Відповідей #12 : 2008-12-18 12:04:49 »
Не розумію, що таке тред Raven`a ::)
Тред - жаргонізм, значення - "гілка, обговорення".
Raven - міфічне створінняанонімна іпостась Ктулху

Відсутній DrIgor

  • Дописувач
  • **
  • дописів: 53
  • Карма: +0/-0
  • Люблю пінгвінчиків
Re: Трикутник Серпінського
« Відповідей #13 : 2008-12-23 17:55:16 »
Вибачаюсь перед читачами цього посту, в деяких попередніх постах я побудував не частину множини Мандельброта, а частину множини Жулія.

Відсутній Fakel._Enterpuer

  • Кореспондент
  • ***
  • дописів: 164
  • Карма: +0/-0
  • Debian Gnu/Linux
Re: Трикутник Серпінського
« Відповідей #14 : 2008-12-24 18:38:51 »
Вибачте за питання, якщо не те ляпнув...
але ... Трикутник Серпінського не те саме що трикутник Паскаля (математика) ?. ::)
LUG irc.id.km.ua