32 Graafika ja funktsioon

Kilpkonn õpib funktsioone

Varasemates osades oleme tähtsamate programmeerimise konstruktsioonidega (nt valikulause ja tsükliga) tutvumisel abiks võtnud kilpkonna, et saada parem visuaalne ettekujutus. Kilpkonnagraafikas on meil läbivaks teemaks olnud ruudu joonistamine, teeme seda ka funktsioone kasutades.

Viimati kasutasime ruudu joonistamisel tsüklit:

from turtle import *
 
i = 0
while i < 4:               # Kilpkonn joonistab tsükli abil ruudu. Tsükli keha läbitakse neli korda.
    forward(100)
    left(90)
    i = i + 1              # Muutujat i suurendatakse ühe võrra
 
exitonclick()

Ruudu joonistamiseks võime defineerida funktsiooni, näiteks nimega ruut. Loome selle esialgu ilma argumentideta:

Näiteprogramm. Ruut III

from turtle import *
 
def ruut():                # Defineerime funktsiooni nimega ruut
    i = 0
    while (i < 4):
        forward(100)
        left(90)
        i = i + 1
 
ruut()                     # Kutsume funktsiooni ruut välja. Kilpkonn joonistab ruudu küljega 100 pikslit
right(45)                  # Pöörame paremale 45°
ruut()                     # Kutsume uuesti funktsiooni ruut välja
 
exitonclick()

Selle näiteprogrammi puhul joonistab kilpkonn alati ruudu, mille külje pikkus on 100 pikslit. Selleks, et me saaksime muuta ruudu külje pikkust vastavalt soovile, lisame funktsioonile ruut argumendi:

Näiteprogramm. Ruut IV

from turtle import *
 
def ruut(külg):            # Defineerime funktsiooni nimega ruut, mille argumendiks on ruudu külje pikkus
    i = 0
    while (i < 4):
        forward(külg)      # Siin kasutatakse argumenti
        left(90)
        i = i + 1
 
ruut(50)                   # Kilpkonn joonistab ruudu küljega 50 pikslit
ruut(75)                   # Kilpkonn joonistab ruudu küljega 75 pikslit
 
exitonclick()

 

Nüüd saab seda funktsiooni rakendades joonistada erineva suurusega ruute. Näiteks ruut(50) korral on argumendi väärtuseks 50 ja ruudu külje pikkuseks tuleb 50. Kui argumendiks on 75 (ruut(75)), siis tuleb külje pikkuseks 75.

Värvimine

Eelmine kord, kui kilpkonna käsitlesime, olid vaatluse all ka värvimise võimalused. Neid on tegelikult veelgi. Näiteks muudetakse pildi taustavärvi käsuga bgcolor("värvi_nimetus").

Olgu meil ülesandeks kirjutada programm, mis joonistab rohelise servaga punase ringi, punase servaga rohelise ruudu ning värvib ülejäänud tausta helesiniseks. Selleks, et ruutu ei joonistataks ringi peale, kasutame käske:

  • up() – tõsta pliiats üles;
  • down() – langeta pliiats vastu “paberit”.

Kilpkonn muudab pliiatsi värvi ja täitevärvi vastavalt käskudega:

  • pencolor("värvi_nimetus") – muuda pliiatsi värvi;
  • fillcolor("värvi_nimetus") – muuda täitevärvi.

Näiteprogramm. Ring ja ruut

from turtle import *
 
def ruut(n):               # Defineerime funktsiooni ruudu joonistamiseks
    i = 0
    while (i < 4):
        fd(n)
        lt(90)
        i = i + 1
 
pencolor("#32CD32")        # Kilpkonn muudab pliiatsi värvi laimiroheliseks
fillcolor("red")           # Kilpkonn muudab täitevärvi punaseks
begin_fill()               # Kilpkonn alustab ringi värvimist
circle(100)                # Kilpkonn joonistab ringi raadiusega 100 pikslit
end_fill()                 # Kilpkonn lõpetab ringi värvimise
 
up()                       # Pliiats üles
fd(300)                    # Kilpkonn liigub edasi 300 pikslit
lt(90)                     # Kilpkonn pöörab 90° vasakule
fd(50)
down()                     # Pliiats alla
 
pencolor("red")            # Kilpkonn muudab pliiatsi värvi punaseks
fillcolor("#32CD32")       # Kilpkonn muudab täitevärvi laimiroheliseks
begin_fill()
ruut(100)                  # Kilpkonn joonistab ruudu küljega 100 pikslit
end_fill()
 
bgcolor("pale turquoise")  # Muudame taustavärvi helesiniseks
 
exitonclick()

Hulknurkade joonistamine

Eelnevalt oleme vaadanud programme, mis joonistavad kilpkonnaga ruute või ringe. Kui me tahame, et kilpkonn oskaks luua ka teisi kujundeid, näiteks korrapäraseid hulknurki, siis defineerime selleks vastava funktsiooni.

Kirjutame alamprogrammi hulknurk(n), mis joonistaks soovitud nurkade arvuga hulknurga. Selles funktsioonis on argumendiks n hulknurga nurkade arv. Näiteks viisnurga joonistamiseks anname argumendi n väärtuseks 5 (hulknurk(5)). Selleks, et leida, mitme kraadi võrra kilpkonn pöörama peab, kasutame korrapärase hulknurga sisenurga suuruse leidmiseks valemit (n – 2) * 180 / n, kus n on nurkade arv. Seejärel lahutame saadud väärtuse sirgnurgast (180°). Kui valemit lihtsustada, siis saame 360 / n.

from turtle import *
def hulknurk(n):    
    i = 0
    nurk = 360 / n         # Arvutatakse kilpkonna pööramise nurga suurus
    while (i < n):
        forward(100)
        left(nurk)
        i = i + 1
 
hulknurk(5)
exitonclick()

Täiendame programmi, andes argumendiks ka külje pikkuse. Siis on hulknurga funktsiooni argumentideks nurkade arv ja külje pikkus: hulknurk(n, külg). Näiteks kuusnurga joonistamiseks, mille külg on 150 pikslit, kirjutame hulknurk(6, 150).

Näiteprogramm. Hulknurk

from turtle import *
 
# Defineerime funktsiooni nimega hulknurk. Argumendid on nurkade arv ja külje pikkus
def hulknurk(n, külg):    
    i = 0
    nurk = 360 / n         # Arvutatakse kilpkonna pööramise nurga suurus
    while (i < n):
        forward(külg)
        left(nurk)
        i = i + 1
 
fillcolor("green")
begin_fill()
hulknurk(6, 150)           # Kilpkonn joonistab rohelise korrapärase kuusnurga küljega 150 pikslit
end_fill()
 
fillcolor("red")
begin_fill()
hulknurk(7, 50)            # Kilpkonn joonistab punase korrapärase seitsenurga küljega 50 pikslit
end_fill()
 
exitonclick()

Naerunäo joonistamine

Kirjutame programmi, mis joonistab naerunäo. Kui me ei soovi joonistada tervet ringjoont, vaid osa sellest, siis saame kasutada käsu circle kahe argumendiga väljakutset circle(r, d). Selles käsus tähistab r ringi raadiust ja d kesknurka kraadides. Näiteks kui soovime joonistada veerand ringjoonest raadiusega 100 pikslit, siis saame kasutada käsku circle(100, 90).

Näiteprogramm. Naerunägu

from turtle import *
 
def silm():                # Defineerime funktsiooni silmade joonistamiseks     
    pencolor("#000000")
    fillcolor("#FFFFFF")
    begin_fill()
    circle(25)
    end_fill()
 
pencolor("#000000")        # Pea
fillcolor("#FFFF00")  
begin_fill()
circle(100)                 
end_fill()
 
up()                              
bk(45)
lt(90)
fd(100)
rt(90)
down()
 
silm()                     # Vasak silm
 
up()                             
fd(90)
down()
 
silm()                     # Parem silm
 
up()                       # Suu
bk(95)
rt(90)
fd(30)
down()
circle(50,180)             # Pool ringjoonest
bgcolor("#AFEEEE")
 
exitonclick()

Tähe joonistamine

Kirjutame programmi, mis joonistab ette antud pikkuse ja värviga tähe. Defineerime kahe argumendiga funktsiooni täht(pikkus, värv). Näiteks kollase tähe joonistamiseks pikkusega 100 pikslit kirjutame täht(100, "yellow").

Näiteprogramm. Täht

from turtle import *
 
# Defineerime funktsiooni täht, mis joonistab valitud värvi ja pikkusega tähe
def täht(pikkus, värv):   
    color(värv)
    begin_fill()                 
    i = 0
    while (i < 5):
        fd(pikkus)
        rt(144)
        i = i + 1
    end_fill()
 
täht(100, "yellow")        # Kilpkonn joonistab kollase tähe pikkusega 100 pikslit
 
exitonclick()

Enesekontrolli ülesanne (päikesevarjutus)

Kirjuta programm, mis joonistab kilpkonna abil täielikku päikesevarjutust imiteeriva pildi. Pildi taust võiks olla musta või tumesinist värvi.

Tulemus võiks olla midagi sellist:

Veel kilpkonna võimalustest

Kilpkonnaga tegutsemiseks on võimalusi veelgi. Lähemalt saab uurida Pythoni turtle mooduli dokumentatsioonist, näiteks kuidas muuta pliiatsi paksust või kilpkonna kuju.

Funktsioonid Tkinteriga

Varasemalt tegelesime graafikaga ka mooduli Tkinter abil. Siingi saame ise funktsioone defineerida. Teeme näiteks programmi, millega saab kuusiku joonistada. Kuused koosnevad täisnurksetest kolmnurkadest. Defineerime kolm funktsiooni.

  • Funktsioon joonista_tase joonistab kuuse ühe taseme – täisnurkse kolmnurga, mis on määratud ülatipu ja selle vastaskülje pikkusega (taseme laius). Argumentideks on ülatipu koordinaadid, laius ja värv.
  • Funktsioon joonista_kuusk joonistab kuuse. Argumentideks on ladva koordinaadid, kuuse laius ja tasemete arv. Kui värvi ei märgita, siis vaikimisi joonistatakse roheline kuusk. Teistvärvi kuuse tegemiseks tuleb värv ette anda, nt joonista_kuusk(200, 50, 40, 4, "red").
  • Funktsioon joonista_mets joonistab argumendina antud arvu kuuski. Iga kuuse asukoht, tasemete arv ja laius on teatud piirides juhuslikud.

Näiteprogramm. Kuusik

from tkinter import *
from random import *
 
def joonista_tase(ülatipp_x, ülatipp_y, laius, värv):
    tahvel.create_polygon(ülatipp_x, ülatipp_y, ülatipp_x + laius/2, ülatipp_y + laius/2, ülatipp_x - laius/2,  ülatipp_y + laius/2, fill=värv, outline=värv)
 
def joonista_kuusk(ladva_x, ladva_y, laius, tasemeid, värv="green"):
    for tase in range(tasemeid):
        joonista_tase(ladva_x, ladva_y + tase * laius/3, laius, värv)
 
def joonista_mets(kuuskede_arv):
    for tase in range(kuuskede_arv):
        joonista_kuusk(randint(1, 600), randint(1, 200), randint(10, 30), randint(3, 5))
 
raam = Tk()
# nimeks Kuusik
raam.title("Kuusik")
# loome tahvli laiusega 600px ja kõrgusega 300 px
tahvel = Canvas(raam, width=600, height=300)
 
joonista_mets(10)
joonista_kuusk(200, 50, 40, 4, "red")
 
# paigutame tahvli raami ja teeme nähtavaks
tahvel.pack()
# siseneme põhitsüklisse
raam.mainloop()

Video (miiniotsija)

Lõpetuseks video miiniotsija mängu tegemisest.

Litsents

Icon for the Creative Commons Attribution 4.0 International License

Programmeerimine on loodud Eno Tõnisson, Tauno Palts, Merilin Säde, Kaarel Tõnisson jt poolt Creative Commons Attribution 4.0 International License litsentsi alusel, kui pole teisiti märgitud.

Jaga seda raamatut