OpenGL/Matriisi 3d-grafiikassa
Moni kuvittelee, että 3d-grafiikkaan liittyvä matematiikka olisi monimutkaista. Sen kulmakivi on matriisi, jonka käyttäminen on hyvinkin suoraviivaista – suorastaan lineaarialgebraa. Muutamassa asiassa täytyy vain luottaa itseään viisampiin matemaatikoihin, jotka ovat ratkaisseet asiat ohjelmoijan puolesta.
Tämän luvun voi ohittaa, jos pienikin määrä matematiikkaa tuottaa harmaita hiuksia. Kannattaa kuitenkin kokeilla, sillä asia on helppolukuista.
Matriisi
[muokkaa | muokkaa wikitekstiä]Matriisi on kaksiulotteinen taulukko. Koon m × n matriisi piirretään seuraavasti:
4×4-matriisit ovat hyödyllisiä 3d-grafiikassa, koska niillä voidaan liikutella nurkkapisteitä tehokkaasti. Liikuttelua kutsutaan muunnokseksi (engl. transformation) ja siihen soveltuvaa matriisia muunnosmatriisiksi (engl. transformation matrix). Muunnoksia voidaan ketjuttaa lukemattomia määriä, ja lopputulos on silti yksi ainoa 4×4-matriisi.
Muunnosmatriisien luokittelu
[muokkaa | muokkaa wikitekstiä]Ehdottomasti tärkeimmät muunnosmatriisityypit ovat:
- translaatiomatriisi, joka siirtää pisteitä johonkin suuntaan
- rotaatiomatriisi, joka kiertää pisteitä origon kautta kulkevan akselin ympäri
- skaalausmatriisi, joka suurentaa pistepilveä kertomalla niiden koordinaatit jollakin luvulla
- projektiomatriisi, joka projisoi kolmiulotteiset koordinaatit kaksiulotteiselle näyttöruudulle
Jokainen ylläolevista kuuluu affiinikuvausten (engl. affine transformation) joukkoon, sillä:
- Jos kolme pistettä on samalla suoralla, ne ovat samalla suoralla myös affiinikuvauksen jälkeen.
- Kyseisten pisteiden etäisyyksien suhde säilyy.
Lisäksi kaikki paitsi translaatiomatriisi ovat lineaarikuvauksia (engl. linear transformation). Translaatiomatriisi ei nimittäin aina kuvaa origoa origoksi.
Muunnosmatriisien muodostamista käsitellään pintapuolisesti luvun lopussa. Tästä eteenpäin vain oletetaan, että se osataan tehdä – ja itse asiassa niin OpenGL osaakin.
Muunnosten ketjuttaminen on kertolaskua
[muokkaa | muokkaa wikitekstiä]Muunnoksia voidaan ketjuttaa kertomalla muunnosmatriiseja erityisellä tavalla. Halutaan vaikkapa tehdä järjestyksessä seuraavat muunnokset:
- Kierretään pisteitä x-akselin ympäri −10 astetta.
- Liikutetaan pisteitä z-akselin suuntaan 5 yksikköä.
- Kierretään pisteitä y-akselin ympäri 5 astetta.
Tällöin kerrotaan muunnoksia vastaavat matriisit päinvastaisessa järjestyksessä:
- M = M3 M2 M1
Lopputulos on hämmästyttävä: M sisältää kaikki muunnokset oikeassa järjestyksessä, vaikka siinä on yhä vain 4 × 4 lukua!
Muunnos on kertolasku
[muokkaa | muokkaa wikitekstiä]Miten matriiseilla sitten muunnetaan pisteitä? Kuten voi arvata: Matriisi ja pisteen paikkavektori kerrotaan keskenään, jolloin tulos on muunnettu paikkavektori.
- v' = M v
Nämä ”taianomaiset” matriisien kertolaskut ovat myös tehokkaita: Ne eivät tarvitse hitaita trigonometrisiä funktioita eivätkä edes jakolaskuja, vaan ainoastaan kertolaskuja. Tähän verrattuna matriisin muodostaminen voi olla hitaanpuoleista; onneksi matriisi tarvitsee muodostaa vain kerran kymmenistä tuhansista pisteistä koostuvalle 3d-mallille.
Vaikka OpenGL-ohjelmoijan ei varsinaisesti tarvitsekaan tietää matriisien kertolasku- tai muodostussääntöjä, perusteellisuuden vuoksi ne vielä esitellään luvun lopuksi.
Matriisien kertolasku
[muokkaa | muokkaa wikitekstiä]Matriisien kertolaskusäännöt on ehkä helpointa muistaa vektorien pistetulon avulla. Olkoon A ja B kerrottavat matriisit. Ajatellaan, että matriisi A on sarake rivivektoreita; B on puolestaan rivi sarakevektoreita. (C-ohjelmointikielessäkin kaksiulotteinen taulukko muodostetaan sisäkkäisillä yksiulotteisilla taulukoilla!) Kertolaskun lopputulos saadaan pistetuloilla seuraavaan tapaan:
Pistetulo kun on määritelty vektoreille kaikissa ulottuvuuksissa:
- a · b = a1 b1 + a2 b2 + ...
Matriisin ja vektorin kertolasku
[muokkaa | muokkaa wikitekstiä]Matriisin ja vektorin kertolasku on matriisien kertolaskun erikoistapaus: vektoria ajatellaan matriisina, jossa on yksi sarake. Jotta pistetulo olisi mahdollinen, 4×4-matriisien kohdalla kolmiulotteiseen vektoriin täytyy lisätä uusi komponentti w = 1. Sitä käytetään hyväksi perspektiiviprojektiossa.