Strona główna » Poradniki » Logomocja » LOGIA » Logia 1994/95 - Etap I
 

Logia 1994/95 - Etap I

· Etap I · Etap II · Etap III ·
iOryginalna treść zadań jest dostępna pod oficjalnym adresem konkursu LOGIA

Zadanie 1

Napisz procedurę - o nazwie POSADZKA - tworzącą wzór posadzki przedstawiony na rysunku. Widoczny na nim prostokąt jest częścią rysunku, a nie brzegiem ekranu.

Obrazek 1 do zadania 1

Zadanie warto rozbić na dwa pomniejsze. Napiszemy funkcję pomocniczą, która będzie rysowała kwadrat z wypustkami. Druga funkcja, która będzie nadrzędna, narysuje prostokąt i odpowiednio wywoła funkcję pomocniczą, aby narysować wzór na prostokącie. Na początek napiszemy funkcją pomocniczą. W tym celu przeanalizujmy najpierw bok kwadratu:

Obrazek 2 do zadania 1

Bok został podzielony na 3 części. Wypustka to trójkąt prostokątny, równoramienny. Jeśli przyjmiemy bok wypustki jako b to , a z przekształceń wynika, że . Teraz powtarzając ten fragment cztery razy uzyskamy pojedynczy wzór. Realizuje to funkcja pomocnicza POSADZKA_pom:

  1. oto POSADZKA_pom :a
  2.   pod
  3.   pw 45
  4.   np :a/(3*pwk(2))
  5.   lw 45
  6.   opu
  7.   powtórz 4[
  8.     np :a/3
  9.     lw 45
  10.     np :a/(3*pwk(2))
  11.     pw 90
  12.     np :a/(3*pwk(2))
  13.     lw 45
  14.     np :a/3
  15.     pw 90
  16.   ]
  17.   pod
  18.   pw 45
  19.   ws :a/(3*pwk(2))
  20.   lw 45
  21.   opu
  22. już

(1.) Funkcja pomocnicza przyjmuje argument :a. Określa on maksymalną wysokość wzoru. W tym przypadku zakładamy, że do wysokości dodajemy wypustki. Na początek (2. - 6.) przesuwamy pisak. Odcinek, który musimy przebyć wynosi . (7.) Następnie rysujemy cztery razy (8. - 15.) omawiany powyżej bok wielokąta. (17. - 21.) Wracamy z pisakiem do punktu od którego rozpoczęliśmy rysowanie. To zdecydowanie ułatwi wykorzystanie funkcji pomocniczej.

Pozostaje teraz napisać funkcję główną POSADZKA. Będziemy z niej wywoływać funkcję pomocniczą:

  1. oto POSADZKA
  2.   niech "a 100
  3.   pod
  4.   ws :a*1.5
  5.   pw 90
  6.   ws :a*2.5
  7.   lw 90
  8.   opu
  9.   powtórz 2[
  10.     np :a*3
  11.     pw 90
  12.     np :a*5
  13.     pw 90
  14.   ]

(2.) Ustalamy, że wysokość pojedynczego wzoru będzie miała 100 pikseli - pozwoli to na ewentualne dogodne zmiany wielkości obrazka w dowolnym momencie. (3. - 8.) Na początek ustawiamy pisak w lewym dolnym rogu rysunku. Oczywiście przesuwamy podniesiony pisak. (9. - 14.) Rysujemy prostokąt - nasze obramowanie rysunku. Jego wymiary to 5a x 3a. W tym momencie znajdujemy się ponownie w lewym dolnym rogu i możemy rozpocząć rysowanie wzorków:

  1.   powtórz 5[
  2.     powtórz 3[
  3.       opu
  4.       POSADZKA_pom :a-:a/(3*pwk(2))-1
  5.       pod
  6.       np :a
  7.     ]
  8.     ws :a*3
  9.     pw 90
  10.     np :a
  11.     lw 90
  12.   ]
  13.   opu
  14. już

Rysujemy (15.) 5 kolumn po (16.) 3 pojedyncze wzory. (17.) Przed narysowaniem wzoru opuszczamy pisak. Następnie (18.) rysujemy wzór, (19.) podnosimy pisak i (20.) przesuwamy się do przodu o wysokość jednego wzoru :a. Po narysowaniu kolumny będziemy znajdować się na górnej linii, dlatego (22.) cofamy się o trzy wysokości :a, (23.) skręcamy w prawo, idziemy o :a i (24.) skręcamy w lewo. Na koniec (27.) opuszczamy pisak i (28.) kończymy procedurę.

Zadanie 2

Te cztery poniższe rysunki zostały utworzone przez tę samą procedurę ZAKOSY z odpowiednio dobranymi parametrami :n oraz :alfa określającymi złożoność i kąt pomiędzy kolejnymi bokami łamanej tworzącej rysunek.Napisz procedurę ZAKOSY :n :alfa tworzenia takich rysunków.

Poniżej przedstawione są rysunki uzyskane po wywołaniu ZAKOSY 4 135, ZAKOSY 8 144, ZAKOSY 5 120 oraz ZAKOSY 7 144.

Obrazek 1 do zadania 2

Z treści zadania wiemy, że :n mówi nam, że :n razy rysujemy :n odcinków za każdym razem skręcając o kąt :alfa. Jednak takie rozwiązanie nie daje odpowiednich rysunków. W każdym wywołaniu ustalamy na początek długość na :a. Następnie po narysowaniu odcinka mnożymy :a przez 0.7. Innymi słowy za każdym razem zmniejszamy odcinek o 30%. W ten sposób nasz rysunek zaczyna przypominać podane przykłady. Kod jest krótki, ale może namieszać w głowie:

  1. oto ZAKOSY :n :alfa
  2.   powtórz :n[
  3.     niech "a 200
  4.     powtórz :n[
  5.       np :a
  6.       niech "a :a*0.7
  7.       pw :alfa
  8.     ]
  9.   ]
  10. już

Zadanie 3

To jest rysunek hibernakusa. Hibernakus jest drzewem, które składa się z pnia i wyrastających z pnia 3 lub 5 gałęzi. Każda gałąź składa się z konara i wyrastających z konara 3 lub 5 kwiatów. Każdy kwiat składa się z łodygi i wyrastających z niej 3 lub 5 igieł.

  • Konar środkowej gałęzi ma zawsze taki sam kierunek jak pień drzewa, a konary sąsiednich gałęzi tworzą kąt . Długości konarów są równe połowie długości pnia.
  • Łodyga środkowego kwiatu na gałęzi ma ten sam kierunek co konar, a łodygi sąsiednich kwiatów tworzą kąt . Długości łodyg są równe połowie długości konarów.
  • Środkowa igła każdego kwiatu ma ten sam kierunek co łodyga, a sąsiednie igły tworzą kąt . Długości igieł są równe połowie długości łodygi.
  • Napisz procedurę o nazwie HIBERNAKUS (bez parametrów) rysującą na ekranie losowo utworzony kształt hibernakusa. Rysunek powinien być możliwie duży, ale musi mieścić się na ekranie.
Obrazek 1 do zadania 3

Jest to rozwiązanie do którego przyda się znajomość rekurencji. Napiszemy na początek funkcję pomocniczą, która będzie losowała na ile gałęzi lub igieł rozdziela się dany konar. Narysuje je, a na ich końcach wywoła siebie samą, aby narysować kolejne gałęzie:

  1. oto HIBERNAKUS_pom :a :n
  2.   jeśli (:n>0)[
  3.     np :a
  4.     niech "g 3+2*(losowa 2)
  5.     lw 60*((:g-1)/2)
  6.     powtórz (:g)[
  7.       HIBERNAKUS_pom :a/2 :n-1
  8.       pw 60
  9.     ]
  10.     lw 60*((:g-1)/2+1)
  11.     ws :a
  12.   ]
  13. już

(1.) Nasz funkcja przyjmuje dwa parametry: :a - jakiej długości będą teraz gałęzie oraz :n - określi nam ile jeszcze razy funkcja ma siebie wywołać. (2.) Rysujemy kolejne gałęzie pod warunkiem, że parametr :n > 0. Inaczej przerywamy działania rekurencji. (3.) Najpierw rysujemy gałąź, a następnie (4.) losujemy ile podgałęzi (lub igieł) trzeba narysować. Za każdym razem jest to 3 lub 5, więc do trzech dodajemy wynik losowania ze zbioru {0, 1} pomnożonego przez 2. Wynik przechowujemy w zmiennej :g. (5.) W zależności od parametru :g odpowiednio przesuwamy kierunek rysowania w lewo. O ile wyliczamy ze wzoru . Kolejny krok to (6.) narysowanie :g odnóży. (7.) Kolejna część Hibernakusa jest dwa razy mniejsza. Zmniejszamy też parametr :n ze względu na wykonanie iteracji. (8.) Po każdym narysowaniu obracamy się w prawo o \(60^\circ\). Na koniec (10.) obracamy odpowiednio w lewo i (11.) cofamy się o :a. W ten sposób mamy pewność, że skończyliśmy funkcję tam gdzie ją zaczęliśmy.

Teraz musimy napisać bezparametrową funkcję nadrzędną, która wywoła funkcję pomocniczą:

  1. oto HIBERNAKUS
  2.   niech "a 200
  3.   ws :a
  4.   HIBERNAKUS_pom :a 4
  5. już

(1.) W celu uproszczenia zmiany rozmiaru drzewka deklarujemy zmienną pomocniczą :a. Zakładamy, że konar ma długość 200. (2.) Przesuwamy się do tyłu o :a. W ten sposób nasz obrazek znajdzie po środku ekranu. (3.) Wywołujemy funkcją HIBERNAKUS_pom z odpowiednimi parametrami.

Zadanie 4

Ułóż procedurę KWADRATY, która (wywołując odpowiednie procedury pomocnicze) tworzy na środku ekranu możliwie duży rysunek przedstawiony poniżej.

Obrazek 1 do zadania 4

Pracę nad procedurą rozpocznijmy od napisania funkcji pomocniczej, która narysuje kwadrat z czarnym kwadratem w środku:

  1. oto KWADRATY_pom :a
  2.   powtórz 4[
  3.     np :a
  4.     pw 90
  5.   ]
  6.   np :a/2
  7.   pw 45
  8.   wielokąt[
  9.     ukm "czarny
  10.     powtórz 4[
  11.       np (:a*pwk(2)/4)
  12.       pw 90
  13.     ]
  14.   ]
  15.   lw 45
  16.   ws :a/2
  17. już

(1.) Funkcja pomocnicza przyjmuje parametr :a. Określa on jak duży ma być kwadrat. (2. - 5.) Rysujemy kontu większego kwadratu. Drugą część polega na narysowaniu kwadratu wewnątrz. Bok czarnego kwadratu to i zaczyna się w połowie boku pustego kwadratu. Rysowanie zaczynamy od (6., 7.) przesunięcia pisaka na bok kwadratu. (8.) Korzystamy z funkcji wielokąt, która zamaluje na (9.) wybrany kolor obrysowany obszar. (9. - 12.) Obrysowujemy wewnętrzny kwadrat. Na koniec (14., 15.) wracamy tam gdzie zaczęliśmy procedurę.

Główna funkcja KWADRATY wygląda tak:

  1. oto KWADRATY
  2.   niech "h 60
  3.   ws :h*2
  4.   pw 90
  5.   ws :h*2
  6.   lw 90
  7.   KWADRATY_pom :h*4
  8.   ws :h*2
  9.   pw 90
  10.   ws :h*2
  11.   lw 90
  12.   powtórz 4[
  13.     powtórz 6[
  14.       powtórz 2[
  15.         KWADRATY_pom :h
  16.         pw 90
  17.         np :h
  18.         lw 90
  19.       ]
  20.       pw 90
  21.       ws :h*2
  22.       lw 90
  23.       np :h
  24.     ]
  25.     np :h*2
  26.     pw 90
  27.   ]
  28. już

(2.) Na początek ustalamy wielkość pojedynczego kwadratu i zapisujemy w zmiennej :h. Następnie (3. - 6.) przesuwamy się odpowiednio, aby (7.) narysować środkowy wzór o boku równym 4:h. Po narysowaniu przechodzimy do rysowanie małych wzorów. (8. - 11.) Przesuwamy się w lewy dolny róg obrazka. (12.) Będziemy rysować 4 razy sektor po (13.) 6 wierszy, a w każdym wierszu po (14.) 2 wzory. Po (15.) narysowaniu kwadratu zawsze (16. - 18.) przesuwamy pisak w prawo o długość wzoru :h. (19.) Po zakończeniu rysowania wiersza (20. - 23.) wracamy tam gdzie zaczęliśmy go rysować. Pomiędzy rysowaniem każdego sektora przesuwamy się o 2:h i obracamy o .