Xamarin.Forms Obrazce: Pravidla výplně

Download Sample Stažení ukázky

Několik Xamarin.Forms tříd obrazců má FillRule vlastnosti typu FillRule. Patří mezi ně Polygon, Polylinea 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 uzavřené pro účely pravidel výplně.

EvenOdd

Pravidlo EvenOdd výplně nakreslí paprsek z bodu na nekonečno v libovolném směru a spočítá počet segmentů ve tvaru, který paprsk kříží. Pokud je toto číslo liché, je bod uvnitř. Pokud je toto číslo sudé, bod je mimo.

Následující příklad XAML vytvoří a vykresluje 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ů:

Composite shape with EvenOdd fill rule

Ve složeného obrazci si všimněte, že střed a třetí kroužky nejsou vyplněné. Důvodem je to, že paprsek vytažený z libovolného bodu v některém z těchto dvou kroužků prochází sudým počtem segmentů:

Annotated composite shape with EvenOdd fill rule

Na obrázku výše představují červené kruhy body a čáry představují libovolné paprsky. U horního bodu projdou dva libovolné paprsky, každý prochází sudým počtem segmentů čáry. Proto prstenec, ve které je bod, není vyplněný. V dolním bodě oba libovolné paprsky procházejí lichým počtem segmentů čáry. Proto je prstenec, ve které je bod vyplněný.

Nenulová

Pravidlo Nonzero výplně nakreslí paprsek z bodu na nekonečno v libovolném směru a pak prozkoumá místa, kde segment obrazce kříží paprsk. Počínaje počtem nuly se počet zvýší pokaždé, když segment přetíná paprsk zleva doprava a pokaždé, když segment překročí paprsek zprava doleva, a zmenšuje se při každém překročení paprsku zprava doleva. Po počítání přechodů je výsledek nula, pak je bod 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ů:

Diagram shows four concentric circles, all filled in.

Ve složeného obrazci si všimněte, že jsou vyplněné všechny kroužky. Důvodem je to, že všechny segmenty běží ve stejném směru, takže paprsk nakreslený z libovolného bodu protíná jeden nebo více segmentů a součet přechodů se nebude rovnat nule:

Diagram shows the circles from the previous diagram with directional arrows and a ray annotated with + 1 for each circle it crosses.

Na obrázku nad červenými šipkami představují směr vykreslení segmentů a černá šipka představuje libovolný paprsek běžící z bodu v nejvnitřnějším kruhu. Počínaje hodnotou nuly pro každý segment, který paprsk kříží, se přidá hodnota jednoho, protože segment prochází paprskem 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 výjimkou toho, že je vytvořen místo PathGeometry :EllipseGeometry

<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 se nakreslí řada segmentů oblouku, které nejsou uzavřeny:

Diagram shows four concentric circles, with the outmost and third from outermost filled in.

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 překračování segmentů v cestě je nula:

Diagram shows the circles from the previous diagram with directional arrows and two rays annotated with + 1 or – 1 for each circle they cross.

Na obrázku výše představuje červený kruh bod, černé čáry představují libovolné paprsky, které se odsunou od bodu v neplněné oblasti a červené šipky představují směr vykreslení segmentů. Jak je vidět, součet hodnot z paprsků procházejících segmenty je nula:

  • Libovolný paprsek, který prochází diagonálně doprava, prochází dvěma segmenty, které běží v různých směrech. Proto segmenty navzájem zruší hodnotu nuly.
  • Libovolný paprsek, který cestuje diagonálně vlevo, překračuje celkem šest segmentů. Přechody se však navzájem zruší tak, aby nula byla konečným součtem.

Součet nulových výsledků v prstenci, který se nenaplní.