操作說明:控制複合圖案的填色
FillRule或 PathGeometry 的 GeometryGroup 屬性會指定複合圖形用來判斷指定點是否為幾何的一部分的「規則」。 和 有兩個可能的值 FillRule : EvenOdd 和 Nonzero 。 以下各節將說明如何使用這兩個規則。
EvenOdd:這個規則會從某個點朝任意方向繪製無限遠的光線,並且計算給定圖案中與光線相交的路徑線段數目,以判斷該點是否在填滿區域中。 如果這個數字是奇數,該點即是在區域內;如為偶數,該點即在區域外。
例如,下列 XAML 會建立由一系列同心環形 (target) 組成的複合圖形,並將 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>
下圖顯示上一個範例中所建立的圖案。
在上圖中,請注意中心和第三個環形未填滿。 這是因為從這兩個環形中的任何點所繪製的光線,會通過偶數數目的線段。 請參閱下圖:
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>
使用上述範例時,的值 NonzeroFillRule 會提供下列圖例,因此:
如您所見,所有環形都會填滿。 這是因為所有的線段都是相同的方向,因此從任何點所繪製的光線會與一或多個線段交會,而相交的總和不等於零。 例如,在下圖中,紅色箭號代表繪製線段的方向,而白色箭號代表從最內環中點執行的任意光線。 起始值為零,針對光線交會的每個線段,值會增加 1,因為線段由左至右與光線交會。
為了更清楚地示範規則的行為 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 用它而繪製的區段)。
範例
另請參閱
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應