Hlavní navigace

Scalable Vector Graphics a základní geometrické tvary

16. 8. 2007
Doba čtení: 11 minut

Sdílet

Dnes bude popsán zápis informací o základních geometrických tvarech (basic shapes) do souborů typu Scalable Vector Graphics (SVG). Základní geometrické tvary jsou alternativou k minule popsaným cestám, kterou je možné použít při tvorbě animací či při požadavku na zachování informací o nástrojích použitých v editoru.

Obsah

1. Scalable Vector Graphics a základní geometrické tvary
2. Základní geometrické tvary
3. Úsečka
4. Obdélník
5. Kružnice
6. Elipsa
7. Polyčára
8. Polygon
9. Obsah dalšího pokračování tohoto seriálu

1. Vlastnosti cest a základních geometrických tvarů v SVG

V předchozí části tohoto seriálu jsme si popsali, jakým způsobem je možné v souborech typu Scalable Vector Graphics (SVG) ukládat informace o cestách (paths), tj. otevřených či uzavřených tvarech složených z úseček, Bézierových křivek a eliptických i kruhových oblouků. Kromě velmi obecně zadávaných cest jsou však v SVG podporovány i takzvané základní geometrické tvary (basic shapes). Jejich význam spočívá v tom, že už z názvu tvaru, popř. z názvu značky/tagu, kterou je tvar popsán, mohou aplikace zjistit o jaký tvar se jedná a přizpůsobit tomu své chování – grafický editor může například umožnit změnu poloměru kružnice bez její deformace; nebo v případě editace obdélníka je umožněno přemístění jeho vrcholů, ovšem tak, že výsledkem bude zase obdélník a ne obecný čtyřúhelník.

Tohoto chování nebylo u obecných cest možné dosáhnout – v souboru typu SVG je cesta „rozbita“ do jednotlivých segmentů popsaných jedním řetězcem obsahujícím pozice vrcholů a jednoznakové příkazy, které je velmi obtížné jakýmkoli způsobem dále popsat pomocí přidružených metadat. Cestu je také velmi obtížné animovat či dynamicky měnit její tvar, zatímco změna vrcholů základních geometrických tvarů je (za pomoci parametricky zadané animace či JavaScriptu společně s DOM) velmi jednoduchá a především intuitivní. Způsob zápisu základních geometrických tvarů bude popsán v dalších kapitolách, spolu s několika demonstračními příklady. Tvorba animací však přesahuje rozsah dnešního článku, proto se jimi budeme zabývat až v některé navazující části.

Jak cestám, tak i základním geometrickým tvarům je umožněno přiřazovat mnoho vlastností, které mění způsob vykreslení jejich obrysu a styl výplně. Taktéž je možné cesty i tvary seskupit do skupin (groups) a měnit či nastavovat vlastnosti celým skupinám. Právě zde se využívá předností formátu založeného na XML a tedy i na stromové struktuře ukládaných dat. Některé grafické editory, které se SVG formátem nativně pracují, podporují i seskupování (tedy nejenom seskupování zadané v editoru, ale i tvorbu stromů s grafickými objekty), což je jistě výhodné, už jenom kvůli jednoduššímu vytváření výkresů, které se mohou skládat z hierarchicky poskládaných částí. Možnostem nastavení vlastností i seskupování objektů se budeme zabývat v následující části tohoto seriálu.

2. Základní geometrické tvary

Do souborů typu SVG je možné ukládat značky/tagy reprezentující šest typů základních geometrických tvarů. Mezi tyto tvary patří úsečka (line), obdélník (rectangle), kružnice (circle), elipsa (ellipse), polyčára (polyline, lomená čára) a polygon (polygon). Všechny tyto tvary lze nahradit vhodně zapsanou cestou, ale z důvodů vysvětlených v předchozí kapitole (dodatečné informace pro grafické editory či další aplikace, jednodušší zápis i čtení pomocí SAX i DOM) se můžeme často setkat i s přímým zápisem základních geometrických tvarů. Definice tvarů pomocí cesty však většinou bývá kompaktnější, což vede k menšímu objemu výsledného souboru (ovšem tento rozdíl se viditelněji projeví až při velkých objemech dat). V následujících podkapitolách jsou jednotlivé základní geometrické tvary popsány podrobněji.

3. Úsečka

Nejjednodušším základním geometrickým tvarem je úsečka (line). Ta je v souborech typu SVG zapisována nepárovou značkou <line>. Kromě nastavení stylu a popř. i dalších atributů je nutné uvést souřadnice obou vrcholů úsečky. Jedná se o hodnoty atributů x1, y1, x2 a y2. Úsečka patří mezi objekty, které nemají žádný „vnitřek“, nejsou tedy vyplňované a nastavení stylu výplně pro ně nemá žádný smysl (i když úsečka může být součástí skupiny, pro kterou je styl výplně nastaven). Úsečky také nelze spojit do uzavřeného a tím i vyplněného útvaru – pro tento účel se musí použít cesta či dále popsaný polygon. Celý zápis značky s informacemi o úsečce by měl v nejjednodušším případě, tj. bez specifikace dalších negeometrických vlastností úsečky, vypadat takto:

<line x1="číselná hodnota" y1="číselná hodnota" x2="číselná hodnota" y2="číselná hodnota" /> 

Následuje jednoduchý příklad, ve kterém je použito několik úseček vykreslených různou barvou:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="200"
     height="200"
     viewBox="0 0 200 200"
     xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink">

     <!-- diagonální úsečka vykreslená implicitním stylem -->
     <line x1="0" y1="0" x2="200" y2="200" />

     <!-- různobarevné vodorovné úsečky -->
     <line stroke="red"    stroke-width="4" x1="50" y1="20" x2="150" y2="20" />
     <line stroke="blue"   stroke-width="4" x1="50" y1="40" x2="150" y2="40" />
     <line stroke="green"  stroke-width="4" x1="50" y1="60" x2="150" y2="60" />

     <!-- různobarevné svislé úsečky -->
     <line stroke="orange" stroke-width="4" x1="20" y1="50" x2="20" y2="150" />
     <line stroke="yellow" stroke-width="4" x1="40" y1="50" x2="40" y2="150" />
     <line stroke="green"  stroke-width="4" x1="60" y1="50" x2="60" y2="150" />
</svg> 

5101
Obrázek 1: Demonstrační příklad vykreslený v prohlížeči SVG souborů

4. Obdélník

Poněkud složitějším základním geometrickým tvarem je obdélník (rectangle). Implicitně je možné vykreslovat pouze osově orientovaný obdélník, jehož natočení do libovolného směru se provádí pomocí transformací, které budou popsány v následujících částech tohoto seriálu. Obdélník patří mezi geometrické tvary, které mohou být vyplněné, podobně jako uzavřené cesty, proto je u něj možné zadávat styly výplně (to si ukážeme na demonstračním příkladu). Obdélník je do souborů typu SVG zapisován pomocí značky <rect>, která by měla mít uvedeny minimálně atributy x, y, width a height, kterými se specifikuje levý horní vrchol obdélníku a jeho rozměry. Pokud by nebyla šířka ani výška uvedena, či by byla nulová, obdélník se nevykreslí (tj. nebude viditelná ani hrana, i když se geometricky jedná o obdobu úsečky). Záporná výška či šířka vede k chybě. Obecný zápis značky rect má tvar:

<rect x="číselná hodnota" y="číselná hodnota" width="nezáporná číselná hodnota" height="nezáporná číselná hodnota" /> 

Kromě výše zmíněných čtyř atributů je možné definovat i obdélník se zakulacenými rohy (rounded rectangle). Do značky <rect> lze za tímto účelem zapsat další dva atributy nazvané rx a ry, kterými se specifikuje poloměr os elipsy, kterými jsou nahrazeny všechny čtyři rohy obdélníku (každý roh je tedy zakulacen stejným eliptickým čtvrtobloukem, každý je samozřejmě zrcadlen podle toho, který vrchol nahrazuje). V případě, že není uveden ani jeden z atributů rx a ry, je vykreslen obdélník bez zakulacených rohů. Pokud jeden z atributů chybí, je místo jeho hodnoty doplněna hodnota atributu zbývajícího – místo eliptického čtvrtoblouku se tedy bude konstruovat kružnicový čtvrtoblouk. Pokud by jeden či oba poloměry byly větší než polovina hrany obdélníka (což je geometrický nesmysl), je tento poloměr/poloměry přiměřeně zkrácen. To může v limitě vést až k vytvoření elipsy nebo kružnice. Všechny varianty si ukážeme na následujícím demonstračním příkladu:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="300"
     height="300"
     viewBox="0 0 300 300"
     xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink">

     <!-- jednoduchý obdélník bez zakulacených rohů -->
     <rect x="10" y="10" width="100" height="75" />

     <!-- obdélník se zakulacenými rohy -->
     <rect x="120" y="10" width="100" height="75" rx="20" stroke="red" stroke-width="2" fill="none" />

     <!-- rozdílné poloměry zakulacení -->
     <rect x="10" y="90" width="100" height="75" rx="30" ry="20" stroke="green" stroke-width="2" fill="none" />

     <!-- rozdílné poloměry zakulacení -->
     <rect x="120" y="90" width="100" height="75" rx="20" ry="30" stroke="blue" stroke-width="2" fill="none" />

     <!-- co se stane, když je poloměr zaoblení moc velký? -->
     <rect x="10" y="180" width="100" height="75" rx="100" stroke="#cccc00" stroke-width="2" fill="none" />

     <!-- na co kružnice, vystačíme si s obdélníkem :-) -->
     <rect x="120" y="180" width="100" height="100" rx="50" stroke="#80cc80" stroke-width="2" fill="none" />
</svg> 

5102
Obrázek 2: Demonstrační příklad s obdélníky vykreslený v prohlížeči SVG souborů

5. Kružnice

Třetím typem základního geometrického tvaru podporovaného v souborech typu SVG, je kružnice (circle). Tento tvar se zapisuje pomocí značky <circle>, která by měla mít uvedeny minimálně tři atributy: cx (x-ová souřadnice středu kružnice), cy (y-ová souřadnice středu kružnice) a r (poloměr kružnice). Pokud není x-ová či y-ová souřadnice uvedena, je místo její hodnoty dosazena nula. Poloměr by měl být kladný – v případě, že by byl záporný, jedná se o chybu a nulový poloměr zapříčiní, že se kružnice nevykreslí (i když by teoreticky mohla být vykreslena jako jeden ostylovaný bod). Podobně jako obdélník, i kružnice může být vyplněna konstantní barvou, vzorkem nebo gradientní výplní. V následujícím demonstračním příkladu bude ukázáno vytvoření několika kružnic s rozdílným stylem.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="300"
     height="300"
     viewBox="0 0 300 300"
     xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink">

     <!-- kružnice bez nastavených stylů -->
     <circle cx="140" cy="140" r="50" />

     <!-- kružnice bez nastavených stylů -->
     <circle cx="60" cy="60" r="50" fill="#ffaaaa" stroke="black" stroke-width="4" />

     <!-- kružnice s nastaveným stylem výplně a barvy obrysu -->
     <circle cx="220" cy="60" r="50" fill="#aaffaa" stroke="black" stroke-width="4" />

     <!-- kružnice s nastaveným stylem výplně a barvy obrysu -->
     <circle cx="60" cy="220" r="50" fill="#ffffaa" stroke="black" stroke-width="4" />

     <!-- kružnice s nastaveným stylem výplně a barvy obrysu -->
     <circle cx="220" cy="220" r="50" fill="#aaffff" stroke="black" stroke-width="4" />
</svg> 

5103
Obrázek 3: Demonstrační příklad s kružnicemi vykreslený v prohlížeči SVG souborů

6. Elipsa

Elipsa (ellipse) je dalším základním geometrickým tvarem, který je možné v SVG zapsat samostatnou značkou. Tato značka, jež se jmenuje – jak jinak – <ellipse>, by měla mít nastavené čtyři číselné atributy. Jedná se o atribut cx (x-ová souřadnice středu elipsy), cy (y-ová souřadnice středu elipsy), rx (poloměr poloosy rovnoběžné s x-ovou osou) a ry (poloměr poloosy rovnoběžné s y-ovou osou). Podobně jako u kružnice, i v případě elipsy platí, že pokud není nějaká souřadnice nastavená, je považována za nulovou. Zadání záporného poloměru libovolné poloosy vede k chybě, nulový poloměr má za následek, že se elipsa nevykreslí, i když by teoreticky mohla být vykreslena jako úsečka. Samozřejmě se jedná o uzavřený geometrický tvar, takže je možné nastavovat barvu a styl výplně (implicitně se jedná o černou barvu). Demonstrační soubor, ve kterém je definováno celkem pět elips (jedna ve tvaru kružnice, tj. se shodnými poloměry poloos), je velmi podobný předchozímu příkladu:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="300"
     height="300"
     viewBox="0 0 300 300"
     xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink">

     <!-- kružnice vykreslená pomocí elipsy bez nastavených stylů -->
     <ellipse cx="140" cy="140" rx="50" ry="50" />

     <!-- elipsa s rozdílnými poloměry poloos -->
     <ellipse cx="60" cy="60" rx="50" ry="30" fill="#ffaaaa" stroke="black" stroke-width="4" />

     <!-- elipsa s rozdílnými poloměry poloos -->
     <ellipse cx="220" cy="60" rx="50" ry="30" fill="#aaffaa" stroke="black" stroke-width="4" />

     <!-- elipsa s rozdílnými poloměry poloos -->
     <ellipse cx="60" cy="220" rx="30" ry="50" fill="#ffffaa" stroke="black" stroke-width="4" />

     <!-- elipsa s rozdílnými poloměry poloos -->
     <ellipse cx="220" cy="220" rx="30" ry="50" fill="#aaffff" stroke="black" stroke-width="4" />
</svg> 

5104
Obrázek 4: Demonstrační příklad s elipsami vykreslený v prohlížeči SVG souborů

7. Polyčára

Polyčára (polyline) je geometrický tvar složený z libovolného počtu na sebe navazujících úseček. Jedná se o tvar, který nemá určený „vnitřek“, tj. nemůže být vyplněn, a to ani v případě, že koncový bod poslední úsečky je shodný s počátečním bodem polyčáry. Na rozdíl od všech výše popsaných geometrických tvarů, které byly definovány pomocí pevného počtu parametrů (vrcholů, velikostí, popř. jedním či více poloměry), je polyčára odlišná v tom, že je možné specifikovat libovolný počet vrcholů (bodů v 2D prostoru), které se propojí lomenou čarou. Polyčára je v souborech typu SVG zapsána pomocí značky <polyline>, která by měla obsahovat atribut points, jehož hodnotou je seznam sudého počtu čísel reprezentujících souřadnice jednotlivých vrcholů (každý vrchol je v 2D zadán dvojicí souřadnic, bývá dobrým zvykem tyto souřadnice oddělovat čárkou). V případě, že by byl zadán lichý počet souřadnic, jedná se o chybný SVG soubor (na druhou stranu počet souřadnic 2 není považován za chybu).

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
    "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="300"
     height="300"
     viewBox="0 0 300 300"
     xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink">
     <!-- vykreslení domečku jedním tahem -->
    <polyline fill="none" stroke="red" stroke-width="2"
        points="100,250 200,250 100,150 100,250 200,150 100,150 150,100 200,150, 200,250" />

</svg> 

5105
Obrázek 5: Demonstrační příklad s polyčarou vykreslený v prohlížeči SVG souborů

8. Polygon

Polygon je základní geometrický tvar zadávaný podobně jako výše popsaná polyčára, tj. seznamem vrcholů, které jsou navzájem propojeny. Na rozdíl od polyčáry je však polygon vyplněný, tj. kromě vlastností obrysu je možné specifikovat i vlastnosti výplně. V následujícím příkladu je ukázáno vykreslení vyplněného „domku jedním tahem“, který není celý vyplněný z toho důvodu, že logika pro určování vnitřního a vnějšího prostoru polygonu je založena na stejném principu (pravidlech, rules), jako v případě PostScriptu. Bližší informace o způsobu vyplňování si řekneme v následující části tohoto seriálu.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
    "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="300"
     height="300"
     viewBox="0 0 300 300"
     xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink">
     <!-- vykreslení domečku jedním tahem -->
    <polygon fill="#8080ff" stroke="red" stroke-width="2"
        points="100,250 200,250 100,150 100,250 200,150 100,150 150,100 200,150, 200,250" />

</svg> 

CS24_early

5106
Obrázek 6: Demonstrační příklad s polygonem vykreslený v prohlížeči SVG souborů

9. Obsah dalšího pokračování tohoto seriálu

V následujícím pokračování seriálu o grafických formátech a metaformátech si podrobněji popíšeme vlastnosti vytvářených cest i základních geometrických tvarů, například způsob zápisu barvy cesty či její výplně, seskupování geometrických tvarů do uzlů a specifikace vlastností pro tyto uzly apod.

Byl pro vás článek přínosný?

Autor článku

Vystudoval VUT FIT a v současné době pracuje na projektech vytvářených v jazycích Python a Go.