XAML.cz Magazín moderních technologií založených na XAML

Geometrie ve WPF

Napsáno pro WPF od Jirka Pénzeš [19.08.2010]

Pro potřebu vykreslování 2D geometrických útvarů je ve WPF připravena třída Shape. Z této třídy jsou odvozeny a připraveny pro práci objekty Ellipse, Line, Path, Polygon, Polyline a Rectangle. Pokud ale chceme nakreslit vlastní geometrický tvar nebo se jen zabývat kreslením křivek, je pro nás zajímavá třída Path, která dokáže vykreslit i „libovolnou“ geometrickou cestu.

Při zkoumáni třídy Path přijdeme na to, že definuje pouze jednu vlastnost – Data. Do této vlastnosti se přiřazuje právě jeden objekt, který musí být typu Geometry, resp. třídy odvozené, neboť samotná třída Geometry je abstraktní.

Možná se ptáte, proč používat Geometry objekty, namísto klasických Shapes – na první pohled se může zdát, že se jedná o totéž. Třída Geometry ale definuje pouze geometrický tvar a o vlastní vykreslování se nestará, oproti Shapes. Pro svou jednoduchost má tak široké použití.

Za zajímavost stojí říct, že třída Geometry je potomkem třídy Freezable. Máme tak větší výkonnost při čtení těchto objektů, klonovaní a také více-vláknový přístup by zde měl být lepší (thread-safe). Oproti Shape objektům, které jsou z FrameworkElemenetu

LineGeometry

Už ze školy víme, že nejjednodušeji se v geometrii vždy kreslila úsečka. Ve WPF tomu není jinak. Slouží k tomu objekt typu LineGeometry, kde definujeme pouze počáteční a koncový bod (StartPoint, EndPoint). Při kreslení více úseček si musíme uvědomit, že každý LineGeometry vyžaduje vlastní nastavení hodnot pro Stroke – tedy barvu a StrokeThickness.

<Path Stroke="DarkOliveGreen" Fill="Blue" StrokeThickness="2">
    <Path.Data>
        <LineGeometry StartPoint="25 30" EndPoint="150 50"></LineGeometry>
    </Path.Data>
</Path>
<Path Stroke="DarkCyan" Fill="Blue" StrokeThickness="2">
    <Path.Data>
        <LineGeometry StartPoint="40 50" EndPoint="250 10"></LineGeometry>
    </Path.Data>
</Path>
 
Příklad dvou linek

EllipseGeometry a RectangleGeometry 

Dalšími základními objekty je obecný obdélník a elipsa. Začněme elipsou. U elipsy jsou důležité pro její správné vykreslení tři vlastnosti – Center, RadiusX a RadiusY. Vlastnost Center je typu Point a určuje střed elipsy. Pokud vlastnost center opomenete, je za střed elipsy považován bod [0, 0] – vykreslí se tak pouze čtvrtý kvadrant elipsy v levém horním rohu aplikace. Pokud zadáme bod – dále pak stačí již vyplnit pouze RadiusX a RadiusY, které určí rozměr elipsy.

Rectangle, tedy obecný obdélník, definuje vlastnosti Rect, RadiusX a RadiusY. První vlastnost určí rozměry a pozici obdélníku. Lze jej zadat i textovým řetězcem ve formátu Rect=“X Y Šířka Výška“, kde [X, Y] jsou souřadnice levého horního bodu obdélníku. Rádiusy určují zaoblení rohů – pokud je nezadáme, dostaneme klasický pravoúhlý obdélník.

Elipsa i obdélník mají zmiňované vlastnosti závislé, lze jej tedy snadno animovat.

<Path Stroke="Red" Fill="YellowGreen" StrokeThickness="2">
    <Path.Data>
        <EllipseGeometry Center="200 170" RadiusX="60" RadiusY="30"></EllipseGeometry>
    </Path.Data>
</Path>
<Path Stroke="MediumAquamarine" Fill="Crimson" StrokeThickness="2">
    <Path.Data>
        <RectangleGeometry Rect="50 50 200 80" RadiusX="10" RadiusY="10"></RectangleGeometry>
    </Path.Data>
</Path>
EllipseGeometry a RectangleGeometry 

GeometryGroup

Doposud jsme vždy pracovali vždy pouze s jedním geometrickým objektem, v rámci třídy Path. To je do značné míry zapříčiněno tím, že vlastnost Path.Data může obsahovat pouze jeden geometrický objekt. Tento nedostatek lze obejít pomocí GeometryGroup. Opět se jedná o potomka ke třídě Geometry, jako tomu bylo u předchozích příkladů – lze jej tedy přiřadit k Path.Data. V případě GeometryGroup se ovšem nejedná o třídu reprezentující nějaký specifický geometrický útvar, nýbrž jak už název napovídá – bude se jednat o skupinu geometrických útvarů. Docíleno je to vlastností Children, která je pouze prostou kolekcí objektů typu Geometry. Můžeme tedy v rámci jedné instance Path umístit do vlastnosti Data více instancí geometrických objektů (teoreticky neomezeně).

<Path Stroke="DarkViolet" Fill="AliceBlue" StrokeThickness="2">
    <Path.Data>
        <GeometryGroup>
            <LineGeometry StartPoint="25 30" EndPoint="150 50"></LineGeometry>
            <LineGeometry StartPoint="40 50" EndPoint="250 10"></LineGeometry>
        </GeometryGroup>
    </Path.Data>
</Path>

CombinedGeometry

Obdobně jako předchozí třída dokáže i tato pracovat s více geometrickými objekty. Oproti třídě GeometryGroup zde není vlastnost Children, nýbrž Geometry1 a Geometry2. Klíčovým parametrem je ale GeometryCombineMode, který této třídě otevírá další možnosti při práci s geometrimií. Prvním dvěma vlastnostem (Geometry1 a Geometry2) nastavíme libovolné geometrické útvary. Důležitá a zajímavá vlastnost je právě ta poslední zmiňovaná. Říká nám totiž, jak se geometrické objekty seskupí. Parametrem této property je výčtový typ, který nabízí následující čtyři možnosti:

  • Union (sjednocení)
  • Intersect (průnik)
  • Xor (klasický Xor režim)
  • Exclude (rozdíl –> Geometry1 - Geometry2)

Z popisu je zřejmé, že fungují jako klasické množinové operace (Vennovy diagramy).

<Path Stroke="DarkViolet" Fill="AliceBlue" StrokeThickness="2">
    <Path.Data>
        <CombinedGeometry GeometryCombineMode="Exclude">
            <CombinedGeometry.Geometry1>
                <EllipseGeometry Center="200 170" RadiusX="60" RadiusY="30"></EllipseGeometry>
            </CombinedGeometry.Geometry1>
            <CombinedGeometry.Geometry2>
                <EllipseGeometry Center="300 170" RadiusX="60" RadiusY="30"></EllipseGeometry>
            </CombinedGeometry.Geometry2>
        </CombinedGeometry>
    </Path.Data>
</Path>
 

CombinedGeometry

Závěrem

Toto byl úvod do základní práce s geometrií ve WPF. Příště se podíváme na třídu PathGeometry, která nám již dává naprostou volnost při tvorbě geometrických obrazců, především pak při tvorbě křivek (můžeme pomocí ní kreslit i aproximační křivky - např. známou Bezierovu křivku). 

Komentáře

ukládám komentář, vyčkejte prosím..
  1. Buďte první, kdo napíše komentář.

@xamlcz

  • RT @jvanrhyn: XAML, It's a bit like olives. Takes a while to get used to. But once you're used to it. It is actually pretty good. <3 XAML
  • RT @moser_christian: WPF Inspector 0.9.7 is released. It supports .NET 3.5 and 4.0 The project is now open source and available on CodeP ...
  • Jeff Handley oznámil vydání WCF RIA Services v.1.0 SP1 RTM http://bit.ly/gOgckn ke stažení na http://bit.ly/gVAXdK
  • jedna výzva pro Brno. Byl někdo z vás na přednášce o RIA v MS Akvárku? Dejte o sobě vědět. Děkuji
  • také jste uvažovali o tom, že zkusíte na projekt použít Caliburn Micro nebo naopak Prism 4? A co tak obojí, šlo by to nebo ne? Již brzy