Obsah
1. Logo: použití barev a ovládání kreslicího pera
2. Želví grafika a barvy
3. První demonstrační příklad – vícebarevné obrazce vytvořené s využitím základní barvové palety
4. Demonstrační příklady – práce s větším počtem barev
5. Nastavení stylu vykreslování želví grafiky
6. Čtvrtý demonstrační příklad – zvednutí a spuštění pera při kresbě složitějších obrazců
7. Pátý demonstrační příklad – vytvoření kola s loukotěmi
8. Šestý demonstrační příklad – zobecnění vykreslení kola s loukotěmi
9. Obsah následující části tohoto seriálu
1. Logo: použití barev, stylů želví grafiky, textů, oblouků a výplní
V prvních implementacích programovacího jazyka Logo byly podporovány pouze základní příkazy určené pro práci s želví grafikou. Jednalo se o příkazy provádějící posun želvy dopředu i zpět (procedury forward a back), otáčení želvy okolo její osy (procedury left, right a setheading) a dále o příkazy pro přesun želvy na absolutní souřadnice a smazání grafické plochy (procedury home, setpos, setx, sety, setxy, clearscreen a clean).
Společně s prudkým rozvojem grafických schopností počítačů se repertoár příkazů určených pro práci s grafickou plochou, po které se při kreslení pohybuje želva, rozšiřoval. Dnes si některé tyto příkazy podrobněji popíšeme. Bude se jednat o příkazy pro změnu barvy, kterou želva vykresluje stopu a o příkazy určené pro ovládání stylu vykreslování (především zvedání a spuštění kreslicího pera).
2. Želví grafika a barvy
Většina obrázků, které jsme vytvářeli pomocí příkazů uvedených v předchozích částech tohoto seriálu, byla vykreslena pouze pomocí dvou barev – buď bílou barvou na černém pozadí (implementace Turtle Tracks a USB Logo) nebo naopak černou barvou na bílém pozadí (MSW Logo a většina implementací Loga určených pro operační systémy Microsoft Windows). V každém moderním Logu je však samozřejmě možné vybírat barvu, kterou se mají vytvářené obrazce vykreslovat. Pro tento účel je ve většině dnešních implementací Loga k dispozici procedura setpencolor, kterou je možné volat v několika variantách. V základní variantě je této proceduře předáno pouze jedno nezáporné celé číslo představující index do barvové palety. Jak délka barvové palety (tj. celkový počet vybíratelných barev), tak i její vlastní obsah není standardizován a jednotlivé implementace Loga se v tomto ohledu odlišují.
Například v Turtle Tracks a USB Logu je možné použít pouze barvy s indexy 0 až 7, v MSW Logu existuje v paletě šestnáct barev s indexy 0 až 15 atd. Také samotné barvy uložené v paletě se odlišují. Typicky bývá barva číslo nula nastavená na barvu pozadí (bílá či černá) a barva číslo 7 je inverzní k barvě pozadí (černá či bílá). Ostatní barvy buď odpovídají zbylým šesti barvám RGB spektra (červená, modrá, zelená, fialová, modrozelená a žlutá – tak jako na ZX Spectru) nebo jsou systémově závislé, například na implicitní paletě použité grafické karty. V některých implementacích Loga je možné barvy v paletě měnit pomocí procedury setpalette, které se předá index barvy, která se má změnit a jako druhý parametr je předán seznam trojic hodnot základních barvových složek R, G a B.
Obrázek 1: ZX Spectrum nabízí osm barev, které jsou shodné s některými implementacemi procedury setpaletteVidíme, že práce s barvovou paletou může být problematická a vytvořené programy nepřenositelné na jiné implementace Loga. Pokud například program používá barvy s indexy většími než 7, bude se při spuštění v Turtle Tracks hlásit chyba, kdežto v MSW Logu program poběží bez chyby. Proceduru setpencolor je však také možné volat s jiným typem parametrů – jedná se o seznam (list) obsahující přímo hodnoty základních barvových složek R (červená), G (zelená) a B (modrá). Tyto hodnoty by měly být v rozsahu 0..255, což odpovídá obecným zvyklostem (HTML barvy, grafické knihovny) i schopnostem dnešních grafických karet, monitorů a tiskáren. Jednou z výjimek je UCB Logo, ve kterém je rozsah hodnot barvových složek R, G a B mnohem větší: 0..65536, což odpovídá 655363=281474976710656 barevným odstínům.
3. První demonstrační příklad – vícebarevné obrazce vytvořené s využitím základní barvové palety
V dnešním prvním demonstračním příkladu si ukážeme použití základní barvové palety. Procedura spiral slouží k vykreslení lomené čáry, která při větší hustotě čar připomíná ulitu či spirálu. Z geometrického hlediska se samozřejmě o žádnou spirálu nejedná. Tato procedura je osmkrát volaná z procedury demo, ve které se pomocí příkazu setpencolor nastavuje jedna ze základních osmi barev standardní barvové palety. Když se však podíváme na druhý obrázek, uvidíme pouze sedm „spirál“. Je to z toho důvodu, že první spirála je vykreslena barvou číslo 0, která odpovídá barvě pozadí a obrazec tedy není viditelný. Samotná procedura spirala je vytvořena tak, aby se všech sedm vykreslených spirál pravidelně rozmístilo kolem společného středu.
; "spirála" složená z lomené čáry o 97 segmentech
to spiral :angle
make "side 0
repeat 97 [
forward :side
right :angle
make "side :side + 1
]
end
; vykreslení osmi "spirál" - každá spirála
; je obarvena jednou ze základních osmi barev
to demo
clearscreen
hideturtle
repeat 8 [
; procedura repcount vrací hodnotu čítače smyčky
setpencolor repcount-1
; přesun na začátek dalšího objektu
penup
forward 200
pendown
spiral 88
]
end
; změna velikosti kreslicí plochy - tento příkaz
; je platný pouze pro Turtle Tracks
(draw 300 300)
; vykreslení obrazce
demo
Obrázek 2: Sedm různobarevných objektů vykreslených procedurou spiral
4. Demonstrační příklady – práce s větším počtem barev
Druhý způsob použití procedury setpencolor si můžeme ukázat na jednoduchém příkladu, po jehož spuštění dojde k vykreslení dvou barevných pruhů s lineárním přechodem mezi dvojicí barev. Tento příklad je odladěn pro Turtle Tracks, proto jsou barevné složky každého odstínu vypočteny tak, aby ležely v rozsahu 0..255. Další nová procedura, která se v tomto příkladu objevuje, se jmenuje repcount a slouží k získání aktuální hodnoty čítače smyčky. Musíme si pouze dát pozor na to, že se v Logu začíná čítat od jedničky a nikoli od nuly, což znamená, že poslední hodnota čítače odpovídá číslu zapsanému za procedurou repeat a ne číslu o jedničku menšímu:
; Vykreslení dvou barevných pruhů
; Jsou použity příkazy, které nemusí být platné
; ve všech implementacích Loga!
to color_demo
clearscreen
hideturtle
repeat 256 [
; procedura repcount vrací hodnotu čítače smyčky
; vykreslení horního barevného pruhu
setpencolor (list repcount-1 repcount-1 256-repcount)
penup
setpos (list repcount-127 1)
pendown
setpos (list repcount-127 100)
; vykreslení dolního barevného pruhu
setpencolor (list repcount-1 256-repcount repcount-1)
penup
setpos (list repcount-127 -1)
pendown
setpos (list repcount-127 -100)
]
end
; zobrazení kreslicí plochy - tento příkaz
; je platný pouze pro Turtle Tracks
draw
color_demo
Obrázek 3: Grafická plocha Turtle Tracks po spuštění procedury color_demo
Ve třetím demonstračním příkladu je taktéž využita druhá varianta volání procedury setpencolor, při které se této proceduře předává seznam tří hodnot odpovídajících barvovým složkám R, G a B. Příklad je odladěn pro MSW Logo, což mimo jiné znamená, že se hodnoty všech barvových složek nastavují v rozsahu 0..255, celkem je tedy možné vybrat barvu z 224=16777216 dostupných odstínů. Dále je v tomto příkladu ukázáno, jakým způsobem je možné nastavit barvu pozadí. V případě MSW Loga se pro tuto operaci používá procedura setscreencolor, které se opět předává trojice hodnot R, G a B. Vzhledem k tomu, že jsou použity pouze konstantní hodnoty, je možné celou trojici zapsat do hranatých závorek (což je konstruktor statického seznamu) a není zapotřebí volat proceduru list (to je de facto konstruktor dynamického seznamu):
; Procedura pro vykreslení barevné spirály odladěná v MSW Logu
; Jsou použity příkazy, které nemusí být platné
; ve všech implementacích Loga!
to color_spiral
; vymazání grafické plochy a skrytí želvy
clearscreen
hideturtle
; nastavení černé barvy pozadí
setscreencolor [0 0 0]
; volba velikosti kroku
make "step 4
; sprirála se skládá ze 64 kružnic
repeat 64 [
; na základě čítače smyčky (1..64) se nastaví
; hodnota barvové složky (0..255)
make "color_val (repcount-1)*4
; nastavení barvy kreslicího pera
setpencolor (list :color_val 255 255-:color_val)
; vykreslení kružnice s proměnlivým poloměrem
repeat 180 [
left 2
forward :step
]
left 10
; další kružnice bude zmenšena
make "step :step-0.05
]
end
Obrázek 4: Třetí demonstrační příklad spuštěný v MSW Logu
Pokud by bylo zapotřebí výše uvedený demonstrační příklad spustit v UCB Logu, je nutné v programu provést několik menších úprav. Zejména se mění název procedury použité pro změnu barvy pozadí grafické plochy – místo setscreencolor se používá procedura setbackground. Druhá změna spočívá v tom, že se v této implementaci Loga zvětšuje povolený rozsah hodnot barvových složek: místo hodnot z rozsahu 0..255 se používá rozsah 0..65535. Kdyby nedošlo k úpravě programu, pravděpodobně by na grafické ploše nebyl obrazec vůbec viditelný, protože nízká hodnota barvových složek by vedla k namíchání barev blízkých černé barvě pozadí.
Z tohoto důvodu se hodnoty všech barvových složek násobí 256. Z rozdílů mezi oběma verzemi tohoto demonstračního příkladu je patrné, že pro dosažení co největší přenositelnosti programů je zapotřebí vytvořit si vlastní procedury pro nastavení barvy kreslení i barvy pozadí a striktně pracovat pouze s těmito novými procedurami.
; Procedura pro vykreslení barevné spirály odladěná v UCB Logu
; Jsou použity příkazy, které nemusí být platné
; ve všech implementacích Loga!
to color_spiral
; vymazání grafické plochy a skrytí želvy
clearscreen
hideturtle
; nastavení černé barvy pozadí
setbackground [0 0 0]
; volba velikosti kroku
make "step 4
; sprirála se skládá ze 64 kružnic
repeat 64 [
; na základě čítače smyčky (1..64) se nastaví
; hodnota barvové složky (0..65536-1)
make "color_val (repcount-1)*4*256
; nastavení barvy kreslicího pera
setpencolor (list :color_val 65536-1 65536-:color_val-1)
; vykreslení kružnice s proměnlivým poloměrem
repeat 180 [
left 2
forward :step
]
left 10
; další kružnice bude zmenšena
make "step :step-0.05
]
end
5. Nastavení stylu vykreslování želví grafiky
V prakticky všech implementacích Loga je možné použít příkazy penup a pendown, resp. jejich zkrácené podoby pu a pd, pro zvednutí a spuštění kreslicího pera, kterým želva na grafické ploše vytváří obrazce. Pokud je pero spuštěno, želva ze sebou při svém pohybu zanechává stopu, v opačném případě se pouze přesunuje bez kreslení. Samotný název příkazů má svoje kořeny ve stejně pojmenovaných operacích, které provádí perové plottery při kreslení nebo při přesunu kreslicího pera. Některé implementace Loga dovolují změnit i styl pera, zejména jeho tloušťku (setpensize), typ vykreslované čáry (setpenpattern) a někdy také dokonce i tvar štětce (viz podobný nástroj známý z kreslicích programů). Tyto příkazy však nejsou standardizovány, proto se ve většině demonstračních příkladů uvedených v této i dalších částech, spokojíme se základním nastavením stylu.
Obrázek 5: Typický perový plotter – zařízení, které je vytlačováno velkoplošnými inkoustovými tiskárnami
6. Čtvrtý demonstrační příklad – zvednutí a spuštění pera při kresbě složitějších obrazců
Pomocí příkazů penup (pu) a pendown (pd) je možné zvednout a spustit pomyslné kreslicí pero, pomocí kterého želva při svém pohybu vykresluje stopu. Na první pohled mohou tyto příkazy vypadat jako nadbytečné, protože stačí nastavit barvu pera shodnou s pozadím kreslicí plochy, aby se želva přesunovala bez kreslení. Ve skutečnosti to však není pravda, protože by se současně překresloval (mazal) i již nakreslený obrazec. Použití příkazů pro zvedání a spouštění kreslicího pera si ukážeme na příkladu, ve kterém se v proceduře carky vykreslí úsečka složená z deseti čárek, z nichž každá má délku deset kroků želvy. Vzdálenost mezi čárkami je taktéž rovna deseti krokům želvy. Posléze se v proceduře carky2 vykreslí mnohoúhelník aproximující kružnici. Opět se jedná o objekt složený z čárek o délce deseti kroků želvy:
; Program ukazující použití příkazů penup a pendown
; procedura, která vykreslí čárkovanou úsečku
; o délce 200 kroků (vždy 10 kroků segment a 10 kroků mezera)
to carky
repeat 10 [
pendown
forward 10
penup
forward 10
]
end
; procedura, která vykreslí čárkovanou kružnici
; (desetikrokový úsečkový segment je následován mezerou
; o délce také deseti kroků)
to carky2
repeat 36 [
pendown
forward 10
left 10
penup
forward 10
]
end
; změna velikosti kreslicí plochy - tento příkaz
; je platný pouze pro Turtle Tracks
(draw 300 300)
; příklad použití procedur carky a carky2
to demo_carky
clearscreen
; nejdříve se vykreslí čárkovaně osy
repeat 4 [
penup
setpos [0 0]
pendown
carky
left 90
]
; nastavení želvy na počátek vykreslení kružnice
penup
home
right 90
forward 110
left 90
pendown
; spuštění procedury pro vykreslení čárkované kružnice
carky2
end
demo_carky
Obrázek 6: Čtvrtý demonstrační příklad spuštěný v Turtle Tracks
7. Pátý demonstrační příklad – vytvoření kola s loukotěmi
Po spuštění pátého demonstračního příkladu se na grafickou plochu Loga vykreslí kolo s 36 loukotěmi. Samotné vytvoření kola sestaveného z jednotlivých segmentů je poměrně jednoduché – v proceduře wheel je v počítané programové smyčce volaná procedura segment, která vytvoří čtverec a následně je želva po svém návratu do původní pozice (tou je střed kola) otočena o 10° doprava, což po dokončení vykreslení všech 36 segmentů vede k vygenerování kruhového útvaru. V proceduře segment je sice skutečně vykreslován čtverec, ovšem tak, že vždy pouze část strany čtverce je vykreslena se spuštěným perem (a tedy viditelná) a zbylou část želva projde s perem zvednutým, tj. bez vykreslování či dalšího ovlivnění již vytvořené části grafického objektu:
; vykreslení kola s 36 loukotěmi
to wheel
repeat 36 [
right 10
segment
]
end
; vykreslení jednoho segmentu - čtverce,
; s viditelnou částí stran
to segment
repeat 4 [
penup
forward 60
pendown
forward 70
left 90
]
end
; změna velikosti kreslicí plochy - tento příkaz
; je platný pouze pro Turtle Tracks
(draw 300 300)
; vykreslení celého obrazce
clearscreen
hideturtle
wheel
Obrázek 7: Pátý demonstrační příklad spuštěný v Turtle Tracks
8. Šestý demonstrační příklad – zobecnění vykreslení kola s loukotěmi
Proceduru pro vykreslení segmentu, která byla použita v pátém demonstračním příkladu, je možné zobecnit tak, aby bylo možné měnit poměr mezi vykreslenou a nevykreslenou částí strany čtverce. Čtverec má celkovou délku strany rovnou 144 krokům želvy a pomocí parametru :d je určeno, jak dlouhá má být neviditelná oblast, tj. oblast, přes kterou želva prochází se zvednutým kreslicím perem. V případě, že se hodnota tohoto parametru postupně zvyšuje (opět je použita procedura repcount pro zjištění aktuální hodnoty čítače smyčky), můžeme na výsledném obrázku vidět, jak se původní čtverec mění v několik krátkých čárek. Příklad je možné dále upravovat, například vynucením zpětného pohybu želvy při zadání záporného kroku, což je patrné z desátého obrázku.
; vykreslení obrace složeného z 36 segmentů
to wheel
repeat 36 [
right 10
segment 2*repcount
]
end
; vykreslení jednoho segmentu - čtverce,
; s viditelnou částí stran
; poměr dělení stran je určen parametrem "d"
to segment :d
repeat 4 [
penup
forward 2*:d
pendown
forward 2*(72-:d)
left 90
]
end
; změna velikosti kreslicí plochy - tento příkaz
; je platný pouze pro Turtle Tracks
(draw 300 300)
; vykreslení celého obrazce
clearscreen
hideturtle
wheel
Obrázek 8: Šestý demonstrační příklad spuštěný v Turtle Tracks
Obrázek 9: Zvýšený počet segmentů na 72 spolu se zmenšením úhlu otočení želvy na 5° po dokončení každého segmentu
Obrázek 10: Obrázek vytvořený tak, že se příkaz forward 2(72-:d) zaměnil za forward 272–6*:d, tj. došlo k couvání želvy
Obrázek 11: Při vykreslení každého čtverce se želva posunula o deset kroků dopředu
Obrázek 12: Obdoba předchozího obrázku
Obrázek 13: Při vykreslení každého čtverce se želva posunula o deset kroků dozadu
9. Obsah následující části tohoto seriálu
V další části seriálu o programovacím jazyce Logo dokončíme poměrně rozsáhlou oblast želví grafiky a nakonec si vysvětlíme i další velmi důležitou součást tohoto jazyka – práci se seznamy a řetězci.