14. Kruhy a cykly

Kreslenie kružnice

Zrejme kreslenie kružnice je len špeciálnym prípadom kreslenia elipsy. Ak pri kreslení elipsy „myslený“ obdĺžnik bude štvorcom (oba rozmery: šírku aj výšku má rovnaké), nakreslí sa kružnica, resp. ak bude vyplnená farbou, tak kruh.

Pripomeňme si, nový príkaz stvorec_nahodne zo 4. časti:

import tkinter
import random

platno = tkinter.Canvas(bg='white')
platno.pack()

def stvorec_nahodne():
    x = random.randint(10, 310)
    y = random.randint(10, 200)
    platno.create_rectangle(x, y, x+50, y+50, fill='indian red')

Keďže tento podprogram kreslí štvorce, výmenou create_rectangle za create_oval dostaneme kruhy. Vytvorme na to podprogram kruh_nahodne:

def kruh_nahodne():
    x = random.randint(10, 310)
    y = random.randint(10, 200)
    platno.create_oval(x, y, x+50, y+50, fill='dodger blue')

Aby sme otestovali oba tieto podprogramy stvorec_nahodne aj kruh_nahodne, zavoláme ich vo for-cykle tak, aby sa striedali:

for i in range(20):
    stvorec_nahodne()
    kruh_nahodne()

Dostávame takýto obrázok:

_images/14_01.png

Vo väčšine prípadov, pri kreslení kružníc, by sa nám hodilo, keby sme mohli vychádzať z toho, že ich vieme nakresliť pomocou daného stredu (x, y) a polomeru r. Ak si uvedomíme, že je to takto jednoduché:

platno.create_oval(x - r, y - r, x + r, y + r)

Zjednoduší sa nám pohľad na mnohé úlohy. Vyriešme takúto úlohu: na náhodné pozície nakreslíme 10 žltých kruhov a do každého z nich postupne zapíšeme číslo od 0 do 9. Zrejme využijeme for-cyklus, v ktorej bude premenná cyklu nadobúdať hodnoty od 0 do 9 a v tele cyklu sa vygenerujú náhodné súradnice x a y a na ne sa nakreslí žltý kruh aj vypíše text:

import tkinter
import random

platno = tkinter.Canvas(bg='white')
platno.pack()

for cislo in range(10):
    x = random.randint(30, 330)
    y = random.randint(30, 220)
    platno.create_oval(x-30, y-30, x+30, y+30, fill='gold')
    platno.create_text(x, y, text=cislo, font='arial 40')

Všimnite si, ža ako parameter text pre vypisovanie textu v create_text sme nastavili premennú cyklu cislo. Po spustení sa zobrazí podobný takýto obrázok:

_images/14_02.png

V ďalšej ukážke nakreslíme takýto obrázok:

_images/14_03.png

Obrázok sa skladá z mesiačika (dva prekrývajúce sa kruhy, jeden žltý a druhý tmavomodrý) a 30 žltých hviezdiček na náhodných pozíciách. Hviezdičky vykresľujeme ako žlté znaky '*':

import tkinter
import random

platno = tkinter.Canvas(bg='navy')
platno.pack()

for i in range(30):
    x = random.randint(10, 370)
    y = random.randint(10, 230)
    platno.create_text(x, y, text='*', fill='yellow', font='courier 15')

x = 150
y = 100
r = 80
platno.create_oval(x-r, y-r, x+r, y+r, fill='yellow', width=0)
x = x + 50
platno.create_oval(x-r, y-r, x+r, y+r, fill='navy', width=0)

For-cyklus o vylepšený range možeme využiť napr. pri kreslení sústredných kružníc (kružnice so spoločným stredom), ktoré najú postupne polomery 5, 10, 15, 20, …, 100:

import tkinter

platno = tkinter.Canvas(bg='white')
platno.pack()

for r in range(5, 101, 5):
    platno.create_oval(150-r, 120-r, 150+r, 120+r)

dostaneme:

_images/14_04.png

Zaujímavý výsledok dostaneme, keď budeme tieto kružnice zafarbovať:

for r in range(5, 101, 5):
    platno.create_oval(150-r, 120-r, 150+r, 120+r, fill='pink')

dostaneme:

_images/14_05.png

Hoci sme zafarbovali všetky kružnice, vidíme len najväčšiu z nich. Tá prekryla všetky menšie. Ak by sme chceli vidieť všetky nakreslené zafarbené kružnice, musíme ich kresliť v opačnom poradí: od vajväčšej po najmenšiu. Teda stačí zmeniť range(...) tak, aby namiesto postupnosti 5, 10, 15, 20, …, 100, sa vygenerovala 100, 95, …, 15, 10, 5. Dá sa to zapísať pomocou záporného kroku:

range(100, 0, -5)

a bude to fungovať správne. My sa naučíme užitočnejší zápis, pomocou ktorého otočíme poradie hodnôt ľubovoľnej postupnosti:

reversed(range(5, 101, 5))

Vďaka tomuto nemusíme rozmýšľať, ako správne zapísať dolnú a hornú hranicu pre záporný krok. Teraz naše riešenie vyzerá takto:

for r in reversed(range(5, 101, 5)):
    platno.create_oval(150-r, 120-r, 150+r, 120+r, fill='pink')

a vidíme:

_images/14_06.png

Úlohy

  1. Napíšte podprogram husenica, ktorá na náhodnú pozíciu nakreslí húseničku, ktorá je zložená z náhodného počtu zelených krúžkov. Dĺžka húseničky je od 3 do 10. Po niekoľkých zavaloniach tohto podprogramu, môžeme dostať, napr.

    _images/14_07.png

  1. Napíšte podrogram auto, ktorá na náhodnú pozíciu nakreslí približne takéto autíčko:

    _images/14_08.png

  1. Napíšte podprogram kruznice10, ktorý na náhodnú pozíciu nakreslí 10 kružníc so spoločným stredom a s polomermi postupne 5, 10, 15, 20, 25, 30, 35, 40, 45, 50. Použite for-cyklus s range(10).

    Bude tento podprogram fungovať aj vtedy, keď im nastavíme nejakú výplň, napr. fill='pink'?

Zhrnutie

čo sme sa naučili:

  • elipsy a kružnice sa kreslia na rovnakom princípe ako sa kreslili obdĺžniky

  • aj elypsy môžeme vyfarbovať, resp. im nastaviť hrúbku a farbu obrysu

  • kružnice so stredom (x, y) a plomerom r sa dobre kreslia pomocou create_oval(x-r, y-r, x+r, y+r)