Condividi tramite


Xamarin.Forms Forme: Regole di riempimento

Diverse Xamarin.Forms classi Shapes 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:

Forma composita con regola di riempimento EvenOdd

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:

Forma composita annotata con regola di riempimento EvenOdd

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:

Il diagramma mostra quattro cerchi concentrici, tutti compilati.

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:

Il diagramma mostra i cerchi del diagramma precedente con frecce direzionali e un raggio annotato con + 1 per ogni cerchio incrociato.

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:

Il diagramma mostra quattro cerchi concentrici, con il più esterno e il terzo dal più esterno riempito.

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:

Il diagramma mostra i cerchi del diagramma precedente con frecce direzionali e due raggi annotati con + 1 o - 1 per ogni cerchio incrociato.

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.