共用方式為


操作說明:控制複合圖案的填色

GeometryGroupPathGeometryFillRule 屬性會指定一個「規則」,以便組合圖形用來判斷指定點是否為幾何的一部分。 FillRule 有兩個可能的值:EvenOddNonzero。 以下各節將說明如何使用這兩個規則。

EvenOdd:這個規則會從某個點朝任意方向繪製無限遠的光線,並且計算給定圖案中與光線相交的路徑線段數目,以判斷該點是否在填滿區域中。 如果這個數字是奇數,該點即是在區域內;如為偶數,該點即在區域外。

例如,下面的 XAML 會建立一個由一系列同心環組成的組合圖形 (目標),並將 FillRule 設定為 EvenOdd

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

下圖顯示上一個範例中所建立的圖案。

由一系列色彩交替的同心環組成的圓形。

在上圖中,請注意中間和第三個環形不會填滿。 這是因為從這兩個環形中的任何點所繪製的光線,會通過偶數數目的線段。 請參閱下圖:

此圖表顯示圓形中繪製的 EvenOdd 光線。

NonZero:這個規則會從某個點朝任意方向繪製無限遠的光線,然後檢查圖案線段與光線相交的位置,以判斷該點是否在路徑填滿區域內。 從零開始計算,路徑線段每次從左到右與光線交會就加一,每次從右到左與光線交會就減一。 計算交會後,如果結果為零,則點即在路徑外。 否則就在路徑內。

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

使用上一個範例,FillRuleNonzero 值結果如下圖所示:

由一系列全部以同色填滿的同心環組成的圓形。

如您所見,所有環形都會填滿。 這是因為所有的線段都是相同的方向,因此從任何點所繪製的光線會與一或多個線段交會,而相交的總和不等於零。 例如,在下圖中,紅色箭頭代表繪製線段的方向,而白色箭頭代表從最內側環形中的點射出的任意光線。 起始值為零,針對光線交會的每個線段,值會增加 1,因為線段由左至右與光線交會。

此圖表顯示 FillRule 屬性值等於 NonZero。

若要進一步示範 Nonzero 規則的行為,則需要一個更為複雜的圖形,包含不同方向的線段。 下面的 XAML 程式碼會建立一個類似於上一個範例的圖形,但此圖形是以 PathGeometry 而非 EllipseGeometry 所建立,這會建立四個同心弧而非完全封閉的同心圓。

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

下圖顯示上一個範例中所建立的圖案。

由一系列色彩交替的同心環組成的圓形,其中第三個弧形不會填滿。

請注意,由中心開始的第三個弧形不會填滿。 下圖說明為何如此。 在圖中,紅色箭頭代表繪製線段的方向。 兩個白色箭頭代表兩個從「未填滿」區域中的點射出的任意光線。 從圖中可以看出,交會線段的指定光線,在其路徑中之值的總和為零。 如上面所定義,總和為零表示該點不屬於幾何的一部分 (並非填滿的一部分),而「非」零的總和 (包含負值) 則屬於幾何的一部分。

此圖表顯示任意光線與線段交叉。

注意

基於 FillRule 的目的,所有圖形都視為封閉。 如果線段中有間隙,請繪製虛構線段將它封閉。 在上面的範例中,環形中有小型的間隙。 有鑑於此,我們可能會預期通過間隙射出的光線,會提供與另一個方向的光線不同的結果。 以下是其中一個間隙以及「虛構線段」(為了套用 FillRule 所繪製的線段) 放大後的圖例。

此圖表顯示一律封閉的 FillRule 線段。

範例

另請參閱