Proč je důležité pořadí transformace

Jeden Matrix objekt může uložit jednu transformaci nebo posloupnost transformací. Druhá se nazývá složená transformace. Matice složené transformace se získá vynásobením matic jednotlivých transformací.

Příklady složených transformací

Ve složené transformaci je důležité pořadí jednotlivých transformací. Pokud například poprvé otočíte, pak škálujete, přeložíte, dostanete jiný výsledek než při prvním překladu, pak otočíte a pak škálujete. V GDI+ se složené transformace vytvářejí zleva doprava. Pokud jsou matice S, R a T měřítka, otočení a překladu, pak součin SRT (v tomto pořadí) je matice složené transformace, která se nejprve škáluje, pak otočí a přeloží. Matice vytvořená produktem SRT se liší od matice vyrobené produktem TRS.

Jedním z důvodů je důležité, že transformace, jako je otočení a škálování, se provádějí s ohledem na původ souřadnicového systému. Změna velikosti objektu, který je uprostřed na počátku, způsobí jiný výsledek než změna velikosti objektu přesunutého od původního zdroje. Podobně otočení objektu, který je uprostřed na počátku, vytvoří jiný výsledek než otočení objektu, který byl přesunut od původu.

Následující příklad kombinuje škálování, otočení a překlad (v tomto pořadí) a tvoří složenou transformaci. Argument Append předaný RotateTransform metodě označuje, že rotace bude následovat po škálování. Podobně argument Append předaný TranslateTransform metodě označuje, že překlad bude následovat za otočením. Append a Prepend jsou členy výčtu 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)

Následující příklad provádí stejná volání metody jako předchozí příklad, ale pořadí volání je obrácené. Výsledné pořadí operací se nejprve přeloží, pak otočí a pak škáluje, což vytvoří velmi jiný výsledek než první měřítko, pak otočí a pak přeloží.

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)

Jedním ze způsobů, jak obrátit pořadí jednotlivých transformací ve složené transformaci, je obrátit pořadí posloupnosti volání metody. Druhým způsobem řízení pořadí operací je změna argumentu pořadí matice. Následující příklad je stejný jako předchozí příklad s tím rozdílem, že Append byl změněn na Prepend. Násobení matice se provádí v pořadí SRT, kde S, R a T jsou matice pro měřítko, otočení a překlad. Pořadí složené transformace je nejprve měřítko, pak otočit a pak přeložit.

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)

Výsledek bezprostředně předcházejícího příkladu je stejný jako výsledek prvního příkladu v tomto tématu. Důvodem je to, že jsme převráceli pořadí volání metody i pořadí násobení matice.

Viz také