Artikkelit

Artikkelit olivat Suomipelit.comissa sivuston sulkeuduttua. Näin ollen niihin saattaa sisältyä rikkinäisiä linkkejä tai epämääräisiä viitteitä asioihin, joita ei enää ole olemassa, ja joskus jokin saattaa näkyä väärin.

Palaa artikkelilistaan

Matriisimatematiikkaa peliohjelmoijille

Matriisit ovat tehokas työkalu peliohjelmoinnissa. Tämä artikkeli opettaa sinulle matriisimatematiikan alkeet ja vähän enemmänkin. Voidaksesi lukea tämän artikkelin sinulla täytyy olla kohtalainen pohjatieto vektoreista.
PÄIVITETTY 19.11.2006

23.4.2004 julkaistun artikkelin on kirjoittanut markus.

  1. 1. Johdanto
  2. 2. Matriisien esittäminen tietokoneen muistissa
  3. 3. Matriisien laskutoimitukset
  4. Geometrinen tulkinta
  5. Tensoreista
  6. Kompleksiluvuista vaihtoehto matriiseille

1. Johdanto #

PÄIVITYS 19.11.2006
Tämä artikkeli rikkoutui artikkelialueen uudistamisen myötä viime syksynä.
Korjaan artikkelin joskus, mutta sitä odotellessa tämä artikkeli on saatavana pdf-muodossa:
http://www.suomipelit.com/files/artikkel...


Artikkeli on luettavissa myös Google-Docs palvelussa:
http://docs.google.com/View?docid=ddhjkx...


---------------------------------


Matriisi on kokoelma vektoreita, siinä missä vektori on kokoelma skalaareita eli yksittäisiä lukuja. Matriisia merkitään yleensä seuraavanlaisena hakasuluilla rajattuna taulukkona:


Jossa jokainen sarake (eli pystyrivi) on yksi vektori. Edellisessä matriisissa oli siis vektorit ( a, d, g ), ( b, e, h ) ja ( c, f, i ). Matriisissa voi olla mielivaltainen määrä rivejä ja sarakkeita, eikä niitä välttämättä ole yhtä monta. Matriisia, jossa on vain yksi sarake kutsutaan (yllätys yllätys) vektoriksi ja matriisia, jossa on yhtä monta riviä ja saraketta kutsutaan neliömatriisiksi. Matriisin kokoa merkitään yleensä RIVEJÄxSARAKKEITA. Esim.

olisi 3x2 matriisi ja

2x4 matriisi.

2. Matriisien esittäminen tietokoneen muistissa #

Matriisi kannattaa tallentaa yksiulotteiseksi taulukoksi sarakkeittain eli matriisi


tallennettaisiin muotoon: { a, d, g, b, e, h, c, f, i }.

Esim. jos haluaisimme luoda C/C++ kielellä edellä esitetyn 3x3 matriisin nimeltä m, käyttäisimme seuraavaa:

float m[9] = { a, d, g, b, e, h, c, f, i };


Mikään ei tosin estä matriisin tallentamista riveittäin, mutta tällöin matriisin vektorit eivät olisi muistissa "eheinä" perätysten. Esim.

olisi riveittäin tallennettuna { a, b, c, d, e, f, g, h, i }.

Tietenkin voidaan käyttää myös kaksiulotteista taulukkoa, mutta useimmat ohjelmointikielet tallentavat kaksiulotteiset taulukot muistiin riveittäin.

3. Matriisien laskutoimitukset #

Kuten tavallisilla luvuilla ja vektoreillakin, myös matriiseilla voi laskea. Matriiseille on määritelty paljonkin laskutoimituksia, joista seuraavassa esitellään tarpeelliset.

3.1 Yhteenlasku

Yhteenlasku on matriisien laskutoimituksista hyödyttömimpiä, mutta esittelen yhteenlaskun ihan vain sen yksinkertaisuuden vuoksi. Matriisien yhteenlasku toimii samoin, kuin vektorienkin yhteenlasku.


Eli jokainen matriisin alkio lasketaan yhteen vastaavan kanssa toisessa matriisissa. Kummankin yhteenlaskettavan matriisin täytyy tietenkin olla yhtä suuria. Summa matriisista tulee saman kokoinen kuin summattavat matriisit.

3.2 Kertolasku

Kertolasku on matriisien laskutoimituksista tärkein, mutta myös yhteenlaskua huomattavasti monimutkaisempi. Kertolaskussa ensinnäkin kerrottavien matriisien ei tarvitse olla samankokoisia, mutta kertojamatriisissa täytyy olla yhtä monta saraketta, kuin kerrottavassa matriisissa on rivejä. Tällöin tulomatriisiin tulee yhtä monta riviä, kuin on kertojamatriisissa ja yhtä monta saraketta, kuin on kerrottavassa matriisissa. Esim. 4x2 matriisin ja 2x3 matriisin tulona syntyisi 4x3 matriisi. Matriisien kertolasku ei ole ns. kommutatiivinen eli jos M ja N olisivat matriiseja, niin M*N ei anna välttämättä samaa tulosta kuin N*M.

Kertolasku suoritetaan seuraavasti. Käy tulomatriisin alkiot läpi yksi kerrallaan. Valitse kertojamatriisista se rivi, johon vuorossa oleva alkio kuuluu ja kerrottavasta matriisista se sarake, johon vuorossa oleva alkio kuuluu. Kerro näiden rivin ja sarakkeen kaikki vastaavat alkiot keskenään ja laske tulot yhteen. Seuraava kuvasarja havainnollistaa kertolaskun etenemistä 2x3 ja 3x2 matriisien kertolaskussa. (Näiden matriisien tulo on 2x2 matriisi.)

Seuraavassa lisää esimerkkejä.

On olemassa yhdenlainen matriisi, joka käyttäytyy samoin kuin numero 1 tavallisten lukujen kertolaskussa. Sitä kutsutaan yksikkömatriisiksi (englanniksi identity matrix) ja merkitään symbolilla I. Yksikkömatriisille I siis pätee: I*M=M*I=M. Yksikkömatriisi on aina muotoa:

Eli vinottaisakselilla on ykkösiä ja kaikkialla muualla nollia. Esim. 4x4 yksikkömatriisi:

Johtuen yksikkömatriisin englanninkielisestä nimestä monet, jopa jotkut matematiikan opettajat, kutsuvat sitä välillä identiteettimatriisiksi. Virallinen suomennos on kuitenkin yksikkömatriisi!

3.3 Transponointi

Transponointi on yksinkertainen toimenpide, siinä matriisi yksinkertaisesti "pyöräytetään" vinottaisakselinsa ympäri niin, että sarakkeet muuttuvat riveiksi ja rivit sarakkeiksi. Transponointia merkitään laittamalla T-kirjain matriisin oikeaan ylänurkkaan. Esim.

Jos matriisi transponoidaan kaksi kertaa saadaan alkuperäinen matriisi.

3.4 Determinantti

Matriisin determinantti vastaa lähinnä itseisarvoa. Sitä merkitään vaihtamalla matriisin ympärillä olevat hakasulkeet pystyviivoihin. Matriisia, jonka determinantti on 0, kutsutaan singulaariseksi.

2x2 matriisin determinantti on

3x3 matriisin determinantti voidaan laskea 2x2 matriisin determinantin avulla.

4x4 matriisin determinantti voidaan laskea 3x3 matriisin determinantin avulla.

Ja näin edespäin. NxN matriisin determinantti voidaan aina laskea (N-1)x(N-1) matriisin determinantin avulla. Käydään vain läpi matriisin ylin rivi alkio kerrallaan. Kerrotaan vuorossa olevalla alkiolla, sen matriisin determinantti, joka jää kun alkuperäisestä matriisista poistetaan ylin rivi ja se sarake, johon vuorossa oleva alkio kuuluu. Vuoron perään vähennetään ja vuoron perään lisätään tulo kokonaisdeterminanttiin.

3.5 Käänteismatriisi

Matriisin ja sen käänteismatriisin tulo on aina yksikkömatriisi, eli jos M on matriisi ja N sen käänteismatriisi niin M*N=N*M=I. Jos matriisi on singulaarinen, sillä ei ole käänteismatriisia. Käänteismatriisia merkitään laittamalla -1 matriisin oikeaan yläkulmaan. Esim.

koska

Se kuinka jonkin mielivaltaisen matriisin käänteismatriisi saadaan laskettua on aika monimutkaista. Itseasiassa ei ole olemassa valmista kaavaa, jolla minkä tahansa matriisin käänteismatriisi saadaan laskettua. On olemassa joitakin menetelmiä, joilla käänteismatriisi voidaan löytää, mutta en käsittele niitä tässä. Muutamassa erikoistapauksessa käänteismatriisin laskeminen on kuitenkin helppoa. Esim. yksikkömatriisin käänteismatriisi on aina yksikkömatriisi ja matriisin, jonka determinantti on tasan 1, käänteismatriisi on aina sama kuin sen transpoosi.

Seuraavassa kuitenkin valmiit kaavat 2x2, 3x3 ja 4x4 matriisien käänteismatriisien laskemiseen. Kaavoissa merkintä |M| tarkoittaa kyseessä olevan matriisin determinanttia.

Geometrinen tulkinta #

Siinä missä vektorin voidaan ajatella esittävän suuntaa tai paikkaa, voidaan neliömatriisin ajatella esittävän koordinaatistoa, niin että matriisin jokainen vektori (sarake) esittää koordinaatiston yhtä akselia. Tällöin 2x2 matriisi esittäisi 2-ulotteista koordinaatistoa ja 3x3 matriisi 3-ulotteista koordinaatistoa. Sanotaankin, että matriisi virittää avaruuden. 2x2 matriisissa ensimmäinen sarake on x-akseli ja toinen y-akseli. 3x3 matriisissa on vielä yksi sarake, joka on z-akseli.

Kun matriisilla kerrotaan vektori (Kyllä! Matriisilla voi kertoa vektorin, koska vektori on itseasiassa matriisi, jossa on vain yksi sarake), muuntaa matriisi vektorin omasta koordinaatistostaan globaaliin koordinaatistoon. Sanotaan, että matriisi kuvaa vektorin toiseksi.

Esim. 1:

Matriisi


virittää koordinaatiston, jossa x-akseli on normaali, mutta y-akseli on ylösalaisin. Ks. kuva.

Jos tällä matriisilla nyt kerrotaan vektori, pitäisi vektorinkin kääntyä ylösalaisin. Kokeillaanpa. Otetaan vektori ( 2, 4 ).

Saatiin siis vektori ( 2, -4 ). Eli vektori todellakin keikahti ylösalaisin.

Esim. 2:

Matriisi

virittää koordinaatiston, jossa x-akseli ja y-akseli ovat vaihtaneet paikkaa. ks. kuva:

Jos tällä matriisilla nyt kerrotaan vektori, pitäisi vektorinkin x ja y komponentin vaihtaa paikkaa. Tehdäänpä taas koe. Otetaan vektori ( 7, 3 ).

Kas kummaa. Vektorin x ja y komponentti todellakin vaihtoivat paikkaa.

Esim. 3:

Toimiikohan kaikki myös 3-ulotteisessa koordinaatistossa? Matriisi

virittää koordinaatiston, jossa kaikki koordinaattiakselit ovat kitistyneet puoleen. Kun tällä matriisilla nyt kerrotaan vektori pitäisi vektoristakin tulla puolta lyhempi. Otetaan vektori ( 1, 2, 3 ).

Saatiin vektori ( 0.5, 1, 1.5 ), joka todellakin on puolta lyhempi kuin vektori ( 1, 2, 3 ).

Huom! Kuvattu vektori voidaan kuvata takaisin alkuperäiseksi kertomalla se alkuperäisen matriisin käänteismatriisilla. Eli Jos M on matriisi ja N sen käänteismatriisi ja v ja u ovat vektoreita, niin jos M*v=u, niin N*u=v .

4.1 Kiertomatriisi

Kiertomatriisi (englanniksi rotation matrix) on matriisi, joka kiertää eli pyörittää vektoria.

Kaksiulotteisessa avaruudessa kiertomatriisin muodostaminen on helppoa. Meidän täytyy vain löytää koordinaatiston uudet akselit, kun sitä kierretään kulman a verran .

Eli matriisista tulisi seuraavanlainen, kun x-akseliksi laitetaan vektori ( cos(a), sin(a) ) ja y-akseliksi vektori ( -sin(a), cos(a) ):

Kokeillaanpa kiertää vektoria ( 4, 3 ), 90 astetta. Silloinhan meidän pitäisi saada vektori (-3, 4 ). Vai mitä.

Näkyi toimivan.

3-ulotteisessa avaruudessa tilanne käy vähän hankalemmaksi, sillä kierto tapahtuu akselin ympäri, eikä pisteen kuten tasolla. Kiertomatriisit voidaan muodostaa siitä huolimatta pienellä pohdiskelulla.

x-akselin ympäri:

y-akselin ympäri:

ja z-akselin ympäri:

Mielivaltaisen akselin ( u, v, w ) ympäri:


4.2 Siirtomatriisi

Siirtomatriisi (englanniksi translation matrix) siirtää paikkavektoria toisen vektorin verran. Ei ole kuitenkaan mahdollista muodostaa NxN matriisia, joka siirtää N-komponenttista vektoria, vaan tarvitaan (N+1)x(N+1) matriisi N-komponenttista vektoria varten. Tästä kuitenkin seuraa se ongelma, että NxN matriisilla ei voi kertoa (N-1) komponenttista vektoria. Meidän onkin lisättävä vektoriin yksi ylimääräinen komponentti. Merkittäköön sitä vaikka kirjaimella w, ja sen arvon on oltava aina 1.

3x3 siirtomatriisi (joka siis siirtää 2-ulotteista vektoria, jonka kolmas ylimääräinen komponentti on 1) on muotoa:

ja 4x4 siirtomatriisi (joka siis siirtää 3-ulotteista vektoria, jonka neljäs ylimääräinen komponentti on 1 ) on muotoa:

Kokeillaanpa. Siirretään vektoria ( -3, 8 ) vektorin ( 5, 2 ) verran. Silloin tulokseksi pitäisi tulla vektori ( 2, 10 ).

Tulokseksi tuli todellakin vektori ( 2, 10 ), kunhan ensin ylimääräinen komponentti 1 jätetään lopusta pois.

4.3 Matriisien yhdistäminen

Matriiseja voidaan yhdistää kertomalla ne keskenään. Jos esimerkiksi haluaisimme kiertää vektoria ensin 10 astetta x-akselin ympäri ja sitten 60 astetta z-akselin ympäri, meidän ei tarvitse ensin kertoa vektoria 10 asteesta tehdyllä kiertomatriisilla ja sitten 60 asteesta tehdyllä kiertomatriisilla, vaan voimme kertoa matriisit keskenään ja kertoa vektorin vasta tulomatriisilla. Jotta olisi mahdollista kertoa keskenään NxN kiertomatriisi ja (N+1)x(N+1) siirtomatriisi, on kiertomatriisiin lisättävä yksi ylimääräinen rivi ja sarake. Nämä rivit täytetään nollalla, paitsi oikea alakulma, johon tulee 1. Huomaa, että kertolaskujärjestyksellä on väliä. Jos meillä olisi kiertomatriisit R1 ja R2, niin R1*R2 tarkoittaisi sitä, että ensin kierrettäisiin R1 matriisin verran ja sitten R2 matriisin verran. R2*R1 taas tarkoittaisi, että ensin kierretään R2 matriisin verran ja sitten vasta R1 matriisin verran.

Esim. Jos otetaan vektori ( 5, 3 ) ja siirretään sitä ensin vektorin ( -6, 2 ) verran ja kierretään sitten 270 astetta. Niin silloinhan meidän pitäisi saada tulokseksi vektori ( -3, -3 ). Kokeile vaikka, siirrä vektori ( 5, 3 ) alkamaan (origon sijasta) pisteestä ( -6, 2 ) ja kierrä sitten 270 astetta vastapäivään, niin sen kärki on todellakin pisteessä ( -3, -3 ).


4.4 Asentomatriisi

2-ulotteisessa tapauksessa eli tasolla, objektin asennon kuvaamiseen riittää yksi luku: kulma, jonka verran objekti on kiertynyt alkutilanteesta. Kulman sijaan voitaisiin käyttää myös 2x2 matriisia, joka kuvaa objektin omaa, "paikallista" koordinaatistoa. Tämä matriisi olisi tietenkin alkutilanteessa yksikkömatriisi:

Kun objektia halutaan pyörittää, objektin asentomatriisilla vain kerrotaan kiertomatriisi ja meillä on uusi asento. Samaan matriisiin voidaan tallentaa asennon lisäksi myös objektin sijainti. Lisätään vain yksi rivi ja sarake. Tällöin objektin x-koordinaatti tulee matriisin oikeaan yläkulmaan ja y-koordinaatti oikealle keskelle. Kun sijaintikin on mukana matriisissa voidaan objektia myös siirtää, kertomalla sillä siirtomatriisi. Kierto ja siirto samassa, kätevää. Jos objektin sijainnin koordinaatit halutaan tietää, saadaan ne ottamalla matriisin oikeanpuolinmaisin sarake. Objektin paikalliset koordinaatti akselit taas ovat matriisin kaksi ensimmäistä saraketta 2-ulotteisessa tapauksessa ja kolme ensimmäistä 3-ulotteisessa tapauksessa.

R:llä merkitty alue oli siis se alkuperäinen 2x2 asentomatriisi.

Esim. Avaruusaluksen aseen piippu sijaitsee koordinaateissa ( 2, 1 ) suhteessa alukseen ja sen tulitus suunta on vektorin ( 1, 0 ), eli x-akselin suuntainen. Alus siirtyy koordinaatteihin ( 6, 4 ) ja kiertyy 45 astetta. Mikä on aseen piipun uusi sijainti ja suunta?

Rakennetaan alukselle asentomatriisi. Kierto tulee vasempaan ylänurkkaan ja sijainti oikeaan reunaan.

Matriisi siis voitiin rakentaa "suoraan". Samaan lopputulokseen olisi tietenkin päästy jos aluksen asentomatriisiksi olisi asetettu yksikkömatriisi. Kerrottu sillä vektorista ( 6, 4 ) tehty siirtomatriisi ja kerrottu tuloksella kulmasta 45 tehty kiertomatriisi.

Kerrotaan matriisilla aseen piipun sijainti.

Eli piipun uusi sijainti on noin ( 6.7, 6.1 ). Entäpä suunta? Kerrotaan suuntavektori samalla matriisilla.

Mitä ihmettä! Tulos on selvästi virheellinen! Onhan vektori ( 6.7, 4.7 ) aivan eripituinenkin kuin ( 1, 0 ). Asentomatriisi, jossa on sijainti mukana muodostaakin ongelman niiden vektorien kanssa, jotka ilmoittavat sijainnin sijasta suuntaa, sillä niitä halutaan vain kiertää. Ei siirtää. Ongelma ratkaistaan kertomalla tällaiset vektorit asentomatriisin transpoosin käänteismatriisilla, josta on poistettu alin rivi ja oikeanpuolinmaisin sarake. Koska aluksen matriisin deteminantti on tasan 1, on sen käänteismatriisi sama kuin sen transpoosi. Transpoosin transpoosi on puolestaan alkuperäinen matriisi. Eli voimme suoraan poistaa alimman rivin ja oikean sarakkeen. Itseasiassa kierto-, siirto- ja asentomatriisin ja kaikkien näistä kertomalla saatujen matriisien determinantti on aina tasan 1.

Eli uusi suunta on noin ( 0.7, 0.7 ).

Huomaa jälleen kertolaskujärjestys. Jos objektin asentomatriisi on M ja R on kiertomatriisi, niin M*R tarkoittaa, että objektia kierretään sen oman akseliensa ympäri, kun taas R*M tarkoittaa että objektia kierretään "globaalien" akselien ympäri. Tällä on merkitystä etenkin 3-ulotteisessa tapauksessa.

3-ulotteisessa tapauksessa meidän on talletettava objektin 3x3 asentomatriisi, tai 4x4 matriisi jos sijaintikin halutaan mukaan.


4.5 Eulerin kulmat

Jos kerran 2-ulotteisessa tapauksessa asennon esittämiseen riitti yksi kulma, niin eikö 3-ulotteisessa tapauksessa voitaisi käyttää kolmea kulmaa. Yksi x-akselin ympäri, yksi y-akselin ympäri ja yksi z-akselin ympäri. Nämä niin sanotut Eulerin kulmat (englanniksi Euler angles) riittävätkin joissakin tapauksissa, mutta niitä käyttäessä törmätään erilaisiin ongelmiin. Esim. lopputulos riippuu siitä, missä järjestyksessä objektia kierretään kulmien verran. Jos kierretään ensin x-akselin, sitten y-akselin ja lopuksi z-akselin ympäri, niin saadaan täysin erilainen lopputulos, kuin jos kierrot olisi tehty päinvastaisessa järjestyksessä. Lisäksi saatetaan törmätä tilanteeseen, jossa kaksi kiertoa kumoaa toisensa (ns. gimbal lock). Tämän takia 3-ulotteisessa avaruudessa objektin asento täytyy aina tallentaa 3x3 matriisina, tai 4x4 matriisina jos objektin sijaintikin halutaan samaan matriisiin.

4.6 Hierarkiset kuvaukset

Hierarkisella tilanteella tarkoitetaan tapausta, jossa objekti koostuu useasta toisiinsa kiinnitetystä osasta. Jokaisella osalla on yksi edeltäjä eli vanhempi, johon se on kiinnitetty ja mielivaltainen määrä seuraajia eli lapsia. Jos osalla ei ole vanhempaa, sitä kutsutaan juureksi. Jos osa liikkuu (esim. kiertyy tai siirtyy) myös kaikki sen lapset liikkuvat sen mukana. Jokaisen osan sijainti ja kierto täytyy tallentaa suhteessa sen vanhempaan. Nyt, jos jonkin osan asentomatriisilla halutaan kuvata vektori, täytyy vektori kertoa paitsi osan omalla matriisilla, myös kaikkien sen edeltäjien matriiseilla järjestyksessä juuresta "latvaan" päin.

Oletetaanpa tilanne, jossa meillä on "robottikäsi". Kädessä on kolme osaa: olkavarsi, kyynärvarsi ja kämmen. Olkavarren pituus on 3, kyynärvarren 2 ja kämmenen 1. Olkavarsi on kiinni origossa. Kyynärvarsi on kiinni olkavarressa ja kämmen kyynärvarressa. Käsi on alussa suorana x-akselin suuntaisena. Eli sormenpäät sijaitsisivat koordinaateissa ( 6, 0 ).

Olkavarsi kiertyy 10 astetta, kyynärvarsi 30 astetta suhteessa olkavarteen ja kämmen 50 astetta suhteessa kyynärvarteen. Mikä on sormenpäiden uusi sijainti?

Rakennetaan jokaiselle osalle oma asentomatriisi, joka ilmoittaa sen asennon, suhteessa vanhempaan. Eli olkavarsi origoon, kyynärvarsi olkavarteen ja kämmen kyynärvarteen. Sormenpäiden koordinaatit ilmoitetaan suhteessa kämmeneen eli ne ovat ( 1, 0 ).

Sormenpäiden uusi sijainti on siis noin ( 4.5, 2.8 ). Jos kokeilet asiaa kynän ja paperin kanssa huomaat tuloksen paikkansapitävyyden.

Hierarkisia kuvauksia käytetään ns. luurankoanimaatiossa. Siinä 3D-mallin sisään rakennetaan hierarkinen luuranko, jossa jokainen luu on kiinni edeltäjässään ja liikkuu tämän mukana. Sitten jokainen mallin verteksi tallennetaan suhteessa siihen luuhun, jonka mukana se liikkuu. Animaatiokehyksessä asetetaan jokaiselle luulle animaatiossa määritellyt matriisit, jotka kerrotaan juuresta latvaan päin, päätyen lopulta vertekseihin.


4.7 Korkeammat ulottuvuudet

Vaikka tietokoneen monitorin pinta onkin 2-ulotteinen ja realimaailma 3-ulotteinen ei matemaattisesti ole mitään syytä rajoittua vain 3 ulottuvuuteen. Esimerkiksi neliulotteista koordinaatistoa kuvaamaan voidaan käyttää 4x4 matriisia ja sen kanssa laskeminen toimii aivan samoin kuin 2x2 ja 3x3 matriisienkin kanssa. Se kuinka neliulotteista grafiikkaa saadaan piirrettyä tietokoneen kaksiulotteiselle näytölle onkin sitten toinen juttu.

Tensoreista #

Vektori on siis kokoelma skalaareita ja matriisi kokoelma vektoreita. No mikähän olisi sitten kokoelma matriiseja? Vastaus: 3-asteen tensori. Itseasiassa skalaari, vektori ja matriisi ovat kaikki tensoreita. Skalaari on 0-asteen tensori, vektori on 1-asteen tensori ja matriisi on 2-asteen tensori. 3-asteen tensori olisikin 3-ulotteinen taulukko, jolla on määriteltyjä laskutoimituksia samoin kuin skalaareilla, vektoreilla ja matriiseillakin. Käytännössä 2-astetta suurempia tensoreita ei juuri tarvita. Yleisesti ottaen voidaan sanoa, että kaikki suureet ovat tensoreita.

Kompleksiluvuista vaihtoehto matriiseille #

Vaikka matriisi on oiva väline kappaleen asennon ilmaisemiseen on siinä pari vikaa. Ensinnäkin se vie kohtuuttomasti muistia: 2x2 matriisissa on 4 alkiota, 3x3 matriisissa 9 ja 4x4 matriisissa peräti 16. Lisäksi matriisien laskutoimituksissa pyöristysvirheet kasautuvat nopeasti ja matriisin vektorit eivät enää ole kohtisuorassa toisiaan vastaan. Niinpä tarkastelemme vaihtoehtoista tapaa kuvata kappaleen asentoa: kompleksilukuja. Kompleksiluku on luku, joka koostuu kahdesta osasta: realiosasta ja imaginaariosasta. Kompleksilukua merkitään x+y*i, missä x ja y ovat realilukuja ja i imaginaariyksikkö, jolla on ihmeellinen ominaisuus i*i= -1 . x on tällöin kompleksiluvun realiosa ja y*i sen imaginaariosa.

6.1 2-ulotteinen tapaus

Kompleksilukujen kertolasku on määritelty seuraavasti:

(a+b*i)*(c+d*i) = (a*c-b*d)+(a*d+b*c)*i

Eli jos esim. halutaan kertoa keskenään kompleksiluvut 2+4*i ja 3+5*i saadaan (2*3-4*5)+(2*5+4*3)*i = -14+22*i .

Vektori ( x, y ) voidaan koodata seuraavanlaiseksi kompleksi luvuksi: x+y*i .

Kulma a voidaan koodata seuraavanlaiseksi kompleksiluvuksi: cos(a)+sin(a)*i .

Nyt vektoria voidaan kiertää kulman ympäri vain kertomalla kompleksiluvut keskenään.

Esim. Jos meillä on vektori v = ( 2, 5 ) ja haluamme kiertää sitä kulman a = 90 astetta verran. Teemme v:stä kompleksiluvun k=2+5*i ja kulmasta a kompleksiluvun c= cos(90)+sin(90)*i = 0+1*i . Tämän jälkeen laskemme c*k = (2*0-5*1)+(2*1+5*0)*i = -5+2*i eli vektori ( -5, 2 ) .

Samaan kompleksilukuun ei kuitenkaan voi koodata asennon kanssa sijaintia matriisin tapaan. Kompleksilukujen käyttäminen 2-ulotteisessa tapauksessa ei ole kovin mielekästä, koska asento voidaan ilmaista yhdellä luvulla; kulmalla, kompleksiluvun sijaan.

6.2 3-ulotteinen tapaus

Jos 2-ulotteisessa tapauksessa tarvittiin kompleksilukua, jossa oli kaksi komponenttia (yksi realinen ja yksi imaginaarinen), niin millaista kompleksilukua tarvitaan 3-ulotteisessa tapauksessa? Jos arvasit, että kompleksilukua, jossa on kolme komponenttia, niin olet jäljillä. Kolme komponenttia ei vielä kuitenkaan riitä, vaan tarvitaan kompleksiluku, jossa on peräti neljä komponenttia. Yksi realinen ja kolme imaginaarista. Tällaista kompleksilukua kutsutaan kvaternioksi (englanniksi quaternion) ja se on muotoa w+x*i+y*j+z*k, jossa w, x, y, ja z ovat realilukuja ja i, j ja k imaginaariyksiköitä, joilla on ihmeellinen ominaisuus i*i=j*j=k*k=i*k*j=-1. Kvaternion imaginaariosa x*i+y*j+z*k voidaan samaistaa vektoriksi ( x, y, z ), jolloin kvaterniota voidaan merkitä w+v, jossa w on realiluku ja v on vektori ( x, y, z ).

Kvaternioiden kertolasku on määritelty seuraavasti:

(a+b*i+c*j+d*k)*(e+f*i+g*j+h*k)=
(a*e-b*f-c*g-d*h)+(b*e+a*f-d*g+c*h)*i+(c*e+d*f+a*g-b*h)*j+(d*e-c*f+b*g+a*h)*k.

Tai jos pidit vektorimuodosta enemmän:

(w1+v1)*(w2+v2)=(w1*w2-v1*v2)+(w1*v2+w2*v1+v1xv2) ,

jossa "*" tarkoittaa pistetuloa ja "x" ristituloa.

Akselin v=( x, y, z ) ympäri kulman a verran tapahtuva kierto voidaan koodata kvaternioksi seuraavasti:

cos(a/2)+x*sin(a/2)*i+y*sin(a/2)*j+z*sin(a/2)*k .

Vektori ( x, y, z ) voidaan koodata kvaternioksi

0+x*i+y*j+z*k.

Kvaternioksi koodattua vektoria v voidaan kiertää kvaterniolla q laskemalla q*v*q^-1. q^-1 tarkoittaa kvaternion käänteiskvaterniota, joka puolestaan lasketaan jakamalla kvaternion konjukaatti sen normilla. Jottei tarvitsisi välittää moisista laskutoimituksista sanotaan vain, että riittää kun vaihdat kvaternion kaikkien imaginaarikomponenttien merkit.

Esim. Kierretään vektoria ( 2, 5, 3 ) 180 astetta akselin ( 0, 1, 0 ) eli y-akselin ympäri. Koodataan vektori kvaternioksi q1=0+2*i+5*j+3*k. Koodataan kulma ja akseli kvaternioksi q2=cos(180/2)+sin(180/2)*0*i+sin(180/2)*1*j+sin(180/2)*0*k=0+0*i+1*j+0*k. Lasketaan (0+0*i+1*j+0*k)*(0+2*i+5*j+3*k)*(0+-0*i+-1*j+-0*k)=0+-2*i+5*j+-3*k eli vektori ( -2, 5, -3 ).

Kvaternio voidaan tarvittaessa muuntaa 3x3 kiertomatriisiksi seuraavalla kaavalla:

w+x*i+y*j+z*k=



Kompleksiluvut ovatkin hyödyllisiä vain kolmiulotteisessa avaruudessa. Nimittäin neliulotteisessa avaruudessa tarvitaan jo 8-komponenttista kompleksilukua oktoniota .