Condividi tramite


Trasformazioni

Browse sample. Esplorare l'esempio

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:

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

Screenshot of an 11-pointed star.

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:

Screenshot of unscaled and scaled text.

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:

Screenshot of rotated text.

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 degreesargomenti , xe 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:

Screenshot of an analog clock.

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.