Xamarin.Forms 図形: 塗りつぶしルール

Download Sample サンプルをダウンロードします

いくつかの Xamarin.Forms Shapes クラスには、型FillRuleのプロパティがありますFillRule。 これらには、 PolygonPolyline 、および GeometryGroup が含まれます。

列挙型の FillRule 定義 EvenOddNonzero メンバー。 各メンバーは、図形の塗りつぶし領域にポイントがあるかどうかを判断するための異なる規則を表します。

重要

すべての図形は、塗りつぶしルールの目的で閉じていると見なされます。

Evenodd

塗りつぶしルールは EvenOdd 、ポイントから無限大までの光線を任意の方向に描画し、光線が交差する図形内のセグメントの数をカウントします。 この数値が奇数の場合、ポイントは内側にあります。 この数値が偶数の場合、ポイントは外側にあります。

次の XAML の例では、複合図形を作成してレンダリングします。既定値EvenOddFillRule次のとおりです。

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

この例では、一連の同心円リングで構成される複合図形が表示されます。

Composite shape with EvenOdd fill rule

複合図形では、中心と 3 番目のリングが塗りつぶされていないことに注意してください。 これは、これら 2 つのリングのいずれかのポイントから描画された光線が、偶数のセグメントを通過するためです。

Annotated composite shape with EvenOdd fill rule

上の図では、赤い円は点を表し、線は任意の光線を表しています。 上の点の場合、2 つの任意の光線はそれぞれ偶数の線分を通過します。 したがって、ポイントが入っているリングは塗りつぶされません。 下の点の場合、2 つの任意の光線はそれぞれ奇数の線分を通過します。 したがって、点が入るリングは満たされる。

0 以外

塗りつぶしルールは Nonzero 、ポイントから無限大までの光線を任意の方向に描画し、図形のセグメントが光線と交差する場所を調べます。 カウントが 0 から始まると、セグメントが左から右に光線を通過するたびにカウントがインクリメントされ、セグメントが右から左に光線を通過するたびにデクリメントされます。 交差をカウントした後、結果が 0 の場合、ポイントは多角形の外側にあります。 それ以外の場合は内部です。

次の XAML の例では、次のように設定Nonzeroされた複合図形をFillRule作成してレンダリングします。

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

この例では、一連の同心円リングで構成される複合図形が表示されます。

Diagram shows four concentric circles, all filled in.

複合図形では、すべてのリングが塗りつぶされていることに注意してください。 これは、すべてのセグメントが同じ方向に実行されているため、任意の点から描画された光線が 1 つ以上のセグメントを通過し、交差の合計が 0 にならないためです。

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

上の画像では、赤い矢印はセグメントが描画される方向を表し、黒い矢印は最も内側のリング内の点から実行される任意の光線を表します。 値 0 から開始し、セグメントは左から右に射線と交わるため、射線が交わるセグメントごとに値 1 が加算されます。

塗りつぶしルールの動作をより適切に示すには、セグメントが異なる方向で実行される、より複雑な図形が Nonzero 必要です。 次の XAML の例では、前の例と同様の図形が作成されます。ただし、次のような図形をEllipseGeometry作成PathGeometryします。ただし、

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

この例では、閉じていない一連の円弧セグメントが描画されます。

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

上の図では、中心からの 3 番目の円弧は塗りつぶされていません。 これは、パス内のセグメントを交差する特定のレイの値の合計が 0 であるためです。

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

上の図では、赤い円は点を表し、黒い線は塗りつぶされていない領域の点から外に移動する任意の光線を表し、赤い矢印はセグメントが描画される方向を表しています。 見てわかるように、セグメントを横切る光線の値の合計は 0 です。

  • 斜めに右に移動する任意の光線は、異なる方向に実行される 2 つのセグメントを横切ります。 したがって、セグメントは互いに取り消し合い、値を 0 に設定します。
  • 斜めに左に進む任意の光線は、合計 6 つのセグメントを通過します。 ただし、交差は互いに取り消され、0 が最終的な合計になります。

合計が 0 の場合、リングは塗りつぶされません。