32. fejezet - Az a fránya matek 1.
(lineáris algebra)


Az időnként előforduló elméleti jellegű diskurzusok és fejtegetések közben feltűnt, hogy némelyek megijednek a cikkekben elvétve fellelhető matekos részektől, pedig semmi olyat nem szoktam írni, amit ne tudna megérteni egy óvodából frissen kirúgott gyagyás. Azonban láthatóan igény van egy olyan cikkre ami elmagyarázza legalább az olyan alapvető fogalmakat, mint például az Lp normával értelmezett korlátoslineáris funkcionál (hehehe).

Az első három bekezdés alapozó jellegű, hogy látható legyen hogyan kell bevezetni a 3D grafika tipikus fogalmait. Leszögezném, hogy a definíciók és állítások pongyolák (azaz matematikailag nem egzaktak), ugyanis nem akarok se tételt bizonyítani, se érthetetlenül fogalmazni. Ennek ellenére, ha mégis nehezen érthető lenne az se baj, csak olvasd el, majd később megérted (mondjuk úgy 10-20 év múlva). A lényeg a későbbi bekezdésekben van. A cikkben Gyapjas Ferenc: Lineáris algerba és geometria című jegyzetéből dolgozok. Ha valakit inkább a C++ oldali implementációk érdekelnek, annak javaslom Seeting kolléga cikkét.

BREAKING: Mindenki örömére végre van tartalomjegyzék. Más kérdés, hogy nem lehet normálisan elhelyezni.




Gyorstalpaló matematikai jelölésekből.

Jelölés Magyarázat
X, Y, V, W, T halmazok
a ∈ X a eleme az X halmaznak
K valós (R) vagy komplex (C) számtest
a := b a legyen egyenlő b
f: X → Y az f nevű X-ből Y-ba képező függvény
X × Y az X és Y halmazok Descartes szorzata
λ, μ, ξ skalárok (kiejtés: lambda, mű, xí), ha nem írom ki, akkor K-ból
a, b, c (oszlop)vektorok
aT az a vektor sorvektorként értelmezve
(a1, ..., an) sorvektor az elemeivel megadva
(a1, ..., an)T oszlopvektor az elemeivel megadva
ai az a vektor i-edik eleme
|a| az a vektor hossza
a1, ..., an n darab vektor, ezekre röviden ai-ként hivatkozok
<a, b> az a és b vektorok skaláris szorzata (dot product)
a × b az a és b vektorok vektoriális szorzata (cross product)
A, B, C mátrixok
Aij az A mátrix i-edik sorának j-edik eleme*
[ Aij ] mátrix az elemeivel megadva, helytakarékosan*
AT az A mátrix transzponáltja
A-1 az A mátrix inverze
|A| az A mátrix determinánsa (ugyanaz, mint det(A))
"minden" vagy "bármely"
"létezik"
∃! "egyértelműen létezik"
összegzés a megadott index szerint (kiejtés: szumma)
szorzás a megadott index szerint (kiejtés: produktum)

Természetesen a legtöbbnek a konkrét magyarázata lentebb olvasható. A billentyűzet limitációi miatt nem tudok mindent megkülönböztetni, úgyhogy a hasonló jeöléseket ne tessék félreérteni. A jegyzethez képest eltérő jelöléseket *-al jelöltem, azt sem kéretik félreérteni.


Középiskolában azt tanultad, hogy a vektor egy irányított szakasz, aminek van kezdőpontja és végpontja. Ez az amit most elfelejthetsz. Mivel azonos hosszú és irányítású vektorokat egyenlőnek tekintünk, elég őket helyvektorként megadni (tehát a kezdőpontja az origó, és a végpontját adod meg). Nyilván minden két ponttal megadott vektor konvertálható ilyenbe úgy, hogy a végpontból kivonod a kezdőpontot.

A fejtegetést természetesen nem Ádámtól és Évától fogom kezdeni, hanem Évától és a vektorterektől. Egy V-vel jelölt vektorteret mindig egy T-vel jelölt számtest felett értünk (bármit is jelentsen az), tehát V elemei T-beli számokból összetákolt vektorok. Az alkalmazások szempontjából T szinte mindig vagy a valós (R) vagy a komplex (C) számok halmaza. Ha ezt külön ki akarom emelni, akkor T helyett K-t írok, de komplex számokkal nem fogok külön foglalkozni. Tíz darab feltételnek kell teljesülnie ahhoz, hogy V vektortér legyen, mégpedig:

(a, b, c ∈ V, és λ, μ ∈ T)

  • a vektorokat össze lehet adni (+), ez elemenként történik
  • kommutatív: a + b = b + a
  • asszociatív: a + (b + c) = (a + b) + c
  • van nullelem: 0 + a = a
  • van additív inverz: (-a) + a = 0
  • a vektorokat lehet skalárral szorozni (), szintén elemenként
  • van egységelem: 1 ⋅ a = a
  • asszociatív: λ ⋅ (μ ⋅ a) = (λ ⋅ μ) ⋅ a
  • disztributivitás: (λ + μ) * a = λ ⋅ a + μ ⋅ a
  • disztributivitás: λ ⋅ (a + b) = λ ⋅ a + λ ⋅ b
Nem olyan egetrengető feltételek, sőt meg is nyugtathatjuk magunkat, hogy a konyhanyelven értett vektorok vektorteret alkotnak (mily meglepő). A skalárral való szorzás jelét () mostantól nem fogom kiírni.

Ami még fontos (és tulajdonképpen ezzel kellett volna kezdeni), az a Descartes szorzat fogalma, ami két halmazon értendő, és a két halmaz elemeiből alkotott rendezett párok halmazát jelenti:

X × Y = { olyan (x, y) párok, hogy x ∈ X, y ∈ Y }

Ilyetén módon a kétdimenziós vektorok halmaza R × R, a háromdimenziósaké R × R × R, stb.
Ezeket röviden R2, R3, stb.-nek jelöljük és meglepő módon minden n természetes számra Rn és Cn (mostantól Kn) vektortér.


Továbbra is pongyolán: a V vektortér egy W (nem üres) részhalmazát a V alterének nevezzük, ha W maga is vektorteret alkot a V-beli műveletekre (melyeket fent olyan jól bemutattam). Fontos, hogy a műveletek eredménye nem mutathat ki az altérből (ha fent nem lett volna világos), tehát nem minden részhalmaz altér.

Most vegyünk k darab vektort: a1, ..., ak és ugyanennyi skalárt: λ1, ..., λk, ekkor a

λ1a1 + ... + λkak

vektort az a1, ..., ak vektorok lineáris kombinációjának nevezzük.

Továbbmenve, azt mondjuk, hogy az a1, ..., ak vektorok lineárisan függetlenek, ha abból, hogy

λ1a1 + ... + λkak = 0

következik, hogy λ1 = ... = λk = 0. Ha tehát a lineáris kombináció nulla, de valamelyik lambda nem nulla, akkor a vektorok nem függetlenek (hanem összefüggőek). Az összefüggőség tipikusan azt jelenti, hogy valamelyik vektor előáll a többi lineáris kombinációjával (szélsőséges esetben egy másik vektortól csak hosszban különbözik).

Most jöjjön egy fontos fogalom: a b1, ..., bk vektorokat a V vektortér bázisának hívjuk, ha lineárisan függetlenek, és minden V-beli vektor előáll ezek lineáris kombinációjaként. A vektortér dimenziója a benne levő tetszőleges bázis elemszáma (ami furcsa módon Kn-re mindig n).

Néhány következményt illik megemlíteni, például hogy egy n dimenziós vektortérben bármely n + 1 vektor lineárisan összefüggő (különben bázis lenne), illetve egy W altér dimenziója legfeljebb ugyanannyi lehet, mint V dimenziója (például a háromdimenziós térnek egy altere a kétdimenziós tér).

Továbbá ha b1, ..., bn bázis, akkor persze a definíció alapján minden vektor előáll ezek lineáris kombinációjával, de az is igaz, hogy ez az előállítás egyértelmű. Tehát egy tetszőleges x ∈ V vektor felírható

x = λ1b1 + ... + λnbn

alakban. A lamdákból összerakott 1, ..., λn)T oszlopvektort az x vektor b1, ..., bn bázisra vonatkozó koordináta oszlopának hívják. A T ne zavarjon meg senkit, ez azt próbálja jelezni, hogy egymás alá kéne írnom az értékeket (innen az oszlopvektor), de ezt nyilván nem tudom most megtenni.

Sőt, ha b1, ..., bn az úgynevezett kanonikus bázis (pl. R3-ban (1, 0, 0)T, (0, 1, 0)T, (0, 0, 1)T), akkor a lamdbák értelemszerűen egybeesnek x elemeivel.


3D grafikában a leggyakrabban használt művelet az, amikor két bázis között transzformálunk pontokat. Ehhez meg kell mondani, hogy a két bázis közötti kapcsolat hogyan írható le. Legyen a kiinduló bázis e1, ..., en, a célbázis pedig
f1, ..., fn és írjunk fel egy tetszőleges x vektort a célbázisban (mostantól a szumma jelet fogom használni):

pic1

de persze az fj bázisvektorok előállnak az ei bázisvektorokkal (a bázis definíciója alapján):

pic2
és helyettesítsük be az előbbibe:

pic3

és ezzel felírtuk x-et az eredeti bázisban. Az elvégzett átalakítások minden további nélkül megtehetőek, a vektortér definíciója alapján (és mivel T test). Értelmezzük először, hogy mi történik, illetve miért jelöltem meg λi-vel a belső szummát.

Az alapfeladat az alábbi:
  • ismerjük az x vektor ei-re vonatkozó koordinátáit: 1, ..., λn)T
  • szintén ismerjük az fj-k koordinátáit az ei-kre nézve (11, ..., μn1)T, ..., (μ1n, ..., μnn)T)
  • keresendők ugyanezen x vektor fi bázisbeli 1, ..., ξn)T koordinátái
A fenti egyenlőségből az látszik, hogy a keresett ξi koordináták megkaphatóak úgy, hogy megoldjuk az alábbi n ismeretlenes lineáris egyenletrendszert:
pic3b

Most fogjuk ezeket a μij-ket és írjuk fel őket egy táblázatba:
pic4

és nevezzük el ezt a szerencsétlent (n-edrendű négyzetes) mátrixnak. Pongyolán mondva oszlopvektorok egymás mellé pakolásáról van szó. Különösen fontos ez, mivel programozáskor sosem szoktunk bázisokkal bíbelődni, hanem ezt a mátrixot adjuk csak meg.

Ezzel a jelöléssel felvértezve pakoljuk az ei bázist az E-vel jelölt mátrixba, az fi bázist pedig az F mátrixba. A fenti μij-s mátrixot jelöljük A-val, ekkor a bázisok közti váltást röviden írhatjuk le: F = EA (és nem fordítva!). Ezt fogom majd mátrixszorzásnak hívni (később). Hasonló meggondolásokkal a megoldandó lineáris egyenletrendszer pedig Ay = b alakban írható.

Természetesen nem csak négyzetes mátrixok léteznek, sőt a mátrixokkal könyveket lehetne megtölteni, amit én itt nyilván nem fogok megtenni, de a lényeges dolgokat felépítem a későbbi bekezdésekben.


Középiskolában voltak ilyen fogalmak, hogy skaláris szorzat, vektoriális szorzat, stb. Ezeket én is bevezetem, de nem az ott tanult definícióval, ugyanis annál sokkal drámaibban is meg lehet ezeket fogalmazni.

Euklideszi térnek nevezzük az alábbi párost: (V, <.,.>), ahol V vektortér, <.,.> V × V → K pedig egy úgynevezett skaláris szorzás, és az alábbi feltételek teljesülnek:

(a, b, c ∈ V, és λ, μ ∈ K)

  • <a, b> = <b, a>
  • a + μb, c> = λ<a, c> + μ<b, c>
  • <a, a> > 0, minden a0-ra
(megjegyzés: az első feltételben a felülvonást csak akkor kell figyelembe venni, ha K a komplex számtest, ekkor konjugáltat jelent)

Rn-ben a skaláris szorzás a következőképpen definiálható:

<a, b> = a1b1 + a2b2 + ... + anbn

Tehát a vektorok megfelelő elemeit összeszorzod, majd a szorzatokat összeadod.

Középiskolában a definíció úgy hangzott, hogy <a, b> = |a| |b| cos γ ahol γ a két vektor által bezárt szög. Mivel ott a vektornak más értelmezése volt, nem használható a fenti képlet, csak némi meggondolással. Ennek ellenére ez egy igen fontos egyenlőség, ugyanis ha a két vektor normalizált (a hosszuk 1), akkor a skaláris szorzat megadja a közbezárt szög koszinuszát.

Vegyük most a |.|: V → R függvényt, amit definiáljunk a következőképpen:

|x| := √<x, x>

és nevezzük el az x vektor hoszzának. Megjegyezném, hogy (Rn, |.|) egy úgynevezett normált tér (sőt Banach tér), a |.| függvény pedig egy norma, sőt neve is van: euklideszi norma (mily meglepő).

De menjünk tovább a mátrixokkal. Természetesen mátrixokat is lehet összeadni (ugyanúgy mint vektorokat), de elég ritkán használatos, így nem is pazarlok rá több szót. Egy gyakrabban használt művelet a skalárral való szorzás, ami szintén ugyanaz mint vektoroknál, tehát a mátrix minden komponensét megszorzod a skalárral. Most jön egy nem túl meglepő dolog: a mátrixok vektorteret alkotnak ezen két műveletre.

Ha nem lett volna még elég a fontos dolgokból, akkor most jön a következő legfontosabb dolog: a mátrixsszorzás. A fentiekből már lehet sejteni, hogy ez nem komponensenként történik meg, hanem "skaláris szorzatokkal". Az A és B mátrix szorzatát AB-nek írjuk, ennek elemeit a következőképpen lehet kiszámolni:

pic8

Tehát az A mátrix i-edik sorát "skalárisan szorozzuk" a B mátrix j-edik oszlopával. Papíron ezt úgy lehet ezt jól leírni, hogy az A mátrix jobb felső sarkához illeszted a B mátrix bal alsó sarkát, az eredményt pedig alá számolod ki. Nem lehet elégszer hangsúlyozni, hogy nem kommutatív, viszont asszociatív.

Az A mátrix főátlóját alkotják azok az Aij elemek, ahol i = j (vagyis bal felső sarokból jobb alsó sarokba). Az A mátrix transzponáltjának nevezzük és AT-vel jelöljük azt a mátrixot, amit úgy kapunk, hogy az A elemeit tükrözzük a főátlójára.

pic6

Nyilván ha most egy C = AB mátrixszorzatot veszünk, akkor az írható úgy is, hogy C = (BTAT)T. Persze ez semmin nem változtat, viszont ebből is lászik, hogy baromira nem mindegy hogy melyik oldalról szorzol egy mátrixxal! A DirectX ezt az utóbbi "jobbról szorzok" szemléletet használja, míg az OpenGL (és egyébként minden matematikai irodalom) az eredeti balról szorzást. Kiemelném, hogy mind a kettő helyes, amíg konzisztensen mindig csak az egyiket használod. Ha elkezded kavarni őket, akkor vicces dolgokat fogsz tapasztalni.

Egy további fontos fogalom ami a szorzáshoz kapcsolódik a mátrix inverze (a szorzásra nézve). Ahhoz, hogy ezt értelmezni lehessen be kell vezetni egy egységelemet (jelöljük ezt I-vel és legyen a neve egységmátrix), amire teljesül, hogy IA = AI = A. Legyen I az a mátrix, melynek főátlójában 1-esek vannak, mindenhol máshol 0. Ekkor az inverz az alábbi egyenlőséggel értelmezhető: A-1A = AA-1 = I. Szintén egy gyakran használt fogalom, viszont nem minden mátrixnak van inverze (később lesz róla szó).

A bekezdés végén még nézzünk meg néhány fontos azonosságot (a vektorok oszlopvektorként értendők):

Azonosság Megjegyzés
<a + b, c> = <a, c> + <b, c> a skaláris szorzat felbontható
a, μb> = λμ<a, b> skalár kivihető a skaláris szorzatból
a és b merőleges, akkor és csak akkor, ha <a, b> = 0 ha egyik sem nullvektor
ha <a, b> = <a, c> akkor <a, b - c> = 0 vektorral nem lehet egyszerűsíteni (b != c)
<a, b> = aTb a skaláris szorzás értelmezhető mátrixszorzásként
A(BC) = (AB)C a mátrixsszorzás asszociatív
A(B + C) = AB + AC bal oldali disztributivitás
(B + C)A = BA + CA jobb oldali disztributivitás
(AT)T = A transzponált transzponáltja az eredeti mátrix
(A + B)T = AT + BT összeg transzponáltja
(AB)T = BTAT szorzat transzponáltja
(AB)-1 = B-1A-1 szorzat inverze
(AT)-1 = (A-1)T transzponált inverze
(A-1)-1 = A inverz inverze az eredeti mátrix
(λA)-1 = λ-1A-1 valós számok esetén λ-1 = 1 / λ

Ezeket jó észben tartani, mert sokat kell használni. A vektoriális szorzatot nem említem most meg, majd egy későbbi bekezdésben (ugyanis nem egy általános művelet).


Szöveges feladatokat nem találtam, úgyhogy most mindenki elképzeli, hogy az alábbi egyenletrendszer valami nagyon fontos dolognak a formalizálása.

x + 2y + 5z = -9
x - y + 3z = 2
3x - 6y - z = 25

Persze ezt egy általános iskolás is meg tudná oldani úgy, hogy mondjuk kifejezi x-et a második egyenletből aztán behelyettesíti az elsőbe és kifejezi y-t, stb. Ha viszont adnék neki egy 30 ismeretlenes egyenletrendszert, akkor valószínűleg kapitulálna (hacsak nem lelkiismeretes). Ha esetleg még azt is megoldaná, akkor kerítenék egy neki való egymillió ismeretlenes operációkutatási feladatot, csak hogy legyen dolga (a mai fiataloknak úgyis túl sok szabadideje van).

Mivel mi lineáris algebrát tanulunk, ezért okosabbak vagyunk és ismerjük a Gauss elimináció nevű módszert, ami ráadásul könnyen algoritmizálható, így tetszőlegesen rövid időn belül lekörözzük a kölyköt (akár még fogadhatunk is vele).

Ha jobban megnézzük az egyenletrendszert, akkor valójában egy mátrix-vektor szorzás van bal oldalon, tehát Ax = b alakban írható, ahol x = (x, y, z)T, b = (-9, 2, 25)T és A pedig az együtthatókból készített mátrix. A megoldáshoz húzunk egy vidám vonalat, a bal oldalára írjuk a mátrixot, a jobb oldalára pedig b-t.

pic9
Három dolgot szabad csinálni:
  • egy sort végigszorozhatsz egy skalárral
  • egy sort hozzáadhatsz egy másik sorhoz
  • a sorokat tetszőlegesen cserélgetheted
A cél pedig az, hogy ezen műveletek segítségével bal oldalon az egységmátrix jöjjön ki, ekkor jobb oldalon megkaptad a megoldást. Kezdjük rögtön úgy, hogy az első sort kivonjuk a második sorból, a háromszorosát pedig a harmadik sorból.

pic10

Ahol 0 van az jó. A főátlóban mindegy, hogy mi van, amíg nem nulla. A következő elem amit eliminálni kellene az a -12. Az első sort nem használhatod, mert akkor elrontja a 0-t, tehát akkor a második sor -4-szeresét adjuk hozzá a harmadik sorhoz.

pic11

A harmadik sor már tök jó, osszuk le -8-al, hogy könnyebb legyen számolni. Folytassuk az eliminálást: a harmadik sor kétszeresét adjuk hozzá a második sorhoz, a -5-szörösét pedig az elsőhöz.

pic12

A második sor is majdnem jó lett, leoszthatjuk -3-al, és már csak a 2-t kell eliminálni. A második sor kétszeresét vonjuk le az elsőből.
pic13

És a megoldás x = 2, y = -3, z = -1. Látható, hogy szisztematikusan haladtam, először a főátló alatt, aztán fölötte. Néhány dolgot viszont észben kell tartani:
  • ha az elimináció során egy csupa nulla sor jön ki bal oldalon, akkor nincs megoldás mert a sorok lineárisan összefüggnek
  • ha a főátlóban valahol nulla van, akkor cseréld meg azt a sort valamivel
  • ha annyi nulla van, hogy nincs is mit cserélgetned, akkor ki tudod számolni kézzel is :P
Ha ezeket betartod, akkor a módszer könnyen leimplementálható, ugyanúgy haladva, mint a példában. A lényeg, hogy az eliminálandó elem helyén nulla jöjjön ki, az ehhez szükséges szorzó mindig kiszámolható, ha a főátlóban nincs nulla.

Mondok egy még jobb hírt: egy mátrix inverzét ugyanezzel a módszerrel ki lehet számolni. Bal oldalra írod a mátrixot, jobb oldalra pedig az egységmátrixot. A cél ugyanaz: bal oldalon jöjjön ki az egységmátrix, ekkor jobb oldalon ott az inverz.

Ha most az inverz tekintetében nézzük a lineáris egyenletrendszert (amit most Ax = b-nek írok), akkor az megoldható úgy (mindkét oldalt balról megszorozva A-1-el), hogy kiszámolod az x = A-1b szorzatot.


A sok matekos handabandázás után itt az ideje, hogy konkrétan rákanyarodjunk a 3D grafika legfontosabb fogalmaira. A 3D világban kóválygó objektumok viselkedését úgynevezett affin leképezésekkel írjuk le, ami bár leírva bonyolultnak hangzik, valójában speciális mátrixokról van szó. Egy objektum minden eltárolt pontját beszorozva egy ilyen mátrixxal valósítható meg pl. az eltolás vagy forgatás.

Vegyünk két vektorteret (V és W) a T számtest felett, és egy f: V → W függvényt (leképezést). Azt mondjuk, hogy ez az f egy lineáris transzformáció, ha teljesül az alábbi két feltétel (x, y ∈ V, λ ∈ T):

f(x + y) = f(x) + f(y) (additív)
f(λx) = λf(x) (homogén)

Ez konyhanyelven azt jelenti, hogy ha két vektorra alkalmazok valamilyen transzformációt, majd az eredményvektorokat összeadom, akkor ugyanazt kapom, mintha előbb összeadtam volna őket és utána alkalmaztam volna a transzformációt. Ugyanez igaz skalárral való szorzásra is.

Most tegyük fel, hogy V = W és vegyük az e1, ..., en bázist. Az előbbi definíció nyilvánvaló következménye (sőt, ekvivalens vele), hogy egy lineáris leképezés a lineáris kombinációt megtartja, azaz:

pic14

Na de:
pic15

hiszen az ei-k, mint bázis minden vektort előállítanak, speciel az f(ej)-ket is. Mit látunk tehát ebből? Azt hogy minden lineáris transzformáció leírható egy hozzá (és az adott bázishoz) tartozó M := [ μij ] mátrixxal.

Mondok is néhány példát lineáris transzformációkra (a konkrét mátrixokat egy külön bekezdésben sorolom fel): forgatás, nyújtás, tükrözés. Az eltolás nem lineáris transzformáció (hacsak nem toltad el...érted...hehehe...). Könnyű belátni, hogy miért nem: legyen f(x) := x + a, ekkor f(x) + f(y) = x + y + 2a és az nem egyenlő f(x + y)-al.

Ennél tehát többet kéne megengednünk, hiszen jó lenne ha el tudnánk tolni pontokat. Affin transzformációnak nevezünk egy

f(x) = Mx + b

alakú leképezést, ahol M lineáris transzformáció. Itt már nem elég az, hogy V vektortér, hanem kell fölé egy úgynevezett affin tér (később). Van azonban egy rossz hír: ez nem írható le olyan mátrixxal, mint eddig, hanem be kell vezetni a


fogalmát. Formális definíciót sajnos nem találtam, úgyhogy ebből és saját kútfőből voltam kénytelen dolgozni. Előre is elnézést leszarom, ha esetleg valakinek beletaposok a lelkébe. Jelöljük E3-al a háromdimenziós euklideszi teret ((R3, <.,.>)), ekkor a

H3 := { (wx, wy, wz, w)T ahol (x, y, z)T ∈ E3, w ∈ R }

halmazt E3 projektív lezárásának hívjuk (de mivel úgyis pongyola vagyok, homogén térnek fogom hívni). Innentől fogva meg kell különböztetni a pont és a vektor fogalmát, tehát következzen az affin tér definíciója:

Legyen V egy vektortér K felett, és vegyünk egy A nem üres halmazt. Definiáljuk az összeadást egy p ∈ A és egy a ∈ V között az alábbi módon:
  • p + 0 = p
  • (p + a) + b = p + (a + b)
  • ∀q ∈ A, ∃!a ∈ V : q = p + a
Ekkor az A egy affin tér a V vektortér felett, az elemeit pedig hívhatjuk pontoknak. Ha most Rn-et tekintjük V-nek is és A-nak is, akkor mondhatjuk, hogy Rn affin teret alkot önmagával (hiszen az összeadás a fenti módon definiálható). Mivel affin térben nincs egyértelmű origó, a pontokat nem tekinthetjük (hely)vektornak amíg nem rögzítettünk le egy origót (míg vektortérben a két fogalom ekvivalens).

Magyarázkodás nélkül egy p ∈ A elemnek feleltessük meg a (p1, p2, p3, 1)T homogén koordinátákat, amit ünnepélyesen elnevezek pontnak. Egy v ∈ V vektornak pedig feleltessük meg a (v1, v2, v3, 0)T homogén koordinátákat. A vektort is ünnepélyesen elnevezem vektornak, ezzel is diszkriminálva őt. Meglepő módon két pont különbsége egy vektor (a harmadik feltétel miatt).

Nyilván a (wλ1, wλ2, wλ3, w) homogén koordinátából visszakapható az eredeti pont úgy, hogy végigosztasz w-vel. Ha ezt esetleg vektorra próbálnád megtenni, akkor egy értelmezhetetlen pontot kapsz, speciel az olyan irányú párhuzamos egyenesek metszéspontját.

Ezzel a bővítéssel már mondhatjuk azt, hogy az affin transzformációkat 4x4-es mátrixxal írjuk le, mégpedig így:

pic16

A pontok/vektorok pedig homogén koordinátákkal megadva ilyen mátrixxal szorozhatók. Speciel, ha M az egységmátrix, akkor az így kapott 4x4-es mátrix a b vektorral való eltolás mátrixa.


Erről megint nem találtam formális definíciót, de talán nem is baj. Kétféle nevezetes vetítés van, amit tudni illik: perspektív és párhuzamos (szokták merőlegesnek is nevezni valami érthetetlen okból). Itt most a perspektív vetítést vezetem le, mert az az érdekesebb.

Először is, mi az, hogy perspektíva? A hivatalos definíció az, hogy "ahogy lerajzolod a papírra azt amit látsz". Na akkor már csak azt kéne tudni, hogy mi az amit látsz. Például ha veszel két azonos nagyságú labdát, és az egyiket lerakod jó messzire, a másikat meg tartod magad előtt, akkor a távolabbi sokkal kisebbnek látszik. Aki nem hiszi, annak javaslom, hogy mérje meg vonalzóval a Holdat, majd rökönyödjön meg a valódi méretén.

3D grafikában a perspektív vetítést egy csonkagúlával szokták jellemezni (frustum), ez egy a lehetséges definíciók közül. Máris rajzolom:

pic17

A frustum a következő paraméterekkel van megadva:
  • a képernyő szélessége (w)
  • a képernyő magassága (h)
  • látótér szöge (fovy = 2γ)
  • közeli vágósík z értéke (zn)
  • távoli vágósík z értéke (zf)
A feladat levetíteni a P pontot a közeli vágósíkra, tehát keresendő a Q pont y értéke (avagy a QA távolság. Az ábráról is látszik, hogy az EQA és az EPR háromszögek hasonlóak. E és A távolsága zn, tehát azt ismerjük. Ekkor az alábbi egyenlőség teljesül:

pic18

Ahonnan Qy kifejezhető. Van azonban még egy lépés, amit meg kell tenni: ezt a Qy-t le kell normalizálni a [-1, 1] intervallumba. Ez a következőképpen tehető meg:
pic19

Ez nagyon jó, mert zn kiesett. Most nézzük meg ugyanezt az XZ síkban. Az ábrát teljesen ugyanígy kell elképzelni, csak fovy helyett egy fovx = 2δ szöggel.
pic20

A kérdés az, hogy δ hogyan kapható meg γ-ból. Az is megoldható, de ennél van egy egyszerűbb képlet, hiszen ide tan(δ) kellene. Ezt megkapni baromi egyszerű, ugyanis:

pic21

Ez azért tehető meg, mert a közeli vágósík (ha most, mint síklapot tekintjük) oldalai arányosak a képernyőhöz. Ez utóbbi w / h-t nevezzük el aspect-nek.

Most nézzük hogyan építhető a két végeredményből mátrix. Rossz hír: sehogy, mégpedig a Pz-vel való osztás miatt. Ezért a 3D grafikában a vetítés két lépésre van osztva:
  • pont beszorzása a projekciós mátrixxal: a pont ekkor a vágótérbe (clip space) kerül
  • leosztás Pz-vel (perspective division), így kerül a képernyőtérbe (screen space)
A projekciós mátrix eddig a következőképpen néz ki (a fentiek értelmében):

pic22

Ezzel beszorozva P-t kapod meg a (Qx, Qy, ?, Pz) clip space-beli homogén koordinátákat (device coordinates), melyet leosztva a w komponensével megkapod a képernyő koordinátákat a [-1, 1]2 tartományban (normalized device coordinates), de onnan konkrét pixelbe már könnyen átszámolható.

Viszont van még pár kérdés, amit ?-el jelöltem, nevezetesen, hogy mi történjen z értékkel. A raszteres megjelenítésnek egy fontos tulajdonsága a z buffer, amit arra használ, hogy megmondja mely pixel van "legelöl". A z buffer tekinthető egy harmadik képernyőiránynak, legyen ez mélység (d). Ekkor a cél az, hogy Qz-t is kiszámoljuk, ugyanúgy a [-1, 1] intervallumba. Figyelembe kell venni, hogy a második lépésben leosztunk Pz-vel.

Mit lehet tenni? A ?-ek helyett írjuk fel ami történni fog (vagy történhet):

pic23

Hiszen Pw = 1. Végiggondolva adódik, hogy az xy koordinátákat fölösleges lenne belekeverni a buliba, ha μ = 0 lenne, akkor pedig az eredmény egy konstans, tehát λ is és μ is jogos és értelmes. Amit még tudunk az az, hogy ha Pz = zn, akkor az eredmény -1, illetve ha Pz = zf, akkor pedig 1. Ezt vadul írjuk is fel:

pic24

Amit vidáman meg tudunk oldani kézzel is, és az alábbi jön ki:

pic25

És ezzel kész a perspektív vetítési mátrix. Megjegyznék két fontos dolgot: én most itt úgy tekintettem, hogy a z tengely előrefelé mutat, de OpenGL-ben ez nem így van, tehát a mátrix megfelelő két elemét be kell szorozni -1-el. A másik dolog pedig, hogy DirectX-ben nem a [-1, 1] intervallumba kell kerülnie a Qz-nek, hanem a [0, 1]-be. Az így módosított mátrixokat az utolsó bekezdésben leírom.


Ahhoz, hogy a vektoriális szorzatot definiáljuk, le kell rögzíteni a vektortér irányítását (handedness, nem lehet szebben lefordítani), ami pongyolán mondva a koordináta tengelyek irányát jelenti. A jegyzet egy fantasztikus körmondatban definiálja ezt, amit nem fogok leírni, mert meg se próbáltam megérteni. Helyette mindenki előveszi a bal kezét, és a mutatóujját a monitor felé fordítva (z) a középső ujját jobbra (x), a hüvelykujját pedig felfelé (y) tartja. Ez a balkezes koordinátarendszer (mily meglepő). Most mindenki előveszi a jobb kezét, a mutatóujj fölfele (y), a hüvelykujj jobbra (x), a középső ujj pedig magad felé (z) mutat. Ez a jobbkezes koordinátarenszer (mily meglepő). Mindkettő értelmes, ugyanis a fizkában vannak olyan elektromágneses hullámok amelyek balkezes koordinátarendszert alkotnak (elektromos és mágneses mező iránya, illetve a haladási irány), de általában jobbkezest.

Hogy ezt ilyen jól lerögzítettük lehetővé teszi immár a vektoriális szorzat bevezetését, amely geometriailag függ a vektortér irányításától, a definíció azonban megadható egy egyszerű képlettel:

a × b = (a2b3 - a3b2, a3b1 - a1b3, a1b2 - a2b1)T

Ha most jobbkezes koordinátarendszert nézünk, akkor a mutatóujjad a, a középső ujjad b, és a hüvelykujjad a × b. Balkezes koordinátarendszerben a mutatóujj a × b, a középső ujj a, és a hüvelykujj b.

Mindenekelőtt el kell mondani, hogy a vektorszorzás nem kommutatív. Másrészről csak 3 és 7 dimenzióban létezik, máshol nem (viszont más megközelítésekkel általánosítható). Harmadrészt pedig az eredményvektor merőleges az eredeti két vektorra. A középiskolás definíció a szorzat hosszára vonatkozik, azaz |a × b| = |a| |b| sin γ, amiből persze sin γ meghatározható, pláne ha a vektorok normalizáltak.

Ha most veszünk n darab lineárisan független vektort, akkor azt mondjuk, hogy ezek ortogonálisak, ha bármely kettő skaláris szorzata 0 (azaz merőlegesek egymásra). Ha nem ilyenek lennének, akkor R3-ban a vektoriális szorzat segítségével ortogonalizálni lehet őket. Vegyünk 3 darab linárisan független vektort (a, b, c) amelyek nem ortogonálisak és legyen:

c' := a × b
b' := c' × a

Ekkor az a, b', c' vektorok immár ortogonálisak. Magasabb dimenziókban ez értelemszerűen nem alkalmazható, helyette használható a Gram-Schmidt ortogonalizáció nevű módszer. Vegyünk most n darab linárisan független vektort (a1, ..., an) és legyen b1 = a1, ekkor az alábbi módon kiszámolt

pic26

vektorok ortogonálisak. Ha még le is normalizálod ezeket, akkor azt mondjuk, hogy ortonormáltak. Ha egy olyan mátrixod van amelynek oszlopai orthogonálisak, akkor teljesül, hogy A-1 = AT.


Azt, hogy egy mátrixnak létezik-e inverze többféleképpen is meg lehet mondani. Ehhez be kell vezetni néhány új fogalmat. Korábban említettem, hogy egy mátrix oszlopai tekinthetőek oszlopvektoroknak, hasonlóan a sorai pedig sorvektoroknak. Az ezek által generált altereket oszlopvektor- illetve sorvektor térnek hívják. Mivel ezek alterek, van dimenziójuk, sőt az oszlopvektor tér dimenziója megegyezik a sorvektor tér dimenziójával (tetszőleges mátrixra). Ezt a közös dimenziót hívják a mátrix rangjának.

A dimenzió definíciója alapján egy n×n-es mátrix rangja úgy is megfogalmazható, hogy az oszlopai közül hány darab lineárisan független. Ha ez n, akkor létezik inverz, egyébként nem. A Gauss-eliminációs módszerrel ott mutatkozik ez meg, hogy az elimináció során egy csupa 0 sor jön ki, ekkor tudjuk, hogy a sorok összefüggőek és nincs inverz.

(megjegyzés: bár tetszőleges n×m-es mátrixnak nem létezik egyértelmű inverze, külön jobb- és balinverze létezhet)

A továbbiakban egy újabb fontos fogalom, a determináns bevezetéséhez szükséges fogalmakat mutatom be. Bár ez a fajta definíció elég egzakt, a gyakorlatban sohasem használatos, mert rendkívül nehéz számolni vele.

Jelöljük Sn-el az { 1, 2, ..., n } halmaz összes permutációjának halmazát. Ha most veszünk egy σ ∈ Sn permutációt és az i, j ∈ N, i < j indexeket, amelyekre teljesül, hogy σ(i) > σ(j), akkor azt mondjuk, hogy σ(i) és σ(j) inverziót alkot. Ha σ inverzióinak száma páros, akkor meglepő módon párosnak nevezzük, ha páratlan, akkor páratlannak. Jelöljük ezt sgn-el (signum).

pic27

Ami tehát 1 ha σ páros, és -1 ha páratlan. Ekkor egy A ∈ Rnxn mátrix determinánsát a következőképpen lehet definiálni:

pic28

Ha most egy konkrét permutációt nézünk, akkor tehát a mátrix minden oszlopából kiválasztunk egy-egy elemet (a sor nem egyezhet meg), ezeket összeszorozzuk, és még megszorozzuk 1-el vagy -1-el a permutáció paritása szerint. Ha ezt minden permutációra megtettük, akkor az így kapott értékeket összeadjuk. A determinánst szokás így is jelölni: |A|.

Mint mondtam, ezt a definíciót sosem használjuk, mert kezelhetetlen. Vannak azonban nagyon jó tételek, amikkel sokkal egyszerűbben is ki lehet számolni. Kezdjük rögtön azzal, hogy ha az A mátrix diagonális (a főátlóján kívül mindenhol 0), akkor a determinánsa a főátlóbeli elemek szorzata. Következésképp det(I) = 1.

Ami nem látszik annyira, de fontos, hogy a mátrix determinánsa 0 akkor és csak akkor, ha a mátrix oszlopai (sorai) lineárisan összefüggőek. Ekkor inverze sincs.

Most vegyünk egy A ∈ R2x2, tehát 2x2-es mátrixot, ekkor:

pic29

3x3-as mátrixra is adható viszonylag egyszerű képlet, csak épp a használt LaTeX szerkesztő nem bírta egy sorba bezsúfolni (egyébként is idegesít már), úgyhogy rögtön rátérek a Laplace-féle kifejtési tételre.

Jelöljük aldet(A, i, j)-vel annak a részmátrixnak a determinánsát, amit úgy kapunk, hogy az i-edik sort és j-edik oszlopot kihúzzuk A-ban (így kapva egy kisebb mátrixot). Most rögzítsünk le egy i ∈ [1, n]-et, ekkor:

pic30

Tehát kiválasztod a mátrix valamelyik sorát (az i-ediket), és aszerint fejtesz ki, minden lépésben kihúzva a hozzá tartozó sort és oszlopot. A képletben ξij-vel jelölt elemekből a [ ξij ] kofaktor mátrix rakható össze. Megjegyezném, hogy ugyanígy oszlop szerint is ki lehet fejteni (sőt, tetszőleges permutáció szerint??). Példaként alkalmazzuk ezt egy 3x3-as mátrixra az első sor szerint kifejtve (és most |.|-el jelölöm az aldeterminánsokat, hogy kiférjen).

pic31

Ez a módszer kis mátrixokra elég gyors, nagy mátrixokra baromi lassú, de nekünk 4x4-esnél nagyobb úgyse kell. Nagyobb mátrixokra már érdemesebb az LU dekompozíciót használni (következő cikkben lesz róla szó).

Még egy dolog van, ami itt fontos, ugyanis amennyiben a determináns nem nulla, a mátrix inverze kiszámolható az alábbi képlettel:

pic32

Ezt az utóbbi adj(A) = [ ξij ]T mátrixot az A mátrix adjungáltjának nevezzük. Ha A = adj(A), akkor a mátrix önadjungált.


Egy korábbi cikkben már kifejtettem, hogy ez mire használható, de most leírom részletesebben. Vegyünk egy A ∈ Rnxn mátrixot, és a megfelelő I egységmátrixot. Az A mátrix karakterisztikus polinomjának nevezzük az alábbi polinomot:

kA(λ) = det(A - Iλ)

Emlékeztetőül polinom alatt egy véges összeget értünk, amely a0 + a1λ + a2λ2 + ... + anλn alakú. Például az x2 - 3 is egy polinom. A polinom foka a kifejezésben szereplő határozatlan (pongyolán: változó) legnagyobb hatványa (a példában tehát 2).

A kA karakterisztikus polinom gyökeit (a.k.a. megoldásait) nevezzük az A mátrix sajátértékeinek. Az algebra alaptétele szerint egy n-edfokú polinomnak pontosan n darab gyöke van, megjegyzendő azonban, hogy ezek komplex számok is lehetnek, sőt a többszörös gyököket is beleszámoljuk.

Azt mondjuk, hogy a v ∈ Rn vektor az A mátrix sajátvektora, ha teljesül valamilyen λ ∈ K-ra, hogy Av = λv. Vegyük észre, hogy:
Av = λv    ⇔    Av - λv = 0    ⇔   (A - λI)v = 0

Ami egy lineáris egyenletrendszer. Ha most egy picit belegondolunk, hogy mikor lehet ez nulla, akkor rájöhetünk, hogy a skaláris szorzatnál megbeszélt azonosság miatt az A - λI mátrix minden sora merőleges v-re. Na de n dimenziós térben n + 1 vektor lineárisan összefüggő (a mátrix sorai és v), tehát a mátrix sorai nem lehetnek lineárisan függetlenek.

Azaz a fenti egyenletnek akkor és csak akkor van megoldása, ha a lambdás mátrix determinánsa nulla. Tehát kilyukadtunk a karakterisztikus polinomnál, melynek megoldásai a most λ-val jelzett sajátértékek. A karakterisztikus polinom megkapható az említett Laplace-féle kifejtési tétellel (de mazochisták használhatják az eredeti definíciót). A gyökök kiszámolása után a sajátvektorok meghatározása már történhet ugyanúgy Gauss eliminációval.

Természetesen, ha v egy sajátvektor, akkor a definíció szerint αv is az valamilyen α ∈ R-re. A sajátvektorok tehát egy alteret feszítenek ki, amit meglepő módon sajátaltérnek hívnak. A sajátértékeknek a halmazát pedig spektrum-nak szokták nevezni.

Gyakorlati alkalmazás például az objektumhoz igazított befoglaló doboz kiszámolása. Szélsőséges esetben egy előre transzformált ponthalmazból is visszanyerhető egy (lineáris) transzformációs mátrix, de megjegyezném, hogy ez nem feltétlenül az, amivel eredetileg transzformálták (mint ahogy a befoglaló doboz sem az amit elvárnál).


A duális tér fogalmát analízisben szokás inkább definiálni normált terekre, de én most azt nem fogom végigvezetni. Ha most veszünk egy V vektorteret T felett, akkor egy φ : V → T lineáris leképezést szokás lineáris funkcionálnak is nevezni, de ez a lineáris algebrában vizsgált esetekben kicsit pongyola feltételezés.

(megjegyzés: a lineáris funkcionál tehát egy speciális esete a ineáris transzformációknak, amikor is W = T).

Egy T feletti V vektortér duális tere az összes φ : V → T lineáris leképezések halmaza, amelyet V*-al jelölünk. Ha V elemei függvények, akkor V* elemeit joggal nevezhetjük lineáris funkcionáloknak (a.k.a. függvény függvénye).

Az affin transzformációknál megbeszéltük, hogy minden lineáris leképezés megadható mátrix alakban (a bázisos képletekből levezetve), tehát hasonló gondolkozással mondhatjuk, hogy egy lineáris funkcionál megadható 1×n-es mátrixxal, amit nevezzünk sorvektornak.

pic33

Innentől érthető, hogy miért kell megkülönböztetni a sor- és oszlopvektorokat, hiszen ha egy lineáris funkcionál megadható sorvektorral, akkor bódult állapotban mondhatunk olyanokat, hogy Rn duális tere önmaga. Józan állapotban viszont ez elég nagy ökörség, mint majd mindjárt látni is fogjuk.

Egy kicsit visszakanyarodnék a bázistranszformációhoz, ahol is a célbázisbeli koordináták még mindig kiszámolásra várnak (de a megoldáshoz már fel vagyunk vértezve). Emlékeztetőül tehát a

pic3b

lineáris egyenletrendszert szeretnénk megoldani a ξ1, ..., ξn ismeretlenekre. Továbbra is jelöljük A = [ μij ]-vel az együtthatókból alkotott mátrixot.

Legyen megint E = [ e1, ..., en ] a kiinduló bázis és F = [ f1, ..., fn ] a célbázis, és mint ahogy megbeszéltük
F = EA teljesül (mint mátrixszorzás). Írjunk most fel egy tetszőleges x ∈ V vektort a kiinduló bázisban:

pic34

És jelöljük xe = (λ1, ..., λn)T-vel az x vektor kiinduló bázisra vonatkozó koordináta oszlopát. Ekkor az előbbi lineáris kombináció felírható mátrix-vektor szorzásként:

pic35

De mivel fi is bázis, az is hasonlóan előállítja x-et, tehát:

pic36

És az egyenlet mindkét oldalát balról beszorozva E-1-el, majd A-1-el kapjuk, hogy:

pic37

És megkaptuk a keresett xf = (ξ1, ..., ξn)T koordináta oszlopot a célbázisban. A koordináta oszlopok tehát a bázisváltás mátrixának inverzével transzformálódnak. Ezen fellelkesedve azt mondjuk, hogy az x ∈ V vektorok kontravariánsak.

Most vegyünk egy φ = (a1, ..., an) lineáris funkcionált V*-ból és vezessük be az alábbi jelölést:

pic38

Ami tehát a funkcionál alkalmazva az i-edik kiinduló bázisvektorra (és továbbra is skalár). Következő lépésként kezdjük el számolni ugyanezt a célbázisban:

pic39

Az átalakítás megtehető, mert φ lineáris. Az eredmény még mindig n darab skalár, amit írjunk fel egy sorvektorba és jelöljük
φ(E) = (φ1(E), ..., φn(E))-vel. Ekkor úgy mint előbb, az egyenlőség felírható mátrix-vektor szorzásként, azaz:

pic39b

A lineáris funkcionál tehát ugyanúgy az A mátrixxal transzformálódik, mint a bázis. Ezt pedig úgy mondjuk, hogy a φ ∈ V* egy kovariáns vektor.


Aki 3D grafikázott már annak furcsák lehetnek az itt leírtak, mert látszólag pont fordítva van, mint ahogy azt alkalmazni szoktuk. Úgyhogy akkor most kifejteném, hogy miről volt szó eddig és a 3D grafikában miért van (látszólag) máshogy.

Mit jelent a bázistranszformáció? Szemléltetésül egy egyszerű kétszeres nyújtást fogok segítségül hívni, azt is csak 2D-ben, hogy tudjak rajzolni. Bal oldalon van a kiinduló bázis kékkel, jobb oldalon pedig a célbázis pirossal.

pic50a

Amiről a cikk elején beszéltünk az volt, hogy ugyanazt a vektort írjuk fel a másik bázisban. Könnyű kiszámolni, hogy a kék bázisban a koordináta oszlop (3/4, 5/4)T a piros bázisban pedig (3/8, 5/8)T, azaz valóban a bázisvektorok transzformációjának inverzével szorzódik (tehát mivel kétszeres nyújtást nézünk, feleződik).

Általában viszont nem ugyanazt a vektort akarod, hanem a lineáris kombinációt megtartva keresed az új vektort, azaz egy lineáris transzformációt alkalmazol:

pic50b

Ez tehát egy alapvető különbség a bázistranszformáció és a lineáris transzformáció között. A kavarodást az okozza, hogy Rn-ben a koordináta oszlopok is és a duális tér elemei is ugyanolyan vektornak tekinthetők, sőt affin térként tekintve rá még a pontok is ugyanúgy írhatóak le.

Rn tehát ilyen "sokféleképpen értelmezhető" tér (de azért ne legyen félreértés: rengeteg olyan fontos tér van, ami nem ilyen!). Most tekintsük úgy, hogy Rn affin tér és vegyünk egy p pontot. Rögzítsük le az origót a (0, 0, 0) pontba, ekkor p-t tekinthetjük helyvektornak, tehát használható rá a mátrixxal való szorzás. Mostantól fogva az objektumod minden pontja ilyen pont. Pont ilyen. Egy lineáris transzformációt (M) alkalmazva rá p' = Mp az új pont. Ez a lila nyíl, és kontravariáns vektor. Pont.

Most vegyünk egy funkcionált, mondjuk a példa kedvéért egy síkegyenletet, ami a klasszikus

ax + by + cz + d = 0

egyenlettel írható le. Ami nem lineáris funkcionál, csak hogy könnyű legyen a dolog. Affin funkcionál nincs. Segítségül hívva a homogén koordinátákat viszont leírható így:
(a, b, c, d) ⋅ (x, y, z, 1)T = 0

Ebbe az egyenletbe írjuk be középre az egységmátrixot, mégpedig így:

(a, b, c, d) ⋅ M-1M ⋅ (x, y, z, 1)T = 0

De persze a mátrixsszorzás asszociatív, tehát azt lehet mondani, hogy a síkegyenletet, mint kovariáns vektort a lineáris trafó inverz transzponáltjával kell szorozni. Ez nem a zöld nyíl, de hasonlóan képzelhető el és például az objektum normálvektorait így kell trafózni.

A bázistranszformáció nem keverendő össze a lineáris transzformációval. Az alábbi táblázatban mégegyszer összefoglalom a lényeget:

bázistranszformáció (A) affin/projektív transzformáció (M)
kontravariáns ξ = A-1λ p' = Mp
kovariáns φ(F) = φ(E)A φ' = φM-1


A bázistrafó tehát koordináta oszlopokra, illetve funkcionál értékekre vonatkozik, az affin trafó viszont pontokra/vektorokra illetve magára a funkcionálra. A táblázatból a második oszlopot kell megjegyezni, ugyanis az affin és projektív trafók használatosak mindenre 3D grafikában.


A cikk végén következzenek a leggyakrabban használt (lineáris és projektív) transzformációk mátrixai, ahol nem írom ki külön ott balkezes koordinátarendszerben. Egyrészt azért mert a DirectX-es cikkekben azt használok, másrészt mert sokkal természetesebb mint az elcseszett OpenGL-féle jobbkezes maszturbálás (de valójában csak a vetítések és némelyik forgatás különböző).

pic40
eltolás az (x, y, z)T vektorral
pic41
nyújtás x, y, z szeresre
(spec.: ha < 0, akkor tükrözés)
pic42
nyírás a z tengely mentén
pic43
forgatás az x tengelyen θ szöggel
pic44
forgatás az y tengelyen θ szöggel
pic45
forgatás az z tengelyen θ szöggel
pic46
párhuzamos (merőleges) vetítés
l = left, r = right, stb.
pic47
perspektív vetítés (OpenGL)
α = aspect, γ = fovy / 2
pic48
perspektív vetítés (DirectX)
n = near, f = far

Ugye mindenki látja a transzponálás jelét a DirectX-es mátrixban? És ugye mindenki látja, hogy az y tengelyen való forgatásnál máshol van a negatív szinusz? Részletesebben lásd a megfelelő DirectX és OpenGL függvények dokumentációját.


Summarum

Régen volt ennyi kép egy cikkben. A gyakorlatban sokkal könnyebb alkalmazni az itt leírtakat, amíg a "klasszikus" 3D grafikánál maradsz. A haladóbb algoritmusok megértésehez viszont még ennél is mélyebbre kell menni, például a mátrixok még tovább általánosíthatóak tenzorokká, a mátrixsszorzás pedig kontrakcióvá. És igen, azt is kellett már alkalmaznom.

Elképzelhető, hogy később hozzáveszek még néhány bekezdést a cikkhez, ugyanis ez még csak a jéghegy csúcsa. A következő cikkben numerikus analízisről lesz szó, ugyanis az is igen gyakran használatos 3D grafikában.


Höfö:

  • Emésszed meg az olvasottakat...
  • Mi az, hogy nem érted...?

back to homepage

Valid HTML 4.01 Transitional Valid CSS!