Gewusst wie: Steuern des Ausfüllens einer zusammengesetzten Form

Aktualisiert: November 2007

Die FillRule-Eigenschaft einer GeometryGroup oder einer PathGeometry gibt eine "Regel" an, die von der zusammengesetzten Form verwendet wird, um zu ermitteln, ob ein bestimmter Punkt Teil der Geometrie ist. Es gibt zwei mögliche Werte für FillRule: EvenOdd und Nonzero. In den folgenden Abschnitten wird beschrieben, wie diese beiden Regeln verwendet werden.

EvenOdd: Diese Regel ermittelt, ob sich ein Punkt im Ausfüllbereich befindet, indem von diesem Punkt aus ein Strahl in beliebiger Richtung gegen Unendlich gezeichnet wird und die Anzahl der Pfadsegmente in der Form, die vom Strahl geschnitten wird, gezählt wird. Wenn diese Zahl ungerade ist, liegt der Punkt im Ausfüllbereich, wenn die Zahl gerade ist, befindet sich der Punkt außerhalb des Bereichs.

So erstellt das unten aufgeführte XAML eine zusammengesetzte Form, die aus einer Reihe konzentrischer Ringe (Ziel) besteht, wobei eine FillRule auf EvenOdd festgelegt ist.

<Path Stroke="Black" StrokeThickness="1" Fill="#CCCCFF">
  <Path.Data>
    <GeometryGroup FillRule="EvenOdd">
      <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 der folgenden Abbildung wird die im vorherigen Beispiel erstellte Form dargestellt.

Bildschirmabbildung: FillRule-Eigenschaft EvenOdd

Beachten Sie, dass in der Abbildung oben die Mitte und der dritte Ring nicht ausgefüllt sind. Dies ist darauf zurückzuführen, dass ein Strahl, der von einem beliebigen Punkt innerhalb eines dieser beiden Ringe gezeichnet wird, eine gerade Anzahl von Segmenten durchläuft. Siehe folgende Abbildung:

Diagramm: FillRule-Eigenschaftenwert EvenOdd

NonZero: Diese Regel bestimmt, ob sich ein Punkt im Ausfüllbereich des Pfads befindet, indem ein unendlicher Strahl von diesem Punkt in eine beliebige Richtung gezeichnet wird und anschließend die Stellen überprüft werden, an denen ein Segment der Form den Strahl schneidet. Beginnen Sie mit dem Wert 0 (null), und addieren Sie für jede Stelle, an der ein Segment den Strahl von links nach rechts schneidet, den Wert 1. Subtrahieren Sie für jede Stelle, an der ein Pfadsegment den Strahl von rechts nach links schneidet, den Wert 1. Wenn das Ergebnis nach dem Zählen der Überschneidungen 0 (null) ist, liegt der Punkt außerhalb des Pfads. Andernfalls liegt er innerhalb des Pfads.

<Path Stroke="Black" StrokeThickness="1" Fill="#CCCCFF">
  <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>

Ausgehend vom oben genannten Beispiel ergibt ein Wert von Nonzero für FillRule die folgende Abbildung:

Bildschirmabbildung: FillRule-Wert NonZero

Wie Sie sehen können, sind alle Ringe ausgefüllt. Dies kommt daher, dass alle Segmente in die gleiche Richtung verlaufen und deshalb ein Strahl, der von einem beliebigen Punkt aus gezeichnet wird, ein oder mehrere Segmente kreuzt, sodass die Summe der Berührungen nicht gleich 0 (null) ist. So stellen zum Beispiel die roten Pfeile in der unten aufgeführten Abbildung die Richtung dar, in die die Segmente gezeichnet werden, und die weißen Pfeile stellen einen zufälligen Strahl dar, der von einem Punkt im innersten Ring aus verläuft. Ausgehend vom Wert 0 (null) wird für jedes Segment, das der Strahl kreuzt, der Wert 1 addiert, da das Segment den Strahl von links nach rechts kreuzt.

Diagramm: FillRule-Eigenschaftenwert entspricht NonZero

Um das Verhalten der Nonzero-Regel noch besser zu verdeutlichen, ist eine komplexere Form mit Segmenten, die in verschiedene Richtungen verlaufen, erforderlich. Mit dem unten aufgeführten XAML-Code wird eine ähnliche Form wie im vorhergehenden Beispiel erstellt, mit der Ausnahme, dass sie mit einer PathGeometry statt einer EllipseGeometry erstellt wird, wodurch vier konzentrische Bogen statt vollständig geschlossene konzentrische Kreise erstellt werden.

<Path Stroke="Black" StrokeThickness="1" Fill="#CCCCFF">
  <Path.Data>
    <GeometryGroup FillRule="NonZero">
      <PathGeometry>
        <PathGeometry.Figures>

          <!-- Inner Ring -->
          <PathFigure StartPoint="10,120">
            <PathFigure.Segments>
              <PathSegmentCollection>
                <ArcSegment Size="50,50" IsLargeArc="True" SweepDirection="CounterClockwise" Point="25,120" />
              </PathSegmentCollection>
            </PathFigure.Segments>
          </PathFigure>

          <!-- Second Ring -->
          <PathFigure StartPoint="10,100">
            <PathFigure.Segments>
              <PathSegmentCollection>
                <ArcSegment Size="70,70" IsLargeArc="True" SweepDirection="CounterClockwise" Point="25,100" />
              </PathSegmentCollection>
            </PathFigure.Segments>
          </PathFigure>

          <!-- Third Ring (Not part of path) -->
          <PathFigure StartPoint="10,70">
            <PathFigure.Segments>
              <PathSegmentCollection>
                <ArcSegment Size="100,100" IsLargeArc="True" SweepDirection="CounterClockwise" Point="25,70" />
              </PathSegmentCollection>
            </PathFigure.Segments>
          </PathFigure>

          <!-- Outer Ring -->
          <PathFigure StartPoint="10,300">
            <PathFigure.Segments>
              <ArcSegment Size="130,130" IsLargeArc="True" SweepDirection="Clockwise" Point="25,300" />
            </PathFigure.Segments>
          </PathFigure>
        </PathGeometry.Figures>
      </PathGeometry>
    </GeometryGroup>
  </Path.Data>
</Path>

In der folgenden Abbildung wird die im vorherigen Beispiel erstellte Form dargestellt.

Bildschirmabbildung: FillRule-Eigenschaftenwert NonZero

Beachten Sie, dass der dritte Bogen von der Mitte nicht ausgefüllt ist. In der Abbildung unten wird deutlich, warum dies so ist. In der Abbildung stellen die roten Pfeile die Richtung dar, in der die Segmente gezeichnet werden. Die beiden weißen Pfeile stellen zwei zufällige Strahlen dar, die von einem Punkt im nicht ausgefüllten Bereich ausgehen. Wie aus der Abbildung ersichtlich, ist die Summe der Werte eines bestimmten Strahls, der die Segmente in seinem Pfad schneidet, gleich 0 (null). Wie oben bereits definiert, bedeutet eine Summe 0 (null), dass der Punkt nicht Teil der Geometrie ist (kein Teil der Füllung), während eine Summe, die nicht 0 (null) ist, einschließlich eines negativen Werts, Teil der Geometrie ist.

Diagramm: FillRule-Eigenschaftenwert NonZero

Hinweis: Bei der FillRule wird davon ausgegangen, dass alle Formen geschlossen sind. Wenn eine Lücke in einem Segment vorhanden ist, zeichnen Sie eine gedachte Linie, um sie zu schließen. Im oben aufgeführten Beispiel weisen die Ringe kleine Lücken auf. Ausgehend hiervon wird möglicherweise erwartet, dass ein Strahl durch die Lücke verläuft und ein anderes Ergebnis zurückgibt als ein Strahl, der in eine andere Richtung verläuft. Unten ist eine vergrößerte Abbildung einer dieser Lücken und des "gedachten" Segments dargestellt (Segment, das gezeichnet wird, um die FillRule anwenden zu können), das die Lücke schließt.

Diagramm: Für FillRule sind die Segmente immer geschlossen

Siehe auch

Aufgaben

Gewusst wie: Erstellen einer zusammengesetzten Form

Konzepte

Übersicht über die Geometrie