Xamarin.Forms Shapes: Füllregeln

Beispiel herunterladen Das Beispiel herunterladen

Mehrere Xamarin.Forms Shapes-Klassen verfügen über FillRule Eigenschaften vom Typ FillRule. Dazu zählen Polygon , Polyline und GeometryGroup .

Die FillRule -Enumeration definiert - und Nonzero -EvenOddMember. Jeder Member stellt eine andere Regel dar, um zu bestimmen, ob sich ein Punkt im Füllbereich eines Shapes befindet.

Wichtig

Alle Shapes gelten für Füllregeln als geschlossen.

Evenodd

Die EvenOdd Füllregel zeichnet einen Strahl vom Punkt zur Unendlichkeit in eine beliebige Richtung und zählt die Anzahl der Segmente innerhalb der Form, die der Strahl kreuzt. Wenn diese Zahl ungerade ist, befindet sich der Punkt innerhalb. Wenn diese Zahl gerade ist, liegt der Punkt außerhalb.

Im folgenden XAML-Beispiel wird eine zusammengesetzte Form erstellt und gerendert, wobei der FillRule Standardwert lautet 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>

In diesem Beispiel wird eine zusammengesetzte Form angezeigt, die aus einer Reihe von konzentrischen Ringen besteht:

Zusammengesetzte Form mit EvenOdd-Füllregel

Beachten Sie in der zusammengesetzten Form, dass die mittleren und dritten Ringe nicht gefüllt sind. Dies liegt daran, dass ein Strahl, der von einem beliebigen Punkt innerhalb eines dieser beiden Ringe gezeichnet wird, eine gerade Anzahl von Segmenten durchläuft:

Kommentierte zusammengesetzte Form mit EvenOdd-Füllregel

In der obigen Abbildung stellen die roten Kreise Punkte dar, und die Linien stellen beliebige Strahlen dar. Für den oberen Punkt durchlaufen die beiden beliebigen Strahlen jeweils eine gerade Anzahl von Liniensegmenten. Daher ist der Ring, in dem sich der Punkt befindet, nicht gefüllt. Für den unteren Punkt durchlaufen die beiden beliebigen Strahlen jeweils eine ungerade Anzahl von Liniensegmenten. Daher wird der Ring, in dem sich der Punkt befindet, gefüllt.

Nonzero

Die Nonzero Füllregel zeichnet einen Strahl vom Punkt zur Unendlichkeit in eine beliebige Richtung und untersucht dann die Stellen, an denen ein Segment der Form den Strahl kreuzt. Beginnend mit der Anzahl 0 (null) wird die Anzahl jedes Mal erhöht, wenn ein Segment den Strahl von links nach rechts kreuzt und jedes Mal verringert wird, wenn ein Segment den Strahl von rechts nach links kreuzt. Wenn das Ergebnis nach dem Zählen der Kreuze null ist, befindet sich der Punkt außerhalb des Polygons. Andernfalls ist es drinnen.

Im folgenden XAML-Beispiel wird eine zusammengesetzte Form erstellt und gerendert, wobei die FillRule auf Nonzerofestgelegt ist:

<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>

In diesem Beispiel wird eine zusammengesetzte Form angezeigt, die aus einer Reihe von konzentrischen Ringen besteht:

Das Diagramm zeigt vier konzentrische Kreise, die alle ausgefüllt sind.

Beachten Sie in der zusammengesetzten Form, dass alle Ringe gefüllt sind. Dies liegt daran, dass alle Segmente in derselben Richtung ausgeführt werden, sodass ein Strahl, der von einem beliebigen Punkt gezeichnet wird, ein oder mehrere Segmente kreuzt, und die Summe der Kreuzungen ist nicht gleich 0(0):

Das Diagramm zeigt die Kreise aus dem vorherigen Diagramm mit richtungsförmigen Pfeilen und einem Strahl, der mit + 1 versehen ist, für jeden Kreis, den er kreuzt.

In der Abbildung über stellen die roten Pfeile die Richtung dar, in der die Segmente gezeichnet werden, und der schwarze Pfeil stellt einen beliebigen Strahl dar, der von einem Punkt im innersten Ring ausgeht. Ausgehend vom Wert 0 (null) wird für jedes Segment, das der Strahl schneidet, der Wert 1 addiert, da das Segment den Strahl von links nach rechts schneidet.

Eine komplexere Form mit Segmenten, die in verschiedenen Richtungen verlaufen, ist erforderlich, um das Verhalten der Nonzero Füllregel besser zu veranschaulichen. Im folgenden XAML-Beispiel wird eine ähnliche Form wie im vorherigen Beispiel erstellt, mit der Ausnahme, dass sie mit einem PathGeometry anstelle von EllipseGeometryerstellt wird:

<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>

In diesem Beispiel wird eine Reihe von Bogensegmenten gezeichnet, die nicht geschlossen sind:

Das Diagramm zeigt vier konzentrische Kreise, wobei der äußerste und der dritte von äußerster Rand ausgefüllt sind.

In der obigen Abbildung ist der dritte Bogen aus der Mitte nicht gefüllt. Dies liegt daran, dass die Summe der Werte aus einem bestimmten Strahl, der die Segmente in seinem Pfad durchkreuzt, null ist:

Das Diagramm zeigt die Kreise aus dem vorherigen Diagramm mit Richtungspfeilen und zwei Strahlen, die für jeden Kreis, den sie kreuzen, mit +1 oder – 1 versehen sind.

In der obigen Abbildung stellt der rote Kreis einen Punkt dar, die schwarzen Linien stellen beliebige Strahlen dar, die sich aus dem Punkt im nicht ausgefüllten Bereich bewegen, und die roten Pfeile stellen die Richtung dar, in der die Segmente gezeichnet werden. Wie zu sehen ist, ist die Summe der Werte aus den Strahlen, die die Segmente kreuzen, null:

  • Der beliebige Strahl, der sich diagonal nach rechts bewegt, kreuzt zwei Segmente, die in verschiedenen Richtungen verlaufen. Daher brechen sich die Segmente gegenseitig ab und geben einen Wert von 0 (null) an.
  • Der beliebige Strahl, der sich diagonal links bewegt, kreuzt insgesamt sechs Segmente. Die Kreuzungen heben sich jedoch gegenseitig ab, sodass null die endgültige Summe ist.

Eine Summe von 0 (null) führt dazu, dass der Ring nicht gefüllt wird.