Compartilhar via


Regras de preenchimento

Browse sample. Navegue pelo exemplo

Várias classes de Formas de UI de Aplicativo Multiplataforma do .NET (.NET MAUI) têm FillRule propriedades, do tipo FillRule. Elas incluem Polygon, Polyline e GeometryGroup.

A FillRule enumeração define EvenOdd e Nonzero membros. Cada membro representa uma regra diferente para determinar se um ponto está na região de preenchimento de uma forma.

Importante

Todas as formas são consideradas fechadas para fins de regras de preenchimento.

EvenOdd

A EvenOdd regra de preenchimento desenha um raio do ponto ao infinito em qualquer direção e conta o número de segmentos dentro da forma que o raio atravessa. Se esse número é ímpar, o ponto está dentro. Se esse número for par, o ponto está fora.

O exemplo XAML a seguir cria e renderiza uma forma composta, com o FillRule padrão para EvenOdd:

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

Neste exemplo, uma forma composta composta por uma série de anéis concêntricos é exibida:

Composite shape with EvenOdd fill rule.

Na forma composta, observe que o centro e o terceiro anéis não estão preenchidos. Isso ocorre porque um raio desenhado de qualquer ponto dentro de qualquer um desses dois anéis passa por um número par de segmentos:

Annotated composite shape with EvenOdd fill rule.

Na imagem acima, os círculos vermelhos representam pontos, e as linhas representam raios arbitrários. Para o ponto superior, os dois raios arbitrários passam cada um por um número par de segmentos de linha. Portanto, o anel em que o ponto está não está preenchido. Para o ponto inferior, os dois raios arbitrários passam cada um por um número ímpar de segmentos de linha. Portanto, o anel em que o ponto está é preenchido.

Diferentes de zero

A Nonzero regra de preenchimento desenha um raio do ponto ao infinito em qualquer direção e, em seguida, examina os lugares onde um segmento da forma cruza o raio. Começando com uma contagem de zero, a contagem é incrementada cada vez que um segmento cruza o raio da esquerda para a direita e diminuída cada vez que um segmento cruza o raio da direita para a esquerda. Depois de contar os cruzamentos, se o resultado for zero, o ponto está fora do polígono. Caso contrário, está dentro.

O exemplo XAML a seguir cria e renderiza uma forma composta, com o FillRule conjunto como Nonzero:

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

Neste exemplo, uma forma composta composta por uma série de anéis concêntricos é exibida:

Diagram shows four concentric circles, all filled in.

Na forma composta, observe que todos os anéis estão preenchidos. Isso ocorre porque todos os segmentos estão correndo na mesma direção, e assim um raio desenhado de qualquer ponto cruzará um ou mais segmentos e a soma dos cruzamentos não será igual a zero:

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

Na imagem acima, as setas vermelhas representam a direção em que os segmentos são desenhados, e a seta preta representa um raio arbitrário que corre de um ponto no anel mais interno. Iniciando com um valor de zero, para cada segmento que o raio cruza, um valor de um é adicionado, já que o segmento cruza o raio da esquerda para a direita.

Uma forma mais complexa Nonzero com segmentos correndo em direções diferentes é necessária para demonstrar melhor o comportamento da regra de preenchimento. O exemplo XAML a seguir cria uma forma semelhante ao exemplo anterior, exceto que ele é criado com um em vez de um PathGeometryEllipseGeometry:

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

Neste exemplo, uma série de segmentos de arco são desenhados, que não são fechados:

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

Na imagem acima, o terceiro arco do centro não é preenchido. Isso ocorre porque a soma dos valores de um determinado raio cruzando os segmentos em seu caminho é zero:

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

Na imagem acima, o círculo vermelho representa um ponto, as linhas pretas representam raios arbitrários que se movem do ponto na região não preenchida e as setas vermelhas representam a direção em que os segmentos são desenhados. Como pode ser visto, a soma dos valores dos raios que cruzam os segmentos é zero:

  • O raio arbitrário que viaja diagonalmente para a direita cruza dois segmentos que correm em direções diferentes. Portanto, os segmentos se anulam dando um valor de zero.
  • O raio arbitrário que viaja diagonalmente para a esquerda cruza um total de seis segmentos. No entanto, as travessias se anulam para que zero seja a soma final.

Uma soma de zero resulta no anel não ser preenchido.