Condividi tramite


Importanza dell'ordine delle trasformazioni

Un singolo Matrix oggetto può archiviare una singola trasformazione o una sequenza di trasformazioni. Quest'ultimo è denominato trasformazione composita. La matrice di una trasformazione composita viene ottenuta moltiplicando le matrici delle singole trasformazioni.

Esempi di trasformazione composita

In una trasformazione composita, l'ordine delle singole trasformazioni è importante. Ad esempio, se si ruota prima, quindi si ridimensiona, quindi si traduce, si ottiene un risultato diverso rispetto a se si converte prima, quindi ruotare, quindi scalare. In GDI+, le trasformazioni composite vengono create da sinistra a destra. Se S, R e T sono rispettivamente matrici di scalabilità, rotazione e traslazione, il prodotto SRT (in tale ordine) è la matrice della trasformazione composita che prima scala, quindi ruota, quindi converte. La matrice prodotta dal prodotto SRT è diversa dalla matrice prodotta dal prodotto TRS.

Un ordine di motivo è significativo è che le trasformazioni come la rotazione e il ridimensionamento vengono eseguite rispetto all'origine del sistema di coordinate. Il ridimensionamento di un oggetto centrato in corrispondenza dell'origine produce un risultato diverso rispetto al ridimensionamento di un oggetto spostato dall'origine. Analogamente, la rotazione di un oggetto centrato in corrispondenza dell'origine produce un risultato diverso rispetto alla rotazione di un oggetto spostato dall'origine.

L'esempio seguente combina la scalabilità, la rotazione e la conversione (in tale ordine) per formare una trasformazione composita. L'argomento Append passato al RotateTransform metodo indica che la rotazione seguirà il ridimensionamento. Analogamente, l'argomento Append passato al TranslateTransform metodo indica che la traduzione seguirà la rotazione. Append e Prepend sono membri dell'enumerazione MatrixOrder .

Rectangle rect = new Rectangle(0, 0, 50, 50);
Pen pen = new Pen(Color.FromArgb(128, 200, 0, 200), 2);
e.Graphics.ResetTransform();
e.Graphics.ScaleTransform(1.75f, 0.5f);
e.Graphics.RotateTransform(28, MatrixOrder.Append);
e.Graphics.TranslateTransform(150, 150, MatrixOrder.Append);
e.Graphics.DrawRectangle(pen, rect);
Dim rect As New Rectangle(0, 0, 50, 50)
Dim pen As New Pen(Color.FromArgb(128, 200, 0, 200), 2)
e.Graphics.ResetTransform()
e.Graphics.ScaleTransform(1.75F, 0.5F)
e.Graphics.RotateTransform(28, MatrixOrder.Append)
e.Graphics.TranslateTransform(150, 150, MatrixOrder.Append)
e.Graphics.DrawRectangle(pen, rect)

Nell'esempio seguente vengono eseguite le stesse chiamate al metodo dell'esempio precedente, ma l'ordine delle chiamate viene invertito. L'ordine delle operazioni risultante viene prima convertito, quindi ruota, quindi scala, che produce un risultato molto diverso rispetto alla prima scala, quindi ruota, quindi traduci.

Rectangle rect = new Rectangle(0, 0, 50, 50);
Pen pen = new Pen(Color.FromArgb(128, 200, 0, 200), 2);
e.Graphics.ResetTransform();
e.Graphics.TranslateTransform(150, 150, MatrixOrder.Append);
e.Graphics.RotateTransform(28, MatrixOrder.Append);
e.Graphics.ScaleTransform(1.75f, 0.5f);
e.Graphics.DrawRectangle(pen, rect);
Dim rect As New Rectangle(0, 0, 50, 50)
Dim pen As New Pen(Color.FromArgb(128, 200, 0, 200), 2)
e.Graphics.ResetTransform()
e.Graphics.TranslateTransform(150, 150, MatrixOrder.Append)
e.Graphics.RotateTransform(28, MatrixOrder.Append)
e.Graphics.ScaleTransform(1.75F, 0.5F)
e.Graphics.DrawRectangle(pen, rect)

Un modo per invertire l'ordine delle singole trasformazioni in una trasformazione composita consiste nell'invertire l'ordine di una sequenza di chiamate al metodo. Un secondo modo per controllare l'ordine delle operazioni consiste nel modificare l'argomento dell'ordine della matrice. L'esempio seguente è lo stesso dell'esempio precedente, ad eccezione del fatto che Append è stato modificato in Prepend. La moltiplicazione della matrice viene eseguita nell'ordine SRT, dove S, R e T sono rispettivamente le matrici per la scala, la rotazione e la conversione. L'ordine della trasformazione composita è prima scala, quindi ruota, quindi traduci.

Rectangle rect = new Rectangle(0, 0, 50, 50);
Pen pen = new Pen(Color.FromArgb(128, 200, 0, 200), 2);
e.Graphics.ResetTransform();
e.Graphics.TranslateTransform(150, 150, MatrixOrder.Prepend);
e.Graphics.RotateTransform(28, MatrixOrder.Prepend);
e.Graphics.ScaleTransform(1.75f, 0.5f);
e.Graphics.DrawRectangle(pen, rect);
Dim rect As New Rectangle(0, 0, 50, 50)
Dim pen As New Pen(Color.FromArgb(128, 200, 0, 200), 2)
e.Graphics.ResetTransform()
e.Graphics.TranslateTransform(150, 150, MatrixOrder.Prepend)
e.Graphics.RotateTransform(28, MatrixOrder.Prepend)
e.Graphics.ScaleTransform(1.75F, 0.5F)
e.Graphics.DrawRectangle(pen, rect)

Il risultato dell'esempio immediatamente precedente è uguale al risultato del primo esempio in questo argomento. Ciò è dovuto al fatto che sia l'ordine delle chiamate al metodo sia l'ordine della moltiplicazione della matrice.

Vedi anche