Kategória: Python.
Table of Contents
|
Áttekintés
A teknőcgrafika elsősorban oktatási céllal készült: ideális első találkozás gyerekek számára a programozással. Az alapötlet az, hogy egyszerű utasításokkal ("menj előre", "fordulj balra" stb.) mozgatunk egy teknőcöt, ami közben megrajzolja a bejárt útvonalat. Története 1967-ig, a Logo programozási nyelv megjelenéséig nyúlik vissza. A legismertebb Logo megvalósítás a Comenius Logo, amit a pozsonyi Comenius egyetemen fejlesztette ki. Pythonban a belső turtle könyvtár tartalmazza a megfelelő utasításokat.
Az alábbi oldalak segítettek ennek a leírásnak az elkészítésében:
- https://docs.python.org/3/library/turtle.html: a hivatalos dokumentáció, ami egyébként hivatalos dokumentáció mércével mérve egész jó.
- https://realpython.com/beginners-guide-python-turtle/: szerintem ez a legjobb leírás a témában.
- https://www.geeksforgeeks.org/turtle-programming-python/: jó leírás, és különösen jók a példák.
- https://www.tutorialspoint.com/turtle-programming-in-python: tömör összefoglalás.
Lehetőségek
Első program
A teknőcgrafikát Pythonban többféleképpen használhatjuk. Más leírások esetleg más módszert alkalmaznak; én a következőképpen szoktam használni:
from turtle import * forward(100) done()
Az eredmény:
A kód magyarázata:
- from turtle import *: ezzel töltjük be a teknőcgrafika függvényeit. Természetesen az import turtle is működne, és alapvetően ez utóbbi megközelítést tartom szerencsésebbnek, viszont mivel itt elsősorban oktatási célról beszélünk, ahol nem használunk más könyvtárakat, a kód tömörebbé tétele érdekében hasznosabbnak tartom a fenti kódban megadott megoldást.
- forward(100): a teknőc (ami jelen esetben egy nyíl hegye) előre megy 100 képpontnyit, miközben vonalat húz maga után. A teknőcnek van pozíciója és iránya. A kezdeti pozíció a (0, 0) koordináta, ami az ablak közepén van. A koordináta jobbra és felfelé nő. A méret nem egyértelmű, többfélével találkoztam és többfélét is tapasztaltam; általában pár százas nagyságrendű. A kezdeti irány jobbra mutat. Ha futtatjuk, akkor látható a mozgás is, nemcsak a végeredmény.
- done(): Bizonyos rendszerekből indítva (pl. Visual Studio Code) az ablak egyből bezáródik; ez akadályozza meg a bezáródást. Más rendszerekben (pl. Mu) nem záródik be, így ott nincs szükség erre (de nem is ért, ha ott van).
A későbbiekben az import és a done() sorokat nem adjuk meg, csak a lényegi kódot.
Egyszerű alakzatok
Valósítsuk meg az alábbi programot:
forward(100) right(90) forward(100) right(90) forward(100) right(90) forward(100) right(90)
Az eredmény:
Ebben a programban előre megyünk 100 képpontnyit, utána jobbra fordulunk 90 fokot (right(90)), majd ismét előre megyünk és ismét fordulunk, összesen négyszer végrehajtva a műveletet. Mivel Pythonban vagyunk, használhatjuk erre a for ciklust:
for i in range(4): forward(100) right(90)
Ha még van olyan, aki idáig nem látta a rendszerben rejlő hatalmas oktatási potenciált, az szerintem legkésőbb ezen a ponton meglátja.
Minimális változtatással tudunk további eredményeket elérni:
for i in range(6): forward(70) right(60)
Eredmény:
Sőt, általánosíthatjuk is, bevezetve ezzel a függvények fogalmát:
def n_szog(n): for i in range(n): forward(360 / n) right(360 / n) n_szog(8)
Nyolcszöget kirajzolva az eredmény:
Minimális módosítással betiltott önkényuralmi jelképekhez hasonló ábrákat is készíthetünk:
for i in range(5): forward(100) right(144)
A spirál rajzolásakor a változók fogalmával is megismerkedhetünk:
méret = 5 for _ in range(28): forward(méret) left(90) méret += 5
Rajzolásnál fel is tudjuk emelni a "tollat"; ekkor mozgás közben nem rajzol:
for i in range(4): down() forward(20) up() forward(20)
Talán ebből már jól láthatóak a teknőcgrafika lehetőségei: egyrészt látványos ábrák készítése pár sorból, másrészt a programozási fogalmak bevezetése.
Kör
Kört a circle() függvénnyel tudunk rajzolni:
circle(50)
Ez egy 50 képpontnyi sugarú kört rajzol az aktuális pontból kiindulva, az aktuális irányban, az óramutató járásával ellenkező irányban.
Ha a sugár negatív, akkor óramutató járásával megegyező irányban halad. Második, opcionális paraméterként megadhatunk egy fokokban kifejezett szöget, melynek alapértelmezett értéke 360, azaz egy teljes kör. Háromnegyed környi körívet az alábbi módon rajzolhatunk:
circle(-50, 270) }
Kitöltött kört, azaz nagy méretű pontot rajzolhatunk a dot() függvény segítségével:
dot(50)
A módszer nem konzekvens, ugyanis a kiindulás a kitöltött kör középpontja, paraméterként pedig az átmérőt kell megadni, nem a sugarat.
Paraméterek
A fenti példákban egy fekete nyíl mozgott, amely egy képpont vastagságnyi fekete vonalat húzott. További lehetőségek:
title('Négyzet') shape('turtle') pensize(5) pencolor('red') speed(5) for i in range(4): forward(100) right(90)
Magyarázat:
- title('Négyzet'): az ablak címét változtatja meg az alapértelmezettről.
- shape('turtle'): a teknőc alakját változtatja meg valóban teknőcre.
- pensize(5): a vonal vastagsága 5 képpont 1 helyett.
- pencolor('red'): a vonal színe piros lesz.
- speed(5): a teknőc sebességét lehet ezzel beállítani; minél nagyobb a szám, annál gyorsabb. A maximális sebességet még a 0 paraméterrel is beállíthatjuk.
Kitöltés
Alakzatokat kitölteni a begin_fill() és end_fill() hívásokkal lehet. A fillcolor(…) hívással adhatjuk meg a kitöltés színét. Példa:
pensize(5) pencolor('blue') fillcolor('orange') begin_fill() for i in range(4): forward(100) right(90) end_fill()
Az end_fill() hatására a teknőc ugyanabba a pozícióba ugrik, ahol volt a begin_fill() híváskor. Célszerű úgy megvalósítani a mozgást, hogy eleve ott fejezze be.
Koordináták
A goto(x, y) hatására a megadott koordinátára ugrik a teknőc. Ha a toll le van helyezve, akkor ebben az esetben is rajzol.
Az alábbi példában 4 koordinátára ugrik, és ott "pecsétel" egyet-egyet a stamp() hívás segítségével:
shape('turtle') shapesize(5, 5, 5) up() goto(100, 100) stamp() goto(100, -100) stamp() goto(-100, -100) stamp() goto(-100, 100) stamp()
A shapesize() hívással magának a teknőcnek a méreteit lehet átállítani (szélesség, magasság, körvonal).
Példák
Az alábbiakban néhány pár soros példát láthatunk, ami látványos eredményt ad.
Nap
fillcolor('orange') begin_fill() for i in range(36): forward(200) left(170) end_fill()
Rozetta
for i in range(10): for j in range(10): forward(20) left(36) left(36)
Körök
for i in range(36): right(10) circle(50)
Sakktábla
hideturtle() begin_fill() for i in range(34): forward(160 if i % 2 == (0 if i <= 16 else 1) else 20) left(90 if (i + (0 if i < 16 else 1 if i > 16 else 2)) // 2 % 2 == 0 else -90) end_fill()
Ez a kód talán kevésbé érthető. Én készítettem úgy, hogy először szinte egyesével rajzolta ki a vonalakat, majd egyszerűsítettem le egyetlen ciklussá.
Benzol
színek = ['red', 'purple', 'blue', 'green', 'orange', 'yellow'] bgcolor('black') for i in range(360): pencolor(színek[i % 6]) width(i // 100 + 1) forward(i) left(59)