Xamarin.Forms Obrazce: Pravidla výplně
Několik Xamarin.Forms tříd obrazců má FillRule
vlastnosti typu FillRule
. Patří mezi ně Polygon
, Polyline
a GeometryGroup
.
Výčet FillRule
definuje EvenOdd
a Nonzero
členy. Každý člen představuje jiné pravidlo pro určení, zda je bod v oblasti výplně obrazce.
Důležité
Všechny obrazce jsou považovány za zavřené pro účely pravidel výplně.
EvenOdd
Pravidlo EvenOdd
výplně nakreslí paprsek od bodu do nekonečna v libovolném směru a spočítá počet segmentů ve tvaru, který paprsk protíná. Pokud je toto číslo liché, bod je uvnitř. Pokud je toto číslo sudé, bod je mimo.
Následující příklad XAML vytvoří a vykreslí složený obrazec s FillRule
výchozím nastavením:EvenOdd
<Path Stroke="Black"
Fill="#CCCCFF"
Aspect="Uniform"
HorizontalOptions="Start">
<Path.Data>
<!-- FillRule doesn't need to be set, because EvenOdd is the default. -->
<GeometryGroup>
<EllipseGeometry RadiusX="50"
RadiusY="50"
Center="75,75" />
<EllipseGeometry RadiusX="70"
RadiusY="70"
Center="75,75" />
<EllipseGeometry RadiusX="100"
RadiusY="100"
Center="75,75" />
<EllipseGeometry RadiusX="120"
RadiusY="120"
Center="75,75" />
</GeometryGroup>
</Path.Data>
</Path>
V tomto příkladu se zobrazí složený obrazec tvořený řadou soustředných kroužků:
Ve složeného tvaru si všimněte, že střed a třetí kroužky nejsou vyplněné. Je to proto, že paprsek nakreslený z libovolného bodu v některém z těchto dvou kroužků prochází sudým počtem segmentů:
Na obrázku výše představují červené kruhy body a čáry představují libovolné paprsky. U horního bodu obě libovolné paprsky procházejí sudým počtem segmentů čáry. Proto prstenec, ve které je bod, není vyplněný. V dolním bodě obě libovolné paprsky projdou lichým počtem segmentů čar. Proto je prstenec, ve které je bod vyplněný.
Nenulová
Pravidlo Nonzero
výplně nakreslí paprsek z bodu do nekonečna v libovolném směru a pak prozkoumá místa, kde segment obrazce protíná paprsk. Počínaje počtem nul se počet zvýší pokaždé, když segment protíná paprsek zleva doprava a odpojí se pokaždé, když segment protíná paprsek zprava doleva. Po počítání přechodů platí, že pokud je výsledek nulový, bod je mimo mnohoúhelník. Jinak je uvnitř.
Následující příklad XAML vytvoří a vykresluje složený obrazec se FillRule
sadou na Nonzero
:
<Path Stroke="Black"
Fill="#CCCCFF"
Aspect="Uniform"
HorizontalOptions="Start">
<Path.Data>
<GeometryGroup FillRule="Nonzero">
<EllipseGeometry RadiusX="50"
RadiusY="50"
Center="75,75" />
<EllipseGeometry RadiusX="70"
RadiusY="70"
Center="75,75" />
<EllipseGeometry RadiusX="100"
RadiusY="100"
Center="75,75" />
<EllipseGeometry RadiusX="120"
RadiusY="120"
Center="75,75" />
</GeometryGroup>
</Path.Data>
</Path>
V tomto příkladu se zobrazí složený obrazec tvořený řadou soustředných kroužků:
Ve složeného tvaru si všimněte, že jsou vyplněny všechny kroužky. Důvodem je to, že všechny segmenty běží ve stejném směru, a proto paprsk nakreslený z libovolného bodu protíná jeden nebo více segmentů a součet přechodů se nerovná nule:
Na obrázku nad červenými šipkami představují směr vykreslení segmentů a černá šipka představuje libovolný paprsek spuštěný z bodu v nejvnitřnějším kruhu. Počínaje hodnotou nuly, pro každý segment, který paprsek kříží, je přidána hodnota jednoho, protože segment protíná paprsek zleva doprava.
Složitější obrazec se segmenty spuštěnými v různých směrech je potřeba k lepšímu předvedení chování Nonzero
pravidla výplně. Následující příklad XAML vytvoří podobný obrazec jako v předchozím příkladu, s tím rozdílem PathGeometry
EllipseGeometry
, že se vytvoří místo :
<Path Stroke="Black"
Fill="#CCCCFF">
<Path.Data>
<GeometryGroup FillRule="Nonzero">
<PathGeometry>
<PathGeometry.Figures>
<!-- Inner ring -->
<PathFigure StartPoint="120,120">
<PathFigure.Segments>
<PathSegmentCollection>
<ArcSegment Size="50,50"
IsLargeArc="True"
SweepDirection="CounterClockwise"
Point="140,120" />
</PathSegmentCollection>
</PathFigure.Segments>
</PathFigure>
<!-- Second ring -->
<PathFigure StartPoint="120,100">
<PathFigure.Segments>
<PathSegmentCollection>
<ArcSegment Size="70,70"
IsLargeArc="True"
SweepDirection="CounterClockwise"
Point="140,100" />
</PathSegmentCollection>
</PathFigure.Segments>
</PathFigure>
<!-- Third ring -->
<PathFigure StartPoint="120,70">
<PathFigure.Segments>
<PathSegmentCollection>
<ArcSegment Size="100,100"
IsLargeArc="True"
SweepDirection="CounterClockwise"
Point="140,70" />
</PathSegmentCollection>
</PathFigure.Segments>
</PathFigure>
<!-- Outer ring -->
<PathFigure StartPoint="120,300">
<PathFigure.Segments>
<ArcSegment Size="130,130"
IsLargeArc="True"
SweepDirection="Clockwise"
Point="140,300" />
</PathFigure.Segments>
</PathFigure>
</PathGeometry.Figures>
</PathGeometry>
</GeometryGroup>
</Path.Data>
</Path>
V tomto příkladu jsou nakresleny řady obloukových segmentů, které nejsou uzavřeny:
Na obrázku výše není třetí oblouk ze středu vyplněný. Důvodem je to, že součet hodnot z daného paprsku, který překračuje segmenty v jeho cestě, je nula:
Na obrázku výše představuje červený kruh bod, černé čáry představují libovolné paprsky, které se pohybují od bodu v nezaplněné oblasti, a červené šipky představují směr, kterým jsou segmenty nakresleny. Jak je vidět, součet hodnot z paprsků překračujících segmenty je nula:
- Libovolný paprsek, který se pohybuje diagonálně doprava, protíná dva segmenty, které běží v různých směrech. Proto se segmenty navzájem ruší a poskytují hodnotu nuly.
- Libovolný paprsek, který cestuje diagonálně vlevo, překříží celkem šest segmentů. Přechody se ale navzájem ruší, takže nula je konečný součet.
Součet nulových výsledků v prstenci se nevyplní.