Příloha: Maticové transformace
Toto téma obsahuje matematický přehled maticových transformací pro 2D grafiku. Pro použití transformací v Direct2D ale nemusíte znát maticovou matematiku. Přečtěte si toto téma, pokud vás zajímá matematika; v opačném případě můžete toto téma přeskočit.
- Úvod do matic
- Affine Transforms
- představující transformace v Direct2D
- Další
Úvod do matric
Matice je obdélníková matice reálných čísel. Pořadí matice je počet řádků a sloupců. Pokud má matice například 3 řádky a 2 sloupce, pořadí je 3 × 2. Matice se obvykle zobrazují s prvky matice uzavřené v hranatých závorkách:
Zápis: Matice je určena velkým písmenem. Prvky jsou označené malými písmeny. Dolní indexy označují číslo řádku a sloupce prvku. Napříkladij je prvek v i'th řádku a j'th sloupec matice A.
Následující diagram znázorňuje matici i × j s jednotlivými prvky v každé buňce matice.
Operace matice
Tato část popisuje základní operace definované na maticích.
sčítání. Součet A + B ze dvou matic se získá přidáním odpovídajících prvků A a B:
- A + B = \[ a*ij* \] + \[ b*ij* \] = \[ a*ij* + b*ij* \]
skalární násobení. Tato operace vynásobí matici skutečným číslem. Při skutečném čísle kse skalární součin kA získá vynásobením každého prvku A k.
- kA = k\[ a*ij* \] = \[ k × a*ij* \]
násobení matice. Při dvou maticích A a B s pořadím (m × n) a (n × p) je součin C = A × B matice s pořadím (m × p), definovaný takto:
nebo odpovídajícím způsobem:
- c*ij* = a*i*1 x b1*j* + a*i*2 x b2*j* + ... + a*in* + b*nj*
To znamená, že pokud chcete vypočítat každý prvek cij, postupujte takto:
- Vezměte i'th řádek A a j'th sloupec B.
- Vynásobte každou dvojici prvků v řádku a sloupci: první položku řádku první položkou sloupce, druhou položkou řádku druhou položkou sloupce atd.
- Součet výsledku
Tady je příklad násobení matice (2 × 2) maticí (2 × 3).
Násobení matice není kommutativní. To znamená, že A × B ≠ B × A. Z definice vyplývá také, že není možné násobit každou dvojici matic. Počet sloupců v levé matici se musí shodovat s počtem řádků v pravé matici. V opačném případě není definován operátor ×.
Identifikacematice . Matice identit, určená I, je čtvercová matice definovaná takto:
- I*ij* = 1, pokud *i* = *j*, nebo 0 jinak.
Jinými slovy, matice identit obsahuje 1 pro každý prvek, kde se číslo řádku rovná číslu sloupce a nule pro všechny ostatní prvky. Tady je například 3 × 3 matice identit.
Následující rovná se pro libovolnou matici M.
- M x I = M I x M = M
Affine Transforms
je matematická operace, která mapuje jeden souřadnicový prostor na druhý. Jinými slovy, mapuje jednu sadu bodů na jinou sadu bodů. Transformace Affine mají některé funkce, díky kterým jsou užitečné v počítačové grafikě.
- Transformace affinu zachová kolinearitu. Pokud tři nebo více bodů spadnou na čáru, stále tvoří čáru za transformací. Rovné čáry zůstávají rovné.
- Složení dvou affinových transformací je affinová transformace.
Transformace Affinu pro prostorový prostor mají následující tvar.
Pokud použijete definici násobení matice uvedené výše, můžete ukázat, že součin dvou affinových transformací je další affinová transformace. Pokud chcete transformovat 2D bod pomocíffinové transformace, je tento bod reprezentován jako 1 × 3 matice.
- P = \| x y 1 \|
První dva prvky obsahují souřadnice x a y bodu. 1 se umístí do třetího prvku, aby matematika správně fungovala. Pokud chcete použít transformaci, vynásobte tyto dvě matice následujícím způsobem.
- P' = P × M
Tím se rozbalí následující položky.
kde
- x' = ax + cy + e y' = bx + dy + f
Transformovaný bod získáte tak, že vezmete první dva prvky matice P.
- p = (x', y') = (ax + cy + e, bx + dy + f)
Poznámka
1 × n matice se nazývá vektor řádku. Direct2D i Direct3D používají vektory řádků k reprezentaci bodů ve 2D nebo 3D prostoru. Ekvivalentní výsledek můžete získat pomocí vektoru sloupce (n × 1) a transponováním transformační matice. Většina grafických textů používá tvar vektoru sloupce. Toto téma představuje tvar vektoru řádku pro konzistenci s Direct2D a Direct3D.
Následující několik částí odvozuje základní transformace.
Transformace překladu
Matice transformace překladu má následující formulář.
transformace překladu
Připojení bodu P do této rovnice:
- P' = (*x* + *dx*, *y* + *dy*)
který odpovídá bodu (x, y) přeložené dx na ose X a dy na ose Y.
Transformace škálování
Matice transformace škálování má následující tvar.
Připojení bodu P do této rovnice:
- P' = (*x* ≥ *dx*, *y* ≥ *dy*)
který odpovídá bodu (x,y) měřítku podle dx a dy.
Otočení kolem původu
Matice, která má otočit bod kolem počátku, má následující tvar.
Transformovaný bod je:
- P' = (*x*cosΘ – ysinΘ, *x*sinΘ + *y*cosΘ)
Důkaz. Pokud chcete ukázat, že P představuje otočení, zvažte následující diagram.
Daný:
-
P = (x,y)
-
Původní bod transformace.
-
Φ
-
Úhel vytvořený přímkou (0,0) až P.
-
Θ
-
Úhel, kterým chcete otočit (x,y) o původu.
-
P' = (x',y')
-
Transformovaný bod.
-
R
-
Délka čáry (0,0) až P. Také poloměr kruhu otáčení.
Poznámka
Tento diagram používá standardní souřadnicový systém použitý v geometrii, kde osa y ukazuje nahoru. Direct2D používá souřadnicový systém Windows, kde osa y ukazuje dolů.
Úhel mezi osou x a čárou (0,0) na P' je Φ + Θ. Následující identity obsahují:
- x = R cosΦ y = R sinΦ x' = R cos(Φ + Θ) y' = R sin(Φ+ Θ)
Nyní vyřešte x' a y' z hlediska Θ. Podle trigonometrických vzorců sčítání:
- x' = R(cosΦcosΘ – sinΦsinΘ) = RcosΦcosΘ – RsinΦsinΘ y' = R(sinΦcosΘ + cosΦsinΘ) = RsinΦcosΘ + RcosΦsinΘ
Nahrazování získáme:
- x' = xcosΘ – ysinΘ y' = xsinΘ + ycosΘ
který odpovídá výše uvedenému transformovaného bodu P.
Otočení kolem libovolného bodu
K otočení bodu (x,y) jiného než počátku se použije následující matice.
transformace otočení
Tuto matici můžete odvodit tak, že vezmete bod (x,y) jako původ.
Let (x1, y1) je bod, který má za následek otočení bodu (x0, y0) kolem bodu (x,y). X1 můžeme odvodit následujícím způsobem.
- x1 = (x0 – x)cosΘ– (y0 – y)sinΘ + x x1 = x0cosΘ – y0sinΘ + \[ (1 – cosΘ) + ysinΘ \]
Nyní tuto rovnici zapojte zpět do transformační matice pomocí vzorce x1 = ax0 + cy0 + e ze starších verzí. Stejný postup použijte k odvození y1.
Zkosená transformace
Transformace nerovnoměrné distribuce je definována čtyřmi parametry:
- Θ: Množství, které se zkosí podél osy x, měřeno jako úhel od osy y.
- Φ: Velikost nerovnoměrné distribuce podél osy y měřená jako úhel od osy x.
- (px, py): Souřadnice x a y bodu, o kterém se provádí nerovnoměrná distribuce.
Transformace nerovnoměrné distribuce používá následující matici.
Transformovaný bod je:
- P' = (*x* + *y*tanΘ – *py*tanΘ, *y* + *x*tanΦ) – *py*tanΦ
nebo ekvivalentní:
- P' = (*x* + (*y* – *py*)tanΘ, *y* + (*x* – *px*)tanΦ)
Pokud chcete zjistit, jak tato transformace funguje, zvažte jednotlivé komponenty jednotlivě. Parametr Θ přesune každý bod ve směru x o hodnotu rovnající se tanΘ. Následující diagram znázorňuje vztah mezi Θ a nerovnoměrnou zkosenou osou x.
Tady je stejná nerovnoměrná distribuce použitá u obdélníku:
Parametr Φ má stejný účinek, ale podél osy y:
Následující diagram znázorňuje nerovnoměrnou distribuci osy y použitou u obdélníku.
Nakonec parametry px a py posunou středový bod pro nerovnoměrnou distribuci podél os x a y.
Reprezentace transformací v Direct2D
Všechny transformace Direct2D jsou affinové transformace. Direct2D nepodporuje transformace bez affinu. Transformace jsou reprezentovány strukturou D2D1_MATRIX_3X2_F. Tato struktura definuje 3 × 2 matice. Protože třetí sloupec transformace affinu je vždy stejný ([0, 0, 1]) a protože Direct2D nepodporuje neffineové transformace, není nutné zadávat celou 3 × 3 matici. Direct2D interně používá 3 × 3 matice k výpočtu transformací.
Členy D2D1_MATRIX_3X2_F jsou pojmenovány podle jejich pozice indexu: _11 člen je prvek (1,1), _12 člen je prvek (1,2) a tak dále. I když členy struktury můžete inicializovat přímo, doporučuje se použít D2D1::Matrix3x2F třídy. Tato třída dědí D2D1_MATRIX_3X2_F a poskytuje pomocné metody pro vytváření jakékoli základní affine transformace. Třída také definuje operator*() pro vytváření dvou nebo více transformací, jak je popsáno v Použití transformací v direct2D.
Další