Aracılığıyla paylaş


Nasıl yapılır: Bileşik Şeklin Dolgusunu Denetleme

FillRule veya PathGeometryöğesinin GeometryGroup özelliği, bileşik şeklin belirli bir noktanın geometrinin parçası olup olmadığını belirlemek için kullandığı bir "kural" belirtir. için FillRuleiki olası değer vardır: EvenOdd ve Nonzero. Aşağıdaki bölümlerde bu iki kuralın nasıl kullanılacağı açıklanmaktadır.

EvenOdd: Bu kural, bir noktadan herhangi bir yönde sonsuzluğa bir ışın çizerek ve işının geçtiği şekil içindeki yol kesimlerinin sayısını sayarak bir noktanın dolgu bölgesinde olup olmadığını belirler. Bu sayı tekse, nokta içindedir; hatta, önemli olan dışarıdadır.

Örneğin, aşağıdaki XAML, değerine ayarlanmış EvenOddbir dizi eşmerkezli halkadan (hedef) oluşan bileşik bir FillRule şekil oluşturur.

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

Aşağıdaki çizimde, önceki örnekte oluşturulan şekil gösterilmektedir.

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

Önceki çizimde, orta ve üçüncü halkanın doldurulmadığını göreceksiniz. Bunun nedeni, bu iki halkanın herhangi bir noktasından çekilen bir ışının çift sayıda segmentten geçmesidir. Aşağıdaki çizime bakın:

Diagram showing the EvenOdd rays drawn in the circle.

Sıfır olmayan: Bu kural, bir noktadan herhangi bir yönde sonsuzluğa bir ışın çizerek ve ardından şeklin bir kesiminin ışını geçtiği yerleri inceleyerek bir noktanın yolun dolgu bölgesinde olup olmadığını belirler. Sıfır sayısıyla başlayarak, bir Segment soldan sağa her ışını geçtiğinde bir tane ekleyin ve bir yol kesimi ışını sağdan sola doğru her geçtiğinde bir tane çıkarın. Geçişleri saydıktan sonra, sonuç sıfırsa nokta yolun dışındadır. Aksi takdirde, içindedir.

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

Önceki örneği kullanarak, değerinin NonzeroFillRule değeri sonuç olarak aşağıdaki çizimi verir:

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

Gördüğünüz gibi, tüm halkalar dolu. Bunun nedeni, tüm segmentlerin aynı yönde çalışmasıdır ve bu nedenle herhangi bir noktadan çekilen bir ışın bir veya daha fazla segmenti geçer ve kesişimlerin toplamı sıfıra eşit olmaz. Örneğin, aşağıdaki çizimde kırmızı oklar kesimlerin çizildiği yönü, beyaz ok ise en iç halkadaki bir noktadan çalıştırılan rastgele bir ışını temsil eder. Sıfır değerinden başlayarak, ışının kesiştiği her segment için bir değer eklenir çünkü segment, ışını soldan sağa doğru geçer.

Diagram showing the FillRule property value equal to Nonzero.

Kuralın Nonzero davranışını daha iyi göstermek için farklı yönlerde çalışan segmentlerle daha karmaşık bir şekil gereklidir. Aşağıdaki XAML kodu, önceki örneğe benzer bir şekil oluşturur, ancak daha sonra tam olarak kapatılan eşmerkezli daireler yerine dört eşmerkezli yay oluşturan bir PathGeometryEllipseGeometry ile oluşturulur.

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

Aşağıdaki çizimde, önceki örnekte oluşturulan şekil gösterilmektedir.

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

Merkezden gelen üçüncü yay doldurulmadığından dikkat edin. Aşağıdaki çizimde bunun nedeni gösterilmektedir. Çizimde, kırmızı oklar kesimlerin çizildiği yönü temsil eder. İki beyaz ok, "doldurulmayan" bölgedeki bir noktadan çıkan iki rastgele ışını temsil eder. Çizimden de anlaşılacağı gibi, yolundaki segmentleri geçen belirli bir ışından alınan değerlerin toplamı sıfırdır. Yukarıda tanımlandığı gibi, sıfır toplamı, noktanın geometrinin parçası olmadığı (dolgunun parçası olmadığı), negatif değer de dahil olmak üzere sıfır olmayan bir toplamın geometrinin parçası olduğu anlamına gelir.

Diagram showing arbitrary rays crossing segments.

Dekont

amacıyla FillRule, tüm şekiller kapalı olarak kabul edilir. Bir segmentte boşluk varsa, kapatmak için hayali bir çizgi çizin. Yukarıdaki örnekte halkalarda küçük boşluklar vardır. Bunu göz önünde bulundurarak, boşluktan geçen bir ışının farklı bir sonuç vermesini ve ardından başka bir yönde çalışan bir ışın olmasını bekleyebilirsiniz. Aşağıda, bu boşluklardan birinin ve onu kapatan "sanal segmentin" (uygulama FillRuleamacıyla çizilen segment) büyütülmüş bir çizimi yer alır.

Diagram showing FillRule segments that are always closed.

Örnek

Ayrıca bkz.