Trzeci wymiar

Starannie przemyślana grafika stanowi bardzo poważny atut Logo. Od niej też rozpoczyna się kurs tego języka w większości podręczników.
Niniejszy artykuł adresowany jest do tych, którzy posiedli już umiejętność posługiwania się Logo w podstawowym zakresie. Treścią jego jest realizacja prostej grafiki trójwymiarowej.

Przypuszczalnie potrafisz zmusić swój komputer do wykonywania mniej lub bardziej wyrafinowanych rysunków na ekranie. Nie znajdziesz więc w tym opracowaniu opisu działania elementarnych procedur grafiki żółwia. Nie będziemy też omawiać takich czynności, jak nagrywanie na taśmę i ładowanie swego programu, albo korzystanie z edytora. Zatrzymamy się tylko na chwilę przy niektórych, rzadziej być może używanych a użytecznych procedurach Logo.

Zajmiemy się (jeżeli, oczywiście, masz na to ochotę) rzutowaniem, zwanym w rysunku technicznym aksonometrią. Program nie jest trudny, ale do jego pełnego zrozumienia potrzebna jest znajomość podstaw geometrii analitycznej przestrzeni dwu- i trójwymiarowej z zakresu szkoły średniej. Jeżeli zdecydujesz się na trochę głębszą analizę tego, co wprowadzisz na swój komputer, zwróć uwagę na jedną z możliwych metod pracy z Logo, sposób tworzenia "narzędzi" do dalszej pracy i możliwość stawiania sobie coraz trudniejszych zadań bez potrzeb pisania nowego programu, a jedynie przez rozszerzenie tego, co już mamy.

We wszystkich tekstach Logo będziemy używali pełnego alfabetu polskiego, abyś nie musiał tracić czasu np. na domyślanie się, że „BLAD" to to samo, co po polsku „BŁĄD". Rzecz jasna, używając Spectrum czy Commodore napiszemy „a" zamiast "ą", "I" zamiast "ł" itd.

Zaczynamy...

...od prostego ćwiczenia, którego efekty mogą być nam w przyszłości przydatne. Nietrudno się domyślić, że nasze rzutowanie będzie miało wiele wspólnego z rysunkiem technicznym. Wiemy, że w rysunku tym używa się różnych rodzajów linii; w szczególności dotyczy to ich grubości. Ma to znaczenie estetyczne i praktyczne — w ten sposób rysunek staje się bardziej czytelny. Ponieważ rozdzielczość ekranu ZX Spectrum jest mimo wszystko dość niewielka, rysunki wykonywane liniami jednakowej grubości mogą nie dawać właściwego wyobrażenia o kształcie rzutowanej bryły. Wobec tego spróbujmy umożliwić programiście (a zatem sobie) kreślenie na ekranie linii o wybranej grubości. Przyda się to również i w Commodore Logo. Przyjrzyjmy się takiej procedurze:

TO NAPRZÓD :odl

FORWARD :odl

END

Wykonuje ona dokładnie to samo, co FORWARD — zatem kreśli linię, którą nazwalibyśmy „cienką" (cieńszej na naszym komputerze już nie da się otrzymać). Chcielibyśmy jednak, aby ta sama procedura NAPRZÓD wytwarzała na nasze życzenie linie grubsze. Możemy oczywiście w takiej sytuacji zmienić jej treść posługując się edytorem. To rozwiązanie nie jest jednak zadowalające, szczególnie gdy np. mamy nakreślić figurę złożoną z 30 odcinków, z których każdy jest innej grubości niż jego poprzednik. Na szczęście zmiany definicji procedury można dokonać przez wykonanie odpowiedniego fragmentu programu.

TO NOWE: procedura

IF NAMEP: procedura [ERA-

SE: procedura]

END

TO L. CIENKA

NOWE „naprzód

DEFINE „naprzód [[:odl] FD

:odl]]

END

To już znamy — napisanie L. CIENKA powoduje, że definiowana jest od nowa procedura NAPRZÓD o postaci już nam znanej. Jak widać, parametrem DEFINE jest lista list, stanowiących kolejne wiersze tworzonej procedury. Za pierwszy wiersz przyjmuje się listę parametrów. W przypadku ich braku lista ta jest pusta, ale musi również zostać zapisana. Jeżeli masz wątpliwości, do czego właściwie służy NOWE i czy nie wystarczyłoby użycie ERASE, napisz:

ER “Franuszek

Spowoduje to pojawienie się komunikatu

ER doesn't like FRANUSZEK as input

Stanowi to odpowiedź na twoje pytanie. Po prostu nie mamy całkowitej pewności, czy w momencie wywołania NOWE „naprzód istnieje już procedura o podanej nazwie. Przejdźmy do linii grubszych.

TO L. GRUBA NOWE "naprzód DEFINE "naprzód [[:odl] [REPEAT 2 [FD odl RT 90 FD 1 RT 90]] [FD :odl]] END

TO L.B. GRUBA NOWE "naprzód

DEFINE "naprzód [odl][FD

:odl RT 90 FD 1 RT 90] [FD :odl RT 90 FD 2 RT 90][FD :odl RT 90 FD 1 LT 90]]

END

Być może taki zapis treści procedury nie jest dla ciebie wystarczająco czytelny. W takim razie napisz:

L.B. GRUBA PO „naprzód

Łatwiej ci będzie w ten sposób zrozumieć, w jaki sposób otrzymujemy linię podwójnej (L. GRUBA) i potrójnej (L.B. GRUBA) grubości. Ważne jest, aby po wykonaniu NAPRZÓD żółw zawsze znajdował się w tej samej pozycji, co po wykonaniu FORWARD, a nie np. o 1 krok w lewo. Zależy nam przecież, aby można było używać tych dwóch procedur zamiennie.

Obejrzyjmy teraz efekt naszej pracy. Napisz:

CS L. GRUBA NAPRZÓD 70

a potem np.

HOME LT 45 NAPRZÓD 100

Przekonasz się, że NAPRZÓD nie działa dokładnie tak, jak byśmy chcieli: linia się w pewnym miejscu rozdwaja. Jest to związane z rozdzielczością ekranu, wobec czego zadowolimy się tym, co mamy. Oczywiście rysowanie linii pogrubionych trwa znacznie dłużej niż linii zwykłych. Pewne zwiększenie tempa można uzyskać przez uprzednie ukrycie żółwia — HT.

Na tym kończymy wstęp.

Przypomnijmy, sobie nasze szkolne wiadomości o rzutach aksonometrycznych. Poniższy rysunek przedstawia najczęściej spotykane rodzaje tych rzutów. Wykonując rzut aksonometrycz-ny pewnego przedmiotu postępujemy według kilku zasad:

— umieszczamy przedmiot w przestrzeni tak, aby możliwie największa liczba krawędzi i ścian była równoległa do osi układu współrzędnych.

— jeżeli krawędź przedmiotu jest w rzeczywistości równoległy do którejś z osi układu, to długość jej rzutu jest równa długości rzeczywistej tej krawędzi przemnożonej przez odpowiednią po-działkę, określoną dla danej osi.

— jeżeli krawędź przedmiotu jest w rzeczywistości równoległa do którejś z osi układu, to jej rzut jest równoległy do rzutu odpowiedniej osi. Jest to zawężenie pewnej ogólnej zasady, dotyczącej rzutów równoległych.

Inaczej mówiąc, w przestrzeni trójwymiarowej wyróżniamy trzy wzajemnie prostopadłe kierunki, odpowiadające osiom układu współrzędnych. Do jednoznacznego określenia rzutu aksono-metrycznego wystarczy nam sześć wartości liczbowych: kierunki rzutów osi układu na płaszczyźnie rzutowej oraz podziałki przypisane tym osiom. Zapiszmy to w Logo.

TO OSIE :x :y :z

MAKE “kątx :x

MAKE “kąty :y

MAKE “kątz :z END

TO PODZIAŁKI :x :y :z

MAKE “podzx :x

MAKE “podzy :y

MAKE “podzz :z END

Przy pomocy procedur OSIE i PODZIAŁKI możemy teraz w łatwy sposób przypisać wartości zmiennym „kątx, „kąty, „kątz, „podzx, „podzy, „podzz. Na przykład układ jednomiarowy określimy przez

OSIE 120 0 240 PODZIAŁKI 1 1 1

Parametry procedury OSIE podawać będziemy jako wartości

kątów, jakie tworzą rzuty osi układu z “pionem” ekranu, liczone zgodnie z ruchem wskazówek zegara: tak samo jest w przypadku instrukcji SETH i wygodnie będzie trzymać się jednej konwencji. Oczywiście wartości te podane są w stopniach. Pozostałe dwa znane nam rzuty aksonome-tryczne zdefiniujemy przez

OSIE 135 0 225 PODZIAŁKI 1 0.5 1

OSIE 90 0 225 PODZIAŁKI 1 1 0.5

Zanim zajmiemy się przełożeniem powyższego na język konkretnego rysunku, napiszmy jedną procedurę RZUT, której parametr stanowić będzie nazwę żądanego rzutu aksonometryczne-go. Chcemy, aby np. napisanie

RZUT “jednomiarowy

spowodowało przypisanie odpowiednich wartości naszym zmiennym.

TO RZUT :nazwa

IF MEMBERP :nazwa

[prostokątny p][OSIE 90 0 225 PODZIAŁKI1 1 .5 CS STOP]

IF MEMBERP :nazwa

[jednowiarowy j][OSIE 120 0 240 PODZIAŁKI 1 1 1 CS STOP]

IF MEMBERP :nazwa [wojskowy w][OSIE 135 0 225 PODZIAŁKI 1

.5 1 CS STOP]

IF MEMBERP nazwa [górny g][OSIE 90 0 180 PODZIAŁKI 1 0 1 CS STOP]

IF MEMBERP :nazwa [boczny b][OSIE 0 0 90 PODZIAŁKI 0 1 1 SC STOP]

IF MEMBERP nazwa [z. przodu z][OSIE 90 0 0 PODZIAŁKI 1 1 0 CS STOP]

IF MAMBERP :nazwa [trzy.czwarte t][OSIE 100 0 235 PODZIAŁKI 1 1 .65 CS STOP]

PRINT [Nie znam takiego

rzutu!] TOPLEVEL

END

Przy pisaniu tej procedury wygodnie jest się posłużyć klawiszem .EXTENDED MODE R. Powoduje to, że jako bieżąca linia zostaje wypisany ostatni wprowadzony wiersz Logo. Rodzaj rzutu możemy teraz ustalić przez podanie jego nazwy, np.

     

RZUT “boczny

albo używając tylko jej jednoliterowego skrótu:

RZUT„b

Wywołanie RZUT „p, RZUT „j, RZUT „w daje nam jeden ze znanych rzutów aksonometrycznych. Rzuty „górny, „boczny, „z. przodu to standartowo używane ruchy prostokątne. Zauważ, że jedną z osi eliminujemy z rysunku przez przypisanie jej podziałki 0. Wreszcie rzut „trzy.czwarte da nam nieco inny widok rysowanej bryły. W przypadku napisania np.

RZUT „lotniczy

na ekranie pojawi się komunikat „Nie znam takiego rzutu!, a program, w którym błędne wywołanie wystąpiło, zostanie przerwany.

Zacznijmy od rysowania odcinków równoległych do osi układu. Teraz przydadzą nam się wartości sześciu wcześniej zadeklarowanych zmiennych.

TO PRAWO :odl SETH :kątx

NAPRZÓD :odl * :podzx END

TO LEWO :odl PRAWO — :odl END

LEWO mogliśmy też zapisać tak:

TO LEWO :odl SETH :kątx +180

NAPRZÓD :odl * :podzx END

Nie czyni to zbyt dużej różnicy, użyj więc wersji, która ci bardziej odpowiada. Postaraj się teraz samodzielnie zdefiniować procedury GÓRA, DÓŁ, PRZÓD, TYŁ. Porównaj wynik swojej pracy z poniższym.

TO GÓRA :odl SETH :kąty

NAPRZÓD :odl * :podzy END

TO DÓŁ :odl GÓRA — :odl END

TO PRZÓD :odl SETH :kątz

NAPRZÓD odl * podzz END

TO TYŁ :odl PRZÓD — :odl END

Mamy już do dyspozycji narzędzia, pozwalające na wykonywanie rysunków. Na początek nakreślimy na ekranie układ współrzędnych, co da nam wstępne wyobrażenie o postaci przyszłych rzutów. Przedtem jednak napiszemy krótką procedurę, przydatną w każdej grafice żółwia, powodującą podniesienie “pióra” i opuszczenie go po wykonaniu pewnej sekwencji czynności.

TO HOP :co.zrobić

PENUP

RUN xo.zrobic

PENDOWN

END

Parametrem użytego tu RUN jest lista czynności do wykonania, a zatem tekst Logo ujęty w nawiasy kwadratowe. Przykład zastosowania poniżej.

TO UKŁAD

L.CIENKA HOP [HOME]

PRAWO 200 HOP [HOME]

GÓRA 200 HOP [HOME]

PRZÓD 200 HOP [HOME]

END

Napiszmy teraz np.

RZUT „prostokątny UKŁAD

No, tak: nie dało to pożądanego wyniku, ponieważ ekran znajduje się w trybie WRAP. Żółw po przekroczeniu granicy ekranu pojawia się na jego przeciwległej krawędzi, co psuje efekt trójwymiarowości. Do naszych celów najbardziej przydatny jest tryb WINDOW. Poprawmy nasz rysunek.

WINDOW CS RZUT „p UKŁAD

Jeżeli chcesz, obejrzyj też układ współrzędnych w pozostałych rzutach.

Być może jedną z pierwszych przez ciebie zdefiniowanych procedur Logo była ta rysująca prostokąt. Dokonajmy tego samego w trzech wymiarach. Ponieważ na razie umiemy poruszać żółwia tylko w kierunkach osi układu, nasz prostokąt może leżeć w jednej z płaszczyzn równoległych do xz lub xy. Spróbuj sam napisać procedury PROST.XY PROST .YZ, a dopiero potem ewentualnie popraw je według poniższego wzoru:

TO PROST .XY :x :y

GÓRA :y

PRAWO :x

DÓŁ :y

LEWO :x

END

TO PROST .XZ :x :z

PRZÓD :z

PRAWO :x

TYŁ :z

LEWO :x

END

TO PROST .YZ :y :z

GÓRA :y

PRZÓD :z

DÓŁ :y

TYŁ :z

END

Warto zwrócić uwagę, że treść tych procedur podlega pewnym konwencjom. W przeciwnym wypadku mogłoby się zdarzyć, że napisawszy.

PROST.XY 50 10

nie będziemy wiedzieli, czy rysowany prostokąt ma wysokość 50, a szerokość 10, czy odwrotnie. W tym przypadku zdecydowaliśmy się na podawanie parametrów w porządku alfabetycznym.

Można oczywiście ustalić inną regułę, trzeba jednak się jej trzymać konsekwentnie w całym programie.

Przy okazji warto też poruszyć kwestię tzw. nazw znaczących. Staraliśmy się dotychczas, aby wszystkie występujące w programie nazwy procedur i zmiennych były adekwatne do ich zawartości. Nie było to postępowanie przypadkowe. Oczywiście, z punktu widzenia Logo jest obojętne, czy nazwiesz pewną procedurę NAPRZÓD czy HUHU. HAHA. Ta druga nazwa może się nawet wydać śmieszniejsza, natomiast niesie ze sobą inną niedogodność. Gdy nagrasz cały program na taśmę i powrócisz do niego, powiedzmy, za miesiąc, wiele czasu zajmie ci przypomnienie sobie, co właściwie HUHU. HAHA wykonuje a co HIHI. HOHO? .Należy unikać również dość rozpowszechnionej praktyki nazywania zmiennych „jak leci”, tzn. kolejnymi literami alfabetu, gdy nie są one bezpośrednio związane z treścią programu.

Z naszych prostokątów możemy już składać rysunki trójwymiarowe. Oto prościutki przykład.

RZUT „jednomiarowy

L.CIENKA HT

REPEAT 10 [PROST.XZ 30 50

HOP [GÓRA 3]]

Otrzymujemy taki rysunek: Otwiera się przed tobą pole do własnych doświadczeń. Oto jeszcze jeden przykład figury przestrzennej złożonej z kwadratów...

Następnym etapem pracy będzie rysowanie prostopadłościanu o zadanej długości boków.

TO KOSTKA :x :y :z

PROST .XY :x :y

PROST .XZ :x :z

HOP [PRZÓD :z]

PROST .XY :x:y

HOP [TYŁ :z GÓRA :y]

PROST .XZ :x :z

HOP [DÓŁ :y]

END

Warto poćwiczyć trochę wyobraźnię przestrzenną, analizując działanie tego fragmentu. Interesujące, że nie użyliśmy ani razu PROST.YZ. Ostatnia instrukcja HOP nie ma znaczenia dla samego rysunku. Powoduje za to, że po wykonaniu procedury żółw znajdzie się dokładnie w pozycji wyjściowej. Powiemy, że pozycja żółwia jest niezmiennikiem procedury KOSTKA. Jest to zasada, której warto przestrzegać.

Narysuj teraz kilka prostopadłościanów w różnych rzutach. Gdy to ci się znudzi, napisz

RZUT „t KOSTKA 40 40 40

Na ekranie ukaże się sześcian. Niemniej jednak rzut otrzymany w wyniku

CS OSIE 90 20 200 PODZIAŁ-Kl 1.2 1 .85 KOSTKA 40 40 40

mało ów sześcian przypomina. Wnioskujemy, że przez użycie procedur OSIE i PODZIAŁKI z różnymi parametrami możemy dość dowolnie deformować rzutowane bryły. Zrób kilka doświadczeń tych deformacji. Jeżeli otrzymany rzut odpowiada ci, możesz go dołączyć do procedury RZUT.

Mamy teraz do dyspozycji dość narzędzi, aby popróbować swych sił przy rzutowaniu różnego typu brył prostopadłościen-nych. Na początek możesz spróbować np.

TO PRZYKŁAD

L.CIENKA KOSTKA 30 70 50

HOP [GÓRA 70]

L.B.GRUBA

KOSTKA 30 15 50

HOP [DÓŁ 70 PRAWO 30]

L.GRUBA

KOSTKA 40 45 50

END

Oczywiście proste bryły można składać w coraz bardziej skomplikowane ich układy, aż do utraty czytelności rysunku. Kilka przykładów możesz obejrzeć poniżej.

No, tak — mógłby ktoś powiedzieć — dobrze, ale przecież nie wszystkie krawędzie brył muszą być do siebie prostopadłe. Jak narysować dowolny odcinek w naszym rzucie?

Przyjrzyjmy się poniższemu rysunkowi.

Przedstawia on pewien odcinek w przestrzeni trójwymiarowej. Stanowi on jakby przekątną pewnego prostopadłościanu o bokach, dajmy na to, dx, dy, dz. Krawędzie tego prostopadłościanu potrafimy już przebyć przy pomocy żółwia. Nasuwa się więc następujący algorytm.

TO ODC :dx :dy :dz

MAKE „x XCOR

MAKE „y YCOR

HOP [PRAWO :dx GÓRA :dy PRZÓD :dz] SETPOS SE :x :y

END

Nie jest to jednak dobre rozwiązanie. Po pierwsze wykonujemy kilka niepotrzebnych ruchów żółwiem, po drugie po zakończeniu wykonywania ODC znajduje się on w punkcie wyjścia, a nie. jak chcielibyśmy, na końcu rysowanego odcinka. Lepiej będzie użyć matematyki w celu wyliczenia współrzędnych rzutu tego końca, a następnie „przywołać” żółwia do tego punktu.

TO ODC :dx :dy :dz

MAKE „now.xcor (SUM XCOR :podzx * :dx * SIN :kątx)

podzy * :dy * SIN :kąty :podzz * :dz * SIN: kątz)

MAKE „now.ycor (SUM YCOR :podzx * :dx * COS :kątz

podzy * :dy * COS :kąty :podzz * :dz * COS :kątz

SETH TOWARDS SE :now.xcor :now.ycor

NAPRZÓD

ODLEGŁOŚĆ :now.xcor now.ycor

END

TO ODLEGŁOŚĆ :x :y

MAKE „deltax :x — XCOR

MAKE „deltay :y — YCOR

OUTPUT SORT [:deltax *

:deltax + :deltay * :deltay] END

Zamiast poprzedniego SETPOS użyliśmy sekwencji, która pozwą la na użycie NAPRZÓD a zatem i kreślenie linii grubych. Zauważ, że używając TOWARDS i SETPOS należy napisać

SETPOS SE :x :y

a nie

SETPOS [:x :y]

Sprawdzić działanie ODC możemy np. przez

RZUT „t KOSTKA 60 60 60 ODC 60 60 60

Otrzymamy sześcian i jego przekątną. Zauważymy też, że ODC działa bardzo powoli w porównaniu z np. PRAWO. Spowodowane jest to powolnym obliczaniem funkcji SIN i COS przez ZX Spectrum. Gdyby nie ten fakt, moglibyśmy   zmienić   definicje

PRAWO, GÓRA i PRZÓD

według poniższego wzoru:

TO GÓRA :odl ODC 0 :odl 0

END

Możemy teraz łatwo narysować prostopadłościan np. z przekątnymi ścian. Napisanie jej procedury to ćwiczenie dla ciebie.

Na zakończenie omówimy krótko kilka procedur, które wzbogacą naszą grafikę o ciekawe możliwości.

TO OBRÓCONE :kąt MAKE „katx :kątx + :kąt MAKE „kąty :kąty + :kąt MAKE „kątz :kątz + :kąt END

OBRÓCONE powoduje, iż rysunek (lub jego część) zostaje obrócona o podany kąt.

TO SYMETR.XY MAKE „kątz :kątz t 180 END

PRAWO, GÓRA i PRZÓD według poniższego wzoru:

TO GÓRA :odl

ODC 0 :odl 0

END

Możemy teraz łatwo narysować prostopadłościan np. z przekątnymi ścian. Napisanie jej procedury to ćwiczenie dla ciebie.

Na zakończenie omówimy krótko kilka procedur, które wzbogacą naszą grafikę o ciekawe możliwości.

TO OBRÓCONE :kąt

MAKE „katx :kątx + :kąt

MAKE „kąty :kąty + :kąt

MAKE „kątz :kątz + :kąt END

OBRÓCONE powoduje, iż rysunek (lub jego część) zostaje obrócona o podany kąt.

TO SYMETR.XY

MAKE „kątz :kątz t 180

END

SYMETR.XY daje nam lustrzane odbicie przedmiotu, względem płaszczyzny xy.’Analogicznie działają poniższe procedury:

TO SYMETR.XZ

MAKE „kąty :kąty + 180

END

TO SYMETR.YZ

MAKE „kątx :kątx + 180

END

Wiemy, że złożeniem dwóch symetrii jest obrót. Możemy zatem obejrzeć nasz przedmiot „z drugiej strony’.

TO OD. TYŁU

SYMETR.XY

SYMETR.YZ

END

TO OD.SPODU

SYMETR.XZ

SYMETR.YZ

END

Możemy także nasz rysunek dowolnie powiększyć albo zmniejszyć przez proporcjonalne zwiększenie podziałek na wszystkich osiach.

TO ZBLIŻENIE :krotność PODZIAŁKI :krotnosć * :podzx: krotność *: podzy: krotność * podzz END

Daje to nam możliwość powiększenia dowolnego elementu rysunku. Usprawnimy to przy pomocy dwóch poniższych procedur:

TO WOKÓŁ.PUNKTU :x :y :z MAKE „x.0 (— :x) MAKE

„y« (- :y)

MAKE „z.0 (— :z) END

TC ZERO

HOP [HOME GÓRA :y.0 PRAWO :x.0 PRZÓD :z.0] END

Sposób posługiwania się nimi jest następujący: listę procedur realizujących rysunek poprzedzamy wywołaniem ZERO. Usta-Ie; to niejako początek układu współrzędnych w punkcie, w którym rozpoczyna się rysowanie bryły. Parametrami WOKÓŁ.PUNKTU są współrzędne przestrzeni trójwymiarowej liczone od tego właśnie punktu. Oto prosty przykład.

TO PROSTY.PRZ ZERO

KOSTKA 10 10 10 END

Jeżeli teraz chcemy obejrzeć z bliska jeden z wierzchołków sześcianu, piszemy

RZUT „j ZBLIŻENIE 200 WOKÓŁ.PUNKTU 10 10 10 PROSTY.PRZ

Trzeba pamiętać, że użycie RZUT przywraca standartową sytuację, tzn. usuwa działanie procedur ZBLIŻENIE, OBRÓCONE, OD.SPODU itp.

Zastosowanie otrzymane, w ten sposób grafiki trójwymiarowej zależy już od twojej inwencji. Daje się odczuć brak możliwości „zasłaniania linii”, tzn. pomijania w rysunku linii, które normainie nie są widoczne. Ze względii na elementarny charakter ninieisze go opracowania pominęliśmy rozwiązanie tego problemu. Może też cię niecierpliwić powolność działania Sinclair Logo — nie ma na to jednak rady. Miejrm nadzieję, że otrzymane rzuty interesujących brył zrekompensują ci te niedostatki. Oto przykład rzutu domu i kolejne przybliżenia jego fragmentu — klamki okiennej. Wymyśl coś lepszego!

 

Marcin Waligórski