Bagikan melalui


Cara: Mengontrol Isian Bentuk Komposit

Properti FillRule dari GeometryGroup atau PathGeometry, menentukan "aturan" yang digunakan bentuk komposit untuk menentukan apakah titik tertentu adalah bagian dari geometri. Ada dua nilai yang mungkin untuk FillRule: EvenOdd dan Nonzero. Bagian berikut akan menjelaskan cara menggunakan dua aturan ini.

EvenOdd: Aturan ini menentukan apakah titik berada di wilayah pengisian dengan menggambar sinar dari titik tersebut ke tak terbatas ke arah mana pun dan menghitung jumlah segmen jalur dalam bentuk tertentu yang disilangkan sinar. Jika angka ini ganjil, titiknya ada di dalam; jika bahkan, intinya ada di luar.

Misalnya, XAML di bawah ini membuat bentuk komposit yang terdiri dari serangkaian cincin konsentris (target) dengan diatur FillRule ke 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>

Ilustrasi berikut menunjukkan bentuk yang dibuat dalam contoh sebelumnya.

A circle made up of a series concentric rings with alternating colors.

Dalam ilustrasi sebelumnya, perhatikan bahwa cincin tengah dan ketiga tidak terisi. Ini karena sinar yang diambil dari titik mana pun dalam salah satu dari dua cincin tersebut melewati sejumlah segmen yang merata. Lihat ilustrasi berikut:

Diagram showing the EvenOdd rays drawn in the circle.

NonZero: Aturan ini menentukan apakah titik berada di wilayah pengisian jalur dengan menggambar sinar dari titik tersebut ke tak terbatas ke arah mana pun dan kemudian memeriksa tempat-tempat di mana segmen bentuk melintasi sinar. Dimulai dengan hitungan nol, tambahkan satu setiap kali Segmen melewati sinar dari kiri ke kanan dan mengurangi satu setiap kali segmen jalur melewati sinar dari kanan ke kiri. Setelah menghitung persimpangan, jika hasilnya nol maka titik berada di luar jalur. Jika tidak, itu ada di dalam.

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

Dengan menggunakan contoh sebelumnya, nilai Nonzero untuk FillRule memberikan ilustrasi berikut sebagai hasilnya:

A circle made up of a series concentric rings all filled with the same color.

Seperti yang kau lihat, semua cincin terisi. Ini karena semua segmen berjalan ke arah yang sama dan sehingga sinar yang ditarik dari titik mana pun akan melintasi satu atau beberapa segmen dan jumlah persimpangan tidak akan sama dengan nol. Misalnya, dalam ilustrasi berikut, panah merah mewakili arah segmen digambar dan panah putih mewakili sinar arbitrer yang berjalan dari titik di cincin terdalam. Dimulai dengan nilai nol, untuk setiap segmen yang disilangkan sinar, nilai satu ditambahkan karena segmen melewati sinar dari kiri ke kanan.

Diagram showing the FillRule property value equal to Nonzero.

Untuk lebih menunjukkan perilaku Nonzero aturan bentuk yang lebih kompleks dengan segmen yang berjalan ke arah yang berbeda diperlukan. Kode XAML di bawah ini membuat bentuk yang sama dengan contoh sebelumnya kecuali dibuat dengan PathGeometry agak kemudian yang EllipseGeometry membuat empat busur konsentris daripada lingkaran konsentris yang sepenuhnya tertutup.

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

Ilustrasi berikut menunjukkan bentuk yang dibuat dalam contoh sebelumnya.

A circle made up of a series concentric rings with alternating colors with the third arc not filled.

Perhatikan bahwa busur ketiga dari tengah tidak terisi. Ilustrasi berikut menunjukkan mengapa hal ini. Dalam ilustrasi, panah merah mewakili arah segmen digambar. Dua panah putih mewakili dua sinar arbitrer yang bergerak keluar dari titik di wilayah "tidak terisi". Seperti yang dapat dilihat dari ilustrasi, jumlah nilai dari sinar tertentu yang melintasi segmen di jalurnya adalah nol. Seperti yang didefinisikan di atas, jumlah nol berarti bahwa titik tersebut bukan bagian dari geometri (bukan bagian dari isi) sementara jumlah yang bukan nol, termasuk nilai negatif, adalah bagian dari geometri.

Diagram showing arbitrary rays crossing segments.

Catatan

Untuk tujuan FillRule, semua bentuk dianggap tertutup. Jika ada celah dalam segmen, gambar garis imajiner untuk menutupnya. Dalam contoh di atas, ada celah kecil di cincin. Mengingat ini, seseorang mungkin mengharapkan sinar yang berjalan melalui celah untuk memberikan hasil yang berbeda kemudian sinar berjalan ke arah lain. Di bawah ini adalah ilustrasi yang diperbesar dari salah satu celah ini dan "segmen imajiner" (segmen yang digambar untuk tujuan menerapkan FillRule) yang menutupnya.

Diagram showing FillRule segments that are always closed.

Contoh

Baca juga