Hlavní navigace

Knihovna ClanLib (20)

Petr Kavánek

Minule jsme při popisu třídy CL_Font narazili na třídu CL_Rect, což je, jak už bylo řečeno, třída reprezentující obdélník. Dnes si tuto třídu přiblížíme podrobně, protože při programování aplikací ClanLibu vlastních narazíme na potřebu nějakým způsobem reprezentovat obdélník velmi často.

CL_Rect

Třída CL_Rect má čtyři atributy typu int, kterými jsou left, top, right a bottom. Jedná se o souřadnice (levého horního a pravého dolního rohu), kterými je příslušný obdélník zadán:

Z těchto souřadnic již CL_Rect umí dopočítat šířku a výšku, které získáme po řadě metodami:

int get_width();
int get_height();

Rozměry můžeme získat také jako CL_Size pomocí metody:

CL_Size get_size();

Další velmi užitečnou metodou je

bool is_inside(const CL_Point &p);

Tato metoda vrátí true v případě, že zadaný bod je uvnitř tohoto obdélníku, jinak vrátí false. Bod zadáváme jako CL_Point. Chceme-li tedy zjistit, zda je bod (X, Y) součástí obdélníku O, zeptáme se třeba takto (zejména v případě, kdy si tento bod nereprezentujeme jako CL_Point):

if (O.is_inside(CL_Point(X, Y))) { ... }

Můžeme také zjistit, zda je jiný obdélník uvnitř našeho obdélníku (true) pomocí

bool is_overlapped(const CL_Rect &r);

Jinou metodou, která se může hodit, je

CL_Rect get_rot_bounds(const CL_Point &hotspot, float angle); 

Tato metoda vrací obdélník opsaný obdélníku vzniklému otočením našeho obdélníku okolo bodu hotspot o úhlel angle (ve stupních). Samozřejmě opsaným obdélníkem je myšlen takový opsaný obdélník, který má hrany rovnoběžné se souřadnými osami, viz obrázek:

Pokud chceme změnit rozměry obdélníku, avšak zachovat levý horní roh, můžeme použít metodu

void set_size(const CL_Size &size);

Ke zjištění průniku našeho obdélníku s jiným obdélníkem můžeme použít metodu

CL_Rect calc_union(const CL_Rect &rect);

Ta vrátí příslušný obdélník odpovídající hledanému průniku. V případě, že se obdélníky neprotínají, bude mít výsledek buď left větší než right, nebo top větší než bottom. Metoda callc_union totiž přesněji řečeno vrací obdélník, jehož left je větší z leftů příslušných obdélníků (obdobně je to s top, right a bottom). Snad vše objasní obrázek:


Pokud chceme napravit situace typu levá souřadnice je víc vpravo než pravá souřadnice, které mohou vzniknout například použitím calc_union(), můžeme použít metodu

void normalize();

Tato metoda v případě potřeby prohodí left a right nebo top a bottom.

Třída CL_Rect má konstruktor bez parametrů, který vytvoří prázdný objekt, aniž by jakkoliv inicializoval hodnoty. Dalšími konstruktory jsou:

CL_Rect(int new_left, int new_top, int new_right, int new_bottom);
CL_Rect(const CL_Point &p, const CL_Size &size); 

Ty již samozřejmě vytvoří objekty odpovídající zadaným obdélníkům. Nechybí pochopitelně ani kopírovací konstruktor.

Kromě již popsaných metod definuje třída CL_Rect také několik užitečných operátorů definovaných následovně:

CL_Rect &operator+=(const CL_Rect &r)
{ left += r.left; top += r.top; right += r.right; bottom += r.bottom; return *this; } 

Cílové souřadnice obsahují součty zdrojových. To odpovídá posunutí danému vektorem s počátkem v (0, 0) a koncem v (r.left, r.top) a zvětšení hran o hrany r.

CL_Rect &operator-=(const CL_Rect &r)
{ left -= r.left; top -= r.top; right -= r.right; bottom -= r.bottom; return *this; } 

Cílové souřadnice obsahují rozdíl zdrojových souřadnic (naše – předaná). Tj. posunutí v opačném směru a zmenšení hran.

CL_Rect &operator+=(const CL_Point &p)
{ left += p.x; top += p.y; right += p.x; bottom += p.y; return *this; } 

X-ové (resp. y-ové) souřadnice zvětšíme o x-ovou (resp. y-ovou) souřadnici předaného bodu. To odpovídá posunutí danému vektorem s počátkem v (0, 0) a koncem v (p.x, p.y).

CL_Rect &operator-=(const CL_Point &p)
{ left -= p.x; top -= p.y; right -= p.x; bottom -= p.y; return *this; } 

Totéž co předchozí, avšak odečítáme, tj. posunujeme v opačném směru.

CL_Rect operator+(const CL_Rect &r) const
{ return CL_Rect(left + r.left, top + r.top, right + r.right, bottom + r.bottom); }

CL_Rect operator-(const CL_Rect &r) const
{ return CL_Rect(left - r.left, top - r.top, right - r.right, bottom - r.bottom); }

CL_Rect operator+(const CL_Point &p) const
{ return CL_Rect(left + p.x, top + p.y, right + p.x, bottom + p.y); }

CL_Rect operator-(const CL_Point &p) const
{ return CL_Rect(left - p.x, top - p.y, right - p.x, bottom - p.y); } 

Obdoby += resp -=, které nemodifikují náš objekt:

bool operator==(const CL_Rect &r) const
{ return (left == r.left && top == r.top && right == r.right && bottom && r.bottom); } 

Vrací true, pokud se všechny souřadnice shodují.

bool operator!=(const CL_Rect &r) const
{ return (left != r.left || top != r.top || right != r.right || bottom != r.bottom); } 

Vrací true, pokud se některá dvojice odpovídajících souřadnic nerovná.

Závěr

Myslím, že používání tříd jako CL_Rect může programování s ClanLibem velice zrychlit a zefektivnit, proto doufám, že se vám výše uvedené informace budou alespoň občas hodit. Podobných tříd jako CL_Rect nabízí ClanLib mnohem více. Příkladem budiž například CL_Rectf, což je obdoba CL_Rect pracující s typem float namísto int (názvy metod i jejich význam se shodují, takže jsme se naučili používat vlastně dvě třídy namísto jedné). Dalšími takovými třídami jsou CL_Point, CL_Size a jiné. Jejich popis budu podle uvážení čas od času zařazovat, abyste o nic nepřišli :-).

Příště bychom se už myslím mohli opět vrátit k tvorbě GUI.

Našli jste v článku chybu?
Podnikatel.cz: Přehledná titulka, průvodci, responzivita

Přehledná titulka, průvodci, responzivita

Podnikatel.cz: K EET. Štamgast už peníze na stole nenechá

K EET. Štamgast už peníze na stole nenechá

DigiZone.cz: Recenze Westworld: zavraždit a...

Recenze Westworld: zavraždit a...

DigiZone.cz: Dreambox DM900 Ultra HD přichází

Dreambox DM900 Ultra HD přichází

Lupa.cz: Kdo pochopí vtip, může jít do ČT vyvíjet weby

Kdo pochopí vtip, může jít do ČT vyvíjet weby

Měšec.cz: Air Bank zruší TOP3 garanci a zdražuje kurzy

Air Bank zruší TOP3 garanci a zdražuje kurzy

Vitalia.cz: Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky

Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky

Podnikatel.cz: Chaos u EET pokračuje. Jsou tu další návrhy

Chaos u EET pokračuje. Jsou tu další návrhy

Vitalia.cz: Když přijdete o oko, přijdete na rok o řidičák

Když přijdete o oko, přijdete na rok o řidičák

Vitalia.cz: Pamlsková vyhláška bude platit jen na základkách

Pamlsková vyhláška bude platit jen na základkách

Podnikatel.cz: Udávání a účtenková loterie, hloupá komedie

Udávání a účtenková loterie, hloupá komedie

Lupa.cz: Co se dá měřit přes Internet věcí

Co se dá měřit přes Internet věcí

Vitalia.cz: Jsou čajové sáčky toxické?

Jsou čajové sáčky toxické?

Lupa.cz: Propustili je z Avastu, už po nich sahá ESET

Propustili je z Avastu, už po nich sahá ESET

Vitalia.cz: Spor o mortadelu: podle Lidlu falšovaná nebyla

Spor o mortadelu: podle Lidlu falšovaná nebyla

Měšec.cz: Zdravotní a sociální pojištění 2017: Připlatíte

Zdravotní a sociální pojištění 2017: Připlatíte

Měšec.cz: Kdy vám stát dá na stěhování 50 000 Kč?

Kdy vám stát dá na stěhování 50 000 Kč?

Podnikatel.cz: Podnikatelům dorazí varování od BSA

Podnikatelům dorazí varování od BSA

Lupa.cz: Proč firmy málo chrání data? Chovají se logicky

Proč firmy málo chrání data? Chovají se logicky

Vitalia.cz: I církev dnes vyrábí potraviny

I církev dnes vyrábí potraviny