Condividi tramite


Regole di riempimento

Browse sample. Esplorare l'esempio

Diverse classi dell'interfaccia utente dell'app multipiattaforma .NET (.NET MAUI) hanno FillRule proprietà, di tipo FillRule. Questi includono Polygon, Polylinee GeometryGroup.

L'enumerazione FillRule definisce EvenOdd i membri e Nonzero . Ogni membro rappresenta una regola diversa per determinare se un punto si trova nell'area di riempimento di una forma.

Importante

Tutte le forme vengono considerate chiuse ai fini delle regole di riempimento.

EvenOdd

La EvenOdd regola di riempimento disegna un raggio dal punto all'infinito in qualsiasi direzione e conta il numero di segmenti all'interno della forma attraversata dal raggio. Se questo numero è dispari, il punto si trova all'interno. Se questo numero è pari, il punto è esterno.

L'esempio XAML seguente crea ed esegue il rendering di una forma composita, con l'impostazione FillRule predefinita :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>

In questo esempio viene visualizzata una forma composita costituita da una serie di anelli concentrici:

Composite shape with EvenOdd fill rule.

Nella forma composita si noti che il centro e il terzo anello non vengono riempiti. Ciò è dovuto al fatto che un raggio disegnato da qualsiasi punto all'interno di uno di questi due anelli passa attraverso un numero pari di segmenti:

Annotated composite shape with EvenOdd fill rule.

Nell'immagine precedente, i cerchi rossi rappresentano punti e le linee rappresentano raggi arbitrari. Per il punto superiore, i due raggi arbitrari passano ognuno attraverso un numero pari di segmenti di linea. Pertanto, l'anello in cui si trova il punto non è riempito. Per il punto inferiore, i due raggi arbitrari passano ognuno attraverso un numero dispari di segmenti di linea. Pertanto, l'anello in cui si trova il punto è riempito.

Diverso da zero

La Nonzero regola di riempimento disegna un raggio dal punto all'infinito in qualsiasi direzione e quindi esamina i punti in cui un segmento della forma attraversa il raggio. A partire da un conteggio pari a zero, il conteggio viene incrementato ogni volta che un segmento attraversa il raggio da sinistra a destra e decrementato ogni volta che un segmento attraversa il raggio da destra a sinistra. Dopo aver conteggiato gli incroci, se il risultato è zero, il punto si trova all'esterno del poligono. In caso contrario, è dentro.

L'esempio XAML seguente crea ed esegue il rendering di una forma composita, con l'oggetto FillRule impostato su 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>

In questo esempio viene visualizzata una forma composita costituita da una serie di anelli concentrici:

Diagram shows four concentric circles, all filled in.

Nella forma composita si noti che tutti gli anelli vengono riempiti. Ciò è dovuto al fatto che tutti i segmenti sono in esecuzione nella stessa direzione e quindi un raggio disegnato da qualsiasi punto attraverserà uno o più segmenti e la somma degli incroci non sarà uguale a zero:

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

Nell'immagine sopra le frecce rosse rappresenta la direzione in cui vengono disegnati i segmenti e la freccia nera rappresenta un raggio arbitrario in esecuzione da un punto nell'anello più interno. A partire da un valore pari a zero, per ogni segmento intersecato dal raggio viene aggiunto un valore di uno, poiché il segmento interseca il raggio da sinistra a destra.

Per illustrare meglio il comportamento della Nonzero regola di riempimento, è necessaria una forma più complessa con segmenti in esecuzione in diverse direzioni. L'esempio XAML seguente crea una forma simile all'esempio precedente, ad eccezione del fatto che viene creata con un PathGeometry oggetto anziché con :EllipseGeometry

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

In questo esempio viene disegnata una serie di segmenti di arco, che non sono chiusi:

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

Nell'immagine precedente, il terzo arco dal centro non viene riempito. Ciò è dovuto al fatto che la somma dei valori di un determinato raggio che attraversa i segmenti nel percorso è 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.

Nell'immagine precedente, il cerchio rosso rappresenta un punto, le linee nere rappresentano raggi arbitrari che si spostano dal punto nell'area non riempita e le frecce rosse rappresentano la direzione in cui vengono disegnati i segmenti. Come si può notare, la somma dei valori dei raggi che attraversano i segmenti è zero:

  • Il raggio arbitrario che attraversa diagonalmente destra attraversa due segmenti che vengono eseguiti in direzioni diverse. Pertanto, i segmenti annullano l'uno dall'altro dando un valore pari a zero.
  • Il raggio arbitrario che viaggia diagonalmente a sinistra attraversa un totale di sei segmenti. Tuttavia, gli incroci si annullano l'uno dall'altro in modo che zero sia la somma finale.

Una somma pari a zero restituisce che l'anello non viene riempito.