Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
La grafica dell'interfaccia utente dell'app multipiattaforma .NET (.NET MAUI) supporta trasformazioni grafiche tradizionali, implementate come metodi nell'oggetto ICanvas . Matematicamente, le trasformazioni modificano le coordinate e le dimensioni specificate nei ICanvas metodi di disegno, quando viene eseguito il rendering degli oggetti grafici.
Sono supportate le trasformazioni seguenti:
- Traduci per spostare le coordinate da una posizione a un'altra.
- Scala per aumentare o ridurre le coordinate e le dimensioni.
- Ruotare per ruotare le coordinate intorno a un punto.
- Asimmetria per spostare le coordinate orizzontalmente o verticalmente.
Queste trasformazioni sono note come trasformazioni affine . Le trasformazioni affine mantengono sempre linee parallele e non causano mai una coordinata o una dimensione diventano infinite.
La classe MAUI VisualElement .NET supporta anche le proprietà di trasformazione seguenti: TranslationX, TranslationY, ScaleRotation, RotationX, e RotationY. Esistono tuttavia diverse differenze tra Microsoft.Maui.Graphics trasformazioni e VisualElement trasformazioni:
- Microsoft.Maui.Graphics le trasformazioni sono metodi, mentre VisualElement le trasformazioni sono proprietà. Pertanto, Microsoft.Maui.Graphics le trasformazioni eseguono un'operazione mentre VisualElement le trasformazioni impostano uno stato. Microsoft.Maui.Graphics le trasformazioni si applicano agli oggetti grafici disegnati successivamente, ma non agli oggetti grafici disegnati prima dell'applicazione della trasformazione. Al contrario, una VisualElement trasformazione si applica a un elemento di cui è stato eseguito il rendering in precedenza non appena viene impostata la proprietà . Pertanto, Microsoft.Maui.Graphics le trasformazioni sono cumulative come vengono chiamati metodi, mentre VisualElement le trasformazioni vengono sostituite quando la proprietà viene impostata con un altro valore.
- Microsoft.Maui.Graphics le trasformazioni vengono applicate all'oggetto ICanvas , mentre VisualElement le trasformazioni vengono applicate a un VisualElement oggetto derivato.
- Microsoft.Maui.Graphics le trasformazioni sono relative all'angolo superiore sinistro di ICanvas, mentre VisualElement le trasformazioni sono relative all'angolo superiore sinistro dell'oggetto VisualElement a cui vengono applicate.
Tradurre la trasformazione
La trasformazione trasla sposta gli oggetti grafici nelle direzioni orizzontali e verticali. La traduzione può essere considerata non necessaria perché lo stesso risultato può essere eseguito modificando le coordinate del metodo di disegno in uso. Tuttavia, quando si visualizza un percorso, tutte le coordinate vengono incapsulate nel percorso e pertanto è spesso più facile applicare una trasformazione di conversione per spostare l'intero percorso.
Il Translate metodo richiede x
e y
argomenti di tipo float
che determinano lo spostamento orizzontale e verticale degli oggetti grafici disegnati successivamente. I valori negativi x
spostano un oggetto a sinistra, mentre i valori positivi spostano un oggetto a destra. I valori negativi y
spostano verso l'alto un oggetto, mentre i valori positivi spostano verso il basso un oggetto.
Un uso comune della trasformazione traduci è per il rendering di un oggetto grafico che è stato originariamente creato utilizzando coordinate utili per il disegno. Nell'esempio seguente viene creato un PathF oggetto per una stella a 11 punte:
PathF path = new PathF();
for (int i = 0; i < 11; i++)
{
double angle = 5 * i * 2 * Math.PI / 11;
PointF point = new PointF(100 * (float)Math.Sin(angle), -100 * (float)Math.Cos(angle));
if (i == 0)
path.MoveTo(point);
else
path.LineTo(point);
}
canvas.FillColor = Colors.Red;
canvas.Translate(150, 150);
canvas.FillPath(path);
Il centro della stella è a (0,0) e i punti della stella si trovano su un cerchio che circonda quel punto. Ogni punto è una combinazione di valori seno e coseno di un angolo che aumenta di 5/11° di 360 gradi. Il raggio del cerchio viene impostato su 100. Se l'oggetto PathF viene visualizzato senza trasformazioni, il centro della stella verrà posizionato nell'angolo superiore sinistro di ICanvase sarà visibile solo un quarto di esso. Pertanto, una trasformazione traduci viene usata per spostare la stella orizzontalmente e verticalmente in (150,150):
Ridimensionare la trasformazione
La trasformazione della scala modifica le dimensioni di un oggetto grafico e spesso può causare lo spostamento delle coordinate quando un oggetto grafico viene reso più grande.
Il Scale metodo richiede x
e y
argomenti di tipo float
che consentono di specificare valori diversi per la scalabilità orizzontale e verticale, altrimenti nota come scala anisotropica . I valori di x
e y
hanno un impatto significativo sul ridimensionamento risultante:
- I valori compresi tra 0 e 1 riducono la larghezza e l'altezza dell'oggetto ridimensionato.
- I valori maggiori di 1 aumentano la larghezza e l'altezza dell'oggetto ridimensionato.
- I valori 1 indicano che l'oggetto non è ridimensionato.
Nell'esempio seguente viene illustrato il Scale metodo :
canvas.StrokeColor = Colors.Red;
canvas.StrokeSize = 4;
canvas.StrokeDashPattern = new float[] { 2, 2 };
canvas.FontColor = Colors.Blue;
canvas.FontSize = 18;
canvas.DrawRoundedRectangle(50, 50, 80, 20, 5);
canvas.DrawString(".NET MAUI", 50, 50, 80, 20, HorizontalAlignment.Left, VerticalAlignment.Top);
canvas.Scale(2, 2);
canvas.DrawRoundedRectangle(50, 100, 80, 20, 5);
canvas.DrawString(".NET MAUI", 50, 100, 80, 20, HorizontalAlignment.Left, VerticalAlignment.Top);
In questo esempio , ".NET MAUI" viene visualizzato all'interno di un rettangolo arrotondato tratteggiato con una linea tratteggiata. Gli stessi oggetti grafici disegnati dopo l'aumento delle dimensioni della Scale chiamata proporzionalmente:
Il testo e il rettangolo arrotondato sono entrambi soggetti agli stessi fattori di ridimensionamento.
Nota
La scala anisotropica fa sì che le dimensioni del tratto diventino diverse per le linee allineate agli assi orizzontali e verticali.
L'ordine è importante quando si combinano Translate le chiamate e Scale . Se la Translate chiamata viene eseguita dopo la Scale chiamata, i fattori di conversione vengono ridimensionati in base ai fattori di ridimensionamento. Se la chiamata precede la Translate Scale chiamata, i fattori di traduzione non vengono ridimensionati.
Ruota trasformazione
La trasformazione di rotazione ruota un oggetto grafico intorno a un punto. La rotazione è in senso orario per gli angoli crescenti. Sono consentiti angoli negativi e angoli maggiori di 360 gradi.
Esistono due Rotate overload. Il primo richiede un degrees
argomento di tipo float
che definisce l'angolo di rotazione e centra la rotazione attorno all'angolo superiore sinistro dell'area di disegno (0,0). L'esempio seguente illustra questo Rotate metodo:
canvas.FontColor = Colors.Blue;
canvas.FontSize = 18;
canvas.Rotate(45);
canvas.DrawString(".NET MAUI", 50, 50, HorizontalAlignment.Left);
In questo esempio ".NET MAUI" è ruotato a 45 gradi in senso orario:
In alternativa, gli oggetti grafici possono essere ruotati al centro intorno a un punto specifico. Per ruotare intorno a un punto specifico, usare l'overload Rotate che accetta degrees
argomenti , x
e y
di tipo float
:
canvas.FontColor = Colors.Blue;
canvas.FontSize = 18;
canvas.Rotate(45, dirtyRect.Center.X, dirtyRect.Center.Y);
canvas.DrawString(".NET MAUI", dirtyRect.Center.X, dirtyRect.Center.Y, HorizontalAlignment.Left);
In questo esempio, il testo MAUI .NET viene ruotato di 45 gradi intorno al centro dell'area di disegno.
Combinare trasformazioni
Il modo più semplice per combinare le trasformazioni consiste nell'iniziare con le trasformazioni globali, seguite dalle trasformazioni locali. Ad esempio, la traslazione, la scalabilità e la rotazione possono essere combinate per disegnare un orologio analogico. L'orologio può essere disegnato utilizzando un sistema di coordinate arbitrario basato su un cerchio centrato su (0,0) con un raggio di 100. La traslazione e il ridimensionamento espandono e centrano l'orologio sull'area di disegno e rotazione possono quindi essere usati per disegnare i segni minuti e ore dell'orologio e ruotare le mani:
canvas.StrokeLineCap = LineCap.Round;
canvas.FillColor = Colors.Gray;
// Translation and scaling
canvas.Translate(dirtyRect.Center.X, dirtyRect.Center.Y);
float scale = Math.Min(dirtyRect.Width / 200f, dirtyRect.Height / 200f);
canvas.Scale(scale, scale);
// Hour and minute marks
for (int angle = 0; angle < 360; angle += 6)
{
canvas.FillCircle(0, -90, angle % 30 == 0 ? 4 : 2);
canvas.Rotate(6);
}
DateTime now = DateTime.Now;
// Hour hand
canvas.StrokeSize = 20;
canvas.SaveState();
canvas.Rotate(30 * now.Hour + now.Minute / 2f);
canvas.DrawLine(0, 0, 0, -50);
canvas.RestoreState();
// Minute hand
canvas.StrokeSize = 10;
canvas.SaveState();
canvas.Rotate(6 * now.Minute + now.Second / 10f);
canvas.DrawLine(0, 0, 0, -70);
canvas.RestoreState();
// Second hand
canvas.StrokeSize = 2;
canvas.SaveState();
canvas.Rotate(6 * now.Second);
canvas.DrawLine(0, 10, 0, -80);
canvas.RestoreState();
In questo esempio, le Translate chiamate e Scale si applicano a livello globale all'orologio e quindi vengono chiamate prima del Rotate metodo .
Ci sono 60 segni di due diverse dimensioni che vengono disegnate in un cerchio intorno all'orologio. La FillCircle chiamata disegna tale cerchio a (0,-90), che rispetto al centro dell'orologio corrisponde alle 12:00. La Rotate chiamata incrementa l'angolo di rotazione di 6 gradi dopo ogni segno di graduazione. La angle
variabile viene utilizzata esclusivamente per determinare se viene disegnato un cerchio grande o un piccolo cerchio. Infine, l'ora corrente viene ottenuta e i gradi di rotazione vengono calcolati per l'ora, il minuto e le mani seconde. Ogni mano viene disegnata nella posizione 12:00 in modo che l'angolo di rotazione sia relativo a tale posizione:
Concatenare trasformazioni
Una trasformazione può essere descritta in termini di matrice di trasformazione affine 3x3, che esegue trasformazioni nello spazio 2D. La tabella seguente illustra la struttura di una matrice di trasformazione affine 3x3:
M11
M12
0.0
M21
M22
0.0
M31
M32
1.0
Una matrice di trasformazione affine ha la colonna finale uguale a (0,0,1), quindi devono essere specificati solo i membri nelle prime due colonne. Pertanto, la matrice 3x3 è rappresentata dallo Matrix3x2
struct, dallo spazio dei System.Numerics nomi , che è una raccolta di tre righe e due colonne di float
valori.
Le sei celle nelle prime due colonne della matrice di trasformazione rappresentano valori che eseguono ridimensionamento, shearing e traslazione:
Scalex
Sheary
0.0
ShearX
Scaley
0.0
TranslateX
TranslateY
1.0
Ad esempio, se si modifica il M31
valore su 100, è possibile usarlo per convertire un oggetto grafico di 100 pixel lungo l'asse x. Se si imposta il M22
valore su 3, è possibile usarlo per estendere un oggetto grafico a tre volte l'altezza corrente. Se si modificano entrambi i valori, si sposta l'oggetto grafico di 100 pixel lungo l'asse x e si estende l'altezza di un fattore pari a 3.
È possibile definire una nuova matrice di trasformazione con il Matrix3x2
costruttore . Il vantaggio di specificare trasformazioni con una matrice di trasformazione è che le trasformazioni composite possono essere applicate come singola trasformazione, definita concatenazione. Lo Matrix3x2
struct definisce anche i metodi che possono essere usati per modificare i valori della matrice.
L'unico ICanvas metodo che accetta un Matrix3x2
argomento è il ConcatenateTransform metodo , che combina più trasformazioni in una singola trasformazione. Nell'esempio seguente viene illustrato come utilizzare questo metodo per trasformare un PathF oggetto :
PathF path = new PathF();
for (int i = 0; i < 11; i++)
{
double angle = 5 * i * 2 * Math.PI / 11;
PointF point = new PointF(100 * (float)Math.Sin(angle), -100 * (float)Math.Cos(angle));
if (i == 0)
path.MoveTo(point);
else
path.LineTo(point);
}
Matrix3x2 transform = new Matrix3x2(1.5f, 1, 0, 1, 150, 150);
canvas.ConcatenateTransform(transform);
canvas.FillColor = Colors.Red;
canvas.FillPath(path);
In questo esempio, l'oggetto PathF viene ridimensionato e ridimensionato sull'asse x e convertito sull'asse x e sull'asse y.