Kreslení tvaru pomocí objektu
Jestlize nevidíte správne ceská písmena, zvolte potrebné kódování cestiny manuálne.
Zadání:
Vytvorte knihovnu objektu a metod, které umozní vykreslovat na klasický
textový terminál jednoduché obrazce tvary: body, cáry, ctverce a kruznice.
Pozadavky:
- Celkem se bude program skládat ze trí souboru:
- tvary.h hlavickový soubor, který bude v sobe nést deklarace tríd, prototypy metod a inline metody
- tvary.C komplementární soubor k hlavickovému souboru, ponese v sobe rozsáhlejsí metody tríd
- tvarymain.C hlavní soubor s main funkcí, tento bude slouzit hlavne pro Vasi potrebu, k vyzkousení funkcnosti predchozích dvou souboru.
Také se odevzdává, avsak není soucástí hodnocení.
- Tyto tri soubory po odladení ulozte (pouze zdrojové tvary) do adresáre /export/e1/pb161/vás_login/cvic6. Odladte je na pocítaci
aisa.
- Klasický
terminál má rozlisení 80x24, pro jednoduchost a zachování správného
zobrazení (i v terminálech s vetsím rozlisením) budeme pouzívat pouze
plochu 79x23. 80tý znak bude vzdy znak konce rádku, tím zajistíme
korektní vykreslení i pri presmerování standardního výstupu do souboru.
- Knihovna bude umet vykreslovat tyto tvary:
- bod zadán pouze souradnicemi [x, y]
- cára zadána souradnicemi pocátecního a koncového bodu [x1, y1] [x2, y2]
- ctverec zadán levým dolním vrcholem a délkou hrany, je vzdy kolmý k osám souradnic [x, y, d]
- kruznice zadána stredem a polomerem [x, y, r]
- V konstruktorech prosím dodrzte poradí jednotlivých parametru (napr.
cára x-ová 1.bodu, y-ová 1.bodu, x-ová 2.bodu, y-ová 2.bodu)
- Nebereme
v úvahu, ze na terminálu není sírka a výska znaku rovna, takze výsledné
ctverce a kruznice odpovídají opticky spíse obdélníkum a elipsám.
- Vykreslovat tvary nebudeme prímo na terminál. K tomu nám bude slouzit speciální trída, kterou pojmenujeme
plocha . Mela by v sobe obsahovat jako atribut vhodný pametový
prostor, jehoz prvky by reprezentovaly body ( pixely ) obrazovky.
- Pro
zajistení kompatibility Vasich metod s testovacím tvarymain.C souborem,
jsou zde uvedeny prototypy vsech metod, které musíte dodrzet, protoze
jinak nepujde Vase knihovna otestovat. Je vzdy uveden název trídy
(který je také potreba dodrzet), kde se daná metoda vyskytuje a pak
její prototyp:
- class plocha
- void vyprazdni(void); // vymaze vycistí plochu, at bylo nakresleno cokoli
- friend
ostream& operator<<(ostream &, plocha &); //
pretízený operátor výstupu tak, aby bylo mozné pouzít:
cout<<instance_ plochy;
- void otoc(int, int,double); // nepovinná metoda, viz níze, [x-ová, y-ová, st-pocet stupnu]
- class bod
- bod(int, int);
// konstruktor s inicializací [x-ová, y-ová]
- void vykresli(plocha &); // vykreslí bod na plochu predanou odkazem
- void schovej(plocha &); // schová bod z plochy predané odkazem
- class cara
- cara(int, int, int, int);
// konstruktor s inicializací [x1-ová, y1-ová] az [x2-ová, y2-ová]
- void vykresli(plocha &); // vykreslí cáru na plochu predanou odkazem
- void schovej(plocha &); // schová cáru z plochy predané odkazem
- class ctverec
- ctverec(int, int, int);
// konstruktor s inicializací [x-ová, y-ová, d-délka hrany]
- void vykresli(plocha &); // vykreslí ctverec na plochu predanou odkazem
- void schovej(plocha &); // schová ctverec z plochy predané odkazem
- class kruznice
- kruznice(int, int, int); // konstruktor s inicializací [x-ová, y-ová, r-polomer]
- void vykresli(plocha &); // vykreslí kruznici na plochu predanou odkazem
- void schovej(plocha &); // schová kruznici z plochy predané odkazem
- Po vytvorení objektu nedochází rovnou k jejich vykreslování do plochy, ale az explicitne po zavolání metody
vykresli() na daném objektu.
- Pokud dojde k prekrízení tvaru, nesmí metoda schovej()
(zavolaná na jednom z nich) smazat sdílené body ( pixely ). Takový
pixel se smaze az v prípade schování posledního tvaru, který jej
spoluvlastnil .
- Pri vykreslování jednotlivých tvaru do
plochy nedochází jeste k výpisu na výstup (napr. cout). K tomu dojde az
pri pouzití pretízeného operátoru << (napr. cout << instance_plochy;)
- Metody
osetrete tak, aby umoznily vykreslovat tvary i mimo rozsah plochy tedy
mimo 79x23, vcetne záporných hodnot. Pokud takový tvar svojí cástí
spadá do korektních souradnic, je tato cást viditelná, zbytek informací
se zahazuje. (napr. bude videt pouze cást kruznice nebo jen polovina
cáry apod.)
- Záporné hodnoty v prípade délky hrany ctverce a polomeru kruznice prevedte na kladná císla.
- V prípade, ze máte zájem obdrzet +3 body navíc, muzete zpracovat následující metodu trídy
plocha :
- void otoc(int, int, double); první dva parametry urcují stred
otácení [x, y] a poslední pocet stupnu.
- Metoda otocí celý obraz o daný pocet stupnu s tím, ze se zachovává rozlisení 79x23, takze dochází ke ztrátám informací.
- Otocení
probíhá pouze na bitovém obraze, tedy neprepocítávají se zádné
parametry tvaru. Prepocet obrazu probíhá pouze v instanci trídy plocha
, na které byla metoda zavolána, tj. nad daty onoho vhodného pametového
prostoru .
- Vzhledem k tomu,
ze tato metoda pracuje nad daty, která uz byla vykreslena a nedochází k
novému prekreslení tvaru, získává výsledný obraz jisté defekty, které
lze samozrejme pricíst tomuto zpusobu resení (napr. po otocení obrazu
budou nekteré cáry díravé apod.)
- Po zavolání metody otoc() není (vetsinou) mozné vykreslené objekty korektne schovat metodou
schovej(). Pouzijte ji tedy az nakonec .
- Jedná se o nepovinnou cást zadání.
- Pokud budete chtít tuto dobrovolnou cást zpracovat, pridejte do Vaseho hlavickového souboru tvary.h :
#define ROTATE. Bude to slouzit pro podmínený preklad pri kontrole odevzdaných úkolu k rozlisení základního nebo rozsíreného zadání
- Hlavickový soubor nezapomente osetrit proti vícenásobnému vlození.
Poznámky:
- Dalsí podrobnosti vám napoví, spustíte-li si (na aise) vzorové resení ze souboru
/home/jkucera/pb161/cvic6/tvarymain nebo z téhoz adresáre
tvary2main. Zdrojový soubor tvary.C má 182 rádku (6192
znaku), hlavickový soubor tvary.h 161 rádku (4839 znaku),
testovací program
tvarymain.C 281 rádku (8577 znaku); soubory vsak pro Vás
nejsou k dispozici.
- Pro vyzkousení kompatibility Vasí knihovny doporucuji zkusit preklad Vasich souboru
tvary.C a tvary.h s následující main souborem, který je Vám k dispozici ve svém zdrojovém tvaru:
/home/jkucera/pb161/cvic6/tvary2main.C
- Vhodný pametový prostor muze být napr. dvoudimenzionální pole;
- Vzhledem
k v soucasné dobe probrané látce z objektového programování není
pouzito zádného dedení ci virtuální metody. Vsechny objekty jsou
vytváreny staticky. Tedy i ve Vasem testovacím souboru ( tvarymain.C )
muzete vsechny objekty vytváret bez pouzití operátoru new a dalsích.
(Ve vzorovém resení je techto technik pouzito ke zlepsení moznosti
vyzkouset onu knihovnu , ale soubory tvary.C a tvary.h jsou jich prosty)
- Pokud
budete potrebovat z reálných císel získat císla celá, pouzívejte
zaokrouhlování, ne orezání desetinné cásti (napr. 1.4 -> 1 , ale 1.5
->2)
- Pokud budete vykreslovat kruznici cyklem, nemusíte
vymýslet nejaké slozité mechanizmy pro inkrementaci. Pouzijte
inkrementaci napr. po 360/(2*obvod_kruznice) nebo proste inkrementaci
po jednom stupni. Díky zaokrouhlování obcas vzniknou defekty v
zobrazení, ale pro jednoduchost to stací. (Vzorové resení pouzívá
obecne inkrementaci po 360/obvod, ale kreslí jen 90 stupnu, ostatní
kvadranty kopíruje. Speciálne pro kruznici o polomeru 3 provádí
inkrementaci po 360/(obvod-4))
- Pri vykreslování kruznice
opiste krivku kolem stredu ve vzdálenosti polomeru. Ideální cára povede
uprostred bodu ( pixelu ). Napr. kruznice se stredem v S[5, 5] a s
polomerem r = 3, bude mít nejlevejsí bod [2, 5] a nejpravejsí [8, 5].
- Pozor, kruznice o polomeru 0 je jen jeden bod ( pixel ).
- Pro hodnotu PI muzete pouzít následující: const double pi = 3.14159265358979;
- Jako znak pro rozsvícený bod ( pixel ) doporucuji pouzít * hvezdicku.
- Metody vykresli() , schovej() , vyprazdni() ,
operator << , konstruktory a prípadne otoc()
jsou nutné pro komunikaci a tedy i testování knihovny . Samozrejme, ze
trídy mohou obsahovat i jiné dalsí metody, které budete potrebovat, ty
jiz budou slouzit pouze pro Vasi potrebu.
- Príklad pouzití by mohl být napr. následující:
- plocha a;
- bod p(5,5);
- p.vykresli(a);
- cout<<a;
- Tuto úlohu pripravil Jaroslav Bayer