L' ultima forma di base è il Polygon. Grazie a questa primitiva possiamo realizzare qualsiasi poligono formato da un insieme di linee definite da un elenco di punti (proprietà Points). L'elenco dei punti in XAML viene definito con una particolare sintassi espressa come "x1,y1 x2,y2"
, anche in questo caso il valore letterale sarà trasformato da un opportuno TypeConverter
. Come di consueto vediamo alcuni esempi.
<StackPanel x:Name="LayoutRoot" Background="Azure"> <Polygon Margin="10" Fill="Orange" Stroke="Black" StrokeThickness="10" Points="20,20 100,100 100,10" /> <Polygon Margin="10" Fill="Yellow" Stroke="Black" StrokeThickness="10" Points="20,20 100,100 200,10 300,100" /> </StackPanel>
L'elemento Polygon
genera sempre una figura chiusa disegnando automaticamente una linea finale che unisce l'ultimo punto con quello di origine.
La particolarità di questa primitiva grafica sta nella strategia di riempimento, perché per forme semplici è facile capire qual è l'area interna, quando invece la forma è complessa, con linee che si incrociano, diventa meno ovvio capire quali sono le parti da riempire e quali no. Polygon
mette a disposizione due tipi di strategie, definite dalla proprietà FillRule: EvenOdd
e NonZero
. Come esempio prendiamo un poligono che rappresenta una stella come nell'immagine seguente.
Nel caso in cui FillRule sia impostata a EvenOdd (che è il valore predefinito), al fine di decidere se compilare una regione, Silverlight conta il numero di linee che devono essere attraversate per uscire della forma, se questo numero è dispari, la regione sarà riempita, altrimenti no.
Nel caso della stella, come vediamo dalla figura, partendo dal punto zero il numero delle righe da attraversate per uscire della forma è pari, quindi la parte centrale non verrà riempita, mentre, partendo dal punto uno il numero delle righe è dispari, quindi quell'area sarà riempita.
Diversamente, se la proprietà è impostata a NonZero, Silverlight utilizza un algoritmo più complesso, basato sempre sul sistema di conteggio delle linee, ma tenendo di conto anche della direzione. Se il numero di linee di che vanno in una direzione (ad esempio, da sinistra a destra) è pari al numero di quelle che vanno nella direzione opposta, l'area non sarà riempita. Se la differenza tra le due somme non è pari a zero, l'area sarà riempita.
Prendendo come esempio la stella, in questo caso lo spazio al centro sarà riempito, poiché per raggiungere l'esterno della figura vengono attraversate due linee disegnate nella solita direzione (da sinistra a destra).
Vediamo nella pratica la differenza fra le due strategie.
<StackPanel Orientation="Horizontal"> <Polygon Margin="10" Stroke="Black" StrokeThickness="10" Fill="Purple" FillRule="EvenOdd" Points="35,200 83,70 125,200 15,125 150,125"> </Polygon> <Polygon Margin="10" Stroke="Black" StrokeThickness="10" Fill="Purple" FillRule="Nonzero" Points="35,200 83,70 125,200 15,125 150,125"> </Polygon> </StackPanel>