Další služby pro kreslení - MujMAC.cz - Apple, Mac OS X, Apple iPod

Odběr fotomagazínu

Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!

 

Zadejte Vaši e-mailovou adresu:

Kamarád fotí rád?

Přihlas ho k odběru fotomagazínu!

 

Zadejte e-mailovou adresu kamaráda:

Soutěž

Sponzorem soutěže je:

IDIF

 

Odkud pochází fotografka Anne Erhard?

V dnešní soutěži hrajeme o:

Seriály

Více seriálů



Software

Další služby pro kreslení

30. října 2006, 00.00 | Seznámili jsme se již s těmi naprostými nejzákladnějšími základy – s nastavováním barev a se službou NSRectFill, jež aktivní barvou vyplní zadaný obdélník. To by nám ovšem pro velké kreslení nestačilo; dnes si proto řekneme malinko více.

Popis toho, kterak vytvářet vlastní podtřídy NSView, jsme začali tím nejdůležitějším: implementací metody drawRect:, jejímž prostřednictvím určujeme, kterak bude takové NSView vypadat na obrazovce (nebo třeba i na papíře po vytištění, neboť při tisku jsou samozřejmě využívány tytéž kreslicí služby, jako při kreslení do oken).

Seznámili jsme se také s těmi naprostými nejzákladnějšími základy – s nastavováním barev a se službou NSRectFill, jež aktivní barvou vyplní zadaný obdélník. To by nám ovšem pro velké kreslení nestačilo; dnes si proto řekneme malinko více.

Jak je to s těmi obdélníky?

Nejen při práci s grafikou je velmi často zapotřebí pracovat s obdélníky; Cocoa proto obsahuje standardní typ (nikoli třídu, neboť to by bylo skutečné plýtvání) NSRect – ten právě representuje obdélník, definovaný prostřednictvím rohu (obvykle levého dolního, ale v zásadě lze použít kterýkoli) a velikosti, šířky a výšky. Odpovídající deklarace vypadají asi nějak takto:

typedef struct _NSPoint {
   float x;
   float y;
} NSPoint;
typedef struct _NSSize {
   float width;
   float height;
} NSSize;
typedef struct _NSRect {
   NSPoint origin;
   NSSize size;
} NSRect;

Kdykoli se nám to hodí, můžeme s nimi přímo takto pracovat (např. tedy šířku obdélníku můžeme přímo nastavit příkazem typu "rect.size.width=100"); v praxi je však obvykle o něco šikovnější využívat standardních funkcí, jež Cocoa pro práci s geometrickými údaji nabízí. S některými z nich již jsme se seznámili minule; dnes si ukážeme další z těch, jež se hodí častěji:

  • NSMakePoint, NSMakeSize a NSMakeRect vytvoří hodnotu odpovídajícího typu – kupříkladu tedy obdélník 100x100 v bodě 10,10 vytvoříme příkazem NSMakeRect(10,10,100,100). Podobně jeho samotný výchozí bod je NSMakePoint(10,10) a jeho samotná velikost NSMakeSize(100,100);
  • chceme-li vytvořit nulový bod, velikost či bod, můžeme použít standardní NSZeroPoint, NSZeroSize a NSZeroRect;
  • hodnoty můžeme porovnávat pomocí funkcí NSEqualPoint, NSEqualSize a NSEqualRect. Pozor však na to, že všechny souřadnice jsou neceločíselné – při porovnávání tak můžeme snadno narazit na nějakou zaokrouhlovací chybu;
  • zde nám pomůže – máme-li vhodnou souřadnou soustavu, samozřejmě – standardní funkce NSIntegralRect: ta zaokrouhlí všechny souřadnice svého argumentu na celočíselné, a nový obdélník vrátí;
  • složitější a občas velmi cenné testy zahrnují NSIsEmptyRect, NSContainsRect (ověří, zda jeden obdélník kompletně obsahuje druhý), NSIntersectsRect (zjistí zda se dva obdélníky protínají);
  • nové obdélníky můžeme vytvářet pomocí služeb NSInsetRect (tu známe již od minula), NSIntersectionRect a NSUnionRect (vrátí průnik a sjednocení obdélníků) a NSDivideRect, jež rozdělí popsaným způsobem obdélník na dva;
  • jak už jsme si ukázali minule, máme k dispozici funkce NSMinX, NSMinY, NSWidth a NSHeight pro zjištění levého dolního (roste-li osa Y nahoru) bodu a velikosti obdélníku; navíc můžeme použít funkce NSMaxX a NSMaxY pro zjištění opačného rohu, a NSMidX, NSMidY pro geometrický střed.

Trochu více kreslení...

Je hezké umíme-li s obdélníky kouzlit, ale hlavním účelem tohoto cvičení je naučit se vykreslit cokoli, co vykreslit potřebujeme.

Již známe službu NSRectFill, jež zadaný obdélník vyplní aktuální barvou. Chceme-li naopak touto barvou vykreslit pouze obvod obdélníka, použijeme službu NSFrameRectWithWidth – jejím druhým argumentem je tloušťka požadované čáry. Ta se, mimochodem, kreslí uvnitř obdélníka – to může být důležité, potřebujeme-li čáry přesně navazovat.

Nevystačíme-li s obdélníky, je třeba sáhnout po nejuniversálnějším grafickém prostředku – po třídě NSBezierPath. Bézierovy křivky jsou velice šikovné matematické konstrukce, jejichž teorii si necháme od cesty :), podstatná je praxe, díky níž se jejich pomocí snadno (a efektivně) dá vyjádřit víceméně libovolný tvar.

Nejjednodušší je použít služeb třídy NSBezierPath pro vykreslení rovné čáry; na to stačí použít příkaz

[NSBezierPath strokeLineFromPoint:pt1 toPoint:pt2];

Nakreslí se čára mezi oběma body (jež můžeme vytvořit pomocí již známé služby NSMakePoint nebo spočíst třeba na základě obdélníka bounds); její tloušťka bude standardní, již bychom mohli v případě potřeby změnit příkazem "[NSBezierPath setDefaultLineWidth:N]". I na první pohled a bez vyzkoušení by vám již nyní mělo být jasné, jak bude vypadat třeba "view" s následující metodou drawRect:

-(void)drawRect:(NSRect)rect {
  [[NSColor blueColor] set];
  NSRectFill(rect);
  [[NSColor whiteColor] set];
  NSRect rr=[self bounds];
  NSFrameRectWithWidth(rr,[NSBezierPath defaultLineWidth]);
  [NSBezierPath strokeLineFromPoint:NSMakePoint(NSMinX(rr),NSMinY(rr))
     toPoint:NSMakePoint(NSMaxX(rr),NSMaxY(rr))];
  [NSBezierPath strokeLineFromPoint:NSMakePoint(NSMinX(rr),NSMaxY(rr))
     toPoint:NSMakePoint(NSMaxX(rr),NSMinY(rr))];
}

Ostatní případy jsou jen docela malilinko složitější – to nejprve Bézierovu křivku vytvoříme, a pak si vyžádáme její vykreslení. Chceme-li tedy kupříkladu nakreslit kružnici dejme tomu o středu 100,100 a poloměru 50, uděláme to takhle:

[[NSBezierPath bezierPathWithOvalInRect:NSMakeRect(50,50,100,100)] stroke];

První zpráva nám vytvoří Bézierovu křivku – instanci třídy NSBezierPath – jež vyjadřuje ovál, vyplňující zadaný obdélník; pošleme-li libovolné instanci třídy NSBezierPath zprávu stroke, křivka se nakreslí. Pokud bychom chtěli kolečko vyplnit, použijeme přesně týmž způsobem zprávu fill.

Bézierovy křivky toho samozřejmě dokáží mnohem více. Chceme-li sestavit a kreslit nějaký složitější tvar, vytvoříme odpovídající křivku postupně: nejprve vyrobíme odpovídající objekt a zadáme jeho výchozí bod:

NSBezierPath *bp=[NSBezierPath bezierPath];
[bp moveToPoint:NSMakePoint(10,20)];

Pak můžeme přidávat další "čáry", jež budou dohromady tvořit celou křivku – k dispozici máme jak rovné čáry, tak i kruhové oblouky:

[bp lineToPoint:NSMakePoint(10,0)];
[bp lineToPoint:NSMakePoint(30,0)];
[bp lineToPoint:NSMakePoint(30,20)];
[bp lineToPoint:NSMakePoint(40,20)];
[bp appendBezierPathWithArcWithCenter:NSMakePoint(20,20)
  radius:20 startAngle:0 endAngle:180];

Chceme-li křivku uzavřít – tedy vrátit se zpět do jejího prvého bodu – můžeme si to vyžádat pomocí zprávy closePath. Můžeme také, chceme-li, explicitně nastavit odlišnou tloušťku čáry od standardní... a výsledek vykreslíme:

[bp closePath];
[bp setLineWidth:4];
[bp stroke];

Bézierovy křivky toho samozřejmě dokáží ještě mnohem více; s tím, co již umíme, si však vystačíme víceméně pro cokoli, co bychom mohli chtít a potřebovat kreslit. Příště se proto pro změnu podíváme na to, kterak do našeho NSView kreslit obrázky a text.

Obsah seriálu (více o seriálu):

Tématické zařazení:

 » Rubriky  » Informace  

 » Rubriky  » Agregator  

 » Rubriky  » Začínáme s  

 » Rubriky  » Software  

Diskuse k článku

 

Vložit nový příspěvek   Sbalit příspěvky

 

Zatím nebyl uložen žádný příspěvek, buďte první.

 

 

Vložit nový příspěvek

Jméno:

Pohlaví:

,

E-mail:

Předmět:

Příspěvek:

 

Kontrola:

Do spodního pole opište z obrázku 5 znaků:

Kód pro ověření

 

 

 

 

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: