TIEA311 Tietokonegrafiikan perusteet

Oli tarkoitus tehdä jotakin suomenkielistä apumateriaalia kurssin Tietokonegrafiikan perusteet opiskelun hyödyttämiseksi tai jotain sellaista ja samalla opetella käyttämään TIM-järjestelmää luentomateriaalin kirjoittamiseen.   Aloitin tämän 2018, mutta aika loppui kesken, kun vasta "Härnäys" oli kirjoitettu. Se ei vielä riittäisi kovin pitkälle.

Vuonna 2019 tähän ehti tulla myös "Avaus" omalle paikalleen heti tuon "Härnäyksen" jälkeen, mikä teki tästä mielestäni alustavasti julkaisukelpoisen. Klikkaan lukuoikeuden maailmalle 17.1.2019 ja tiedotan saman päivän luennolla opiskelijoille URL:stä.

Vuonna 2020 tähän tulee vääjäämättä päivityksiä ja mahdollisesti laajennusta alkaen otsikosta, jossa tällä kellonlyömällä näet avainsanan "TODO:"

Edellisen vuoden kurssin kotisivu ja linkit materiaaleihin on osoitteessa http://users.jyu.fi/~nieminen/tgp19. Keväälle 2020 tulee uusi kotisivu piakkoin, ja siellä täsmennetään kevään 2020 kulku.

Tämä saattaa siis päivittyä kevään 2020 grafiikkakurssin ajan, mutta on parempi olla lupaamatta mitään, koska aika loppuu aina kesken - täydellä varmuudella myös 2020.

Uutena materiaalina tämä sisältää todennäköisesti paljon virheitä. Ota yhteys, jos huomaat asiavirheitä. Niitä emme haluaisi. Tyyli on omani, ja sitä en vaihda. Kestä se tai etsi jonkun toisen materiaali aihepiiristä. Maailma on täynnä hyviä vaihtoehtoja.

Tämän päivitetyn esipuheen allekirjoittaa Paavo-ope 8.1.2020 pikaisesti opintoneuvontasessioiden välissä.

Päivitys 24.1.2019: Tähän materialisoituikin ihan hyvin sisältöä, jonka sisäistäminen luultavasti suoristaa suomenkielisen opiskelijan reittiä perille ja vähentää tarvetta käyttää tunteja Internetin lukemiseen läpi ja hakujen tekemiseen!

Eli, hupsista vaan, tämä onkin nyt suositeltavaa lukemista keväällä 2019!!

Muilta osin edellinen esipuhe pitää yhä paikkansa, muun muassa virheiden mahdollisuus on olemassa, ja lupauksia laajentamisesta kevään aikana 2019 ei pysty tekemään. Silmiesi edessä avautuva versio on jo olemassa siihen asti, mistä juuri tänään alkaa ensimmäinen pääluku otsikolla "TODO:..."

Paavo-ope 24.1.2019 vartti ennen luentoa.

Esitietoja

Härnäys

Vektoriavaruus on joukko \(V\), jonka alkioille on määritelty keskinäinen yhteenlasku sekä kunnan \(\mathbb{F}\) alkiolla kertominen eli skalaarikertolasku siten, että kaikki seuraavat ominaisuudet ovat voimassa.

  • Yhteenlaskun kommutatiivisuus eli vaihdannaisuus: \[u + v = v + u \quad \forall u,v \in V\]
  • Assosiatiivisuus eli liitännäisyys yhteenlaskussa: \[(u+v)+w = u+(v+w) \quad \forall u,v,w \in V\] ja skalaarikertolaskussa: \[(ab)v=a(bv) \quad \forall v \in V, \ a,b \in \mathbb{F}\]
  • Joukossa on mukana yhteenlaskun neutraalialkio eli nollavektori: \[\exists 0 \in V : v + 0 = v \quad \forall v \in V\]
  • Joukossa on yhteenlaskun käänteisalkiot eli "vasta-alkiot": \[\forall v \in V \ \exists w \in V: v + w = 0\]
  • Skalaarikertolaskussa kunnan \(\mathbb{F}\) "ykkösellä" \(1 \in \mathbb{F}\) eli kuntakertolaskun neutraalialkiolla kertominen on identiteettioperaatio eli se pitää alkion samana: \[ 1v = v \quad \forall v \in V\]
  • Distributiivisuus eli osittelulaki: \[a(u+v)=au + av \quad \forall u,v \in V, \ a \in \mathbb{F}\] ja \[(a+b)v=av + bv \quad \forall v \in V, \ a,b \in \mathbb{F}.\]

Vektoriavaruuden alkioita kutsutaan nimellä vektori.

Älä pelästy "ruuhkaisen" näköistä määritelmää! Se on vain matematiikkaa siinä muodossa kuin sen kirjoittanut henkilö päätti tässä yhteydessä sopivaksi tuottaa kuvitellen, että tarkoitettu sanoma välittyy sellaiselle lukijalle, joka tutustuu huolellisesti myös alempana löytyvään tarkentavaan tekstiin. Kirjoittaja ei oleta, että lukijalla olisi taustallaan aiempia yliopistomatematiikan opintoja. Eli lue vaan eteenpäin ja palaa tuohon määritelmään tarvittaessa uudelleen, kunnes se on ymmärrettävissä silmäyksellä. Siihen menee aikaa ja tarvitaan todennäköisesti useita yrityksiä useina eri päivinä, jos tämä on ensimmäinen kerta.

Tämä kurssi on suunniteltu mahdolliseksi ensikosketukseksi ennalta vähemmän tuttuihin matematiikan käsitteisiin ja merkintätapoihin. Mikäli aiempaa kokemusta ei ole, joudut varautumaan ylimääräiseen ajankäyttöön ja hikoiluun matemaattisen työkalupakin avaamiseksi ja erilaisten perustyökalujen pyörittelyyn. Tärkein työkalu on oma pääsi - se kykenee kyllä matematiikkaan, jos vain haluat ja päätät niin! Toiseksi tärkeimpänä työkaluna tämän kirjoittaja suosittelee ergonomisesti muotoiltua kynää ja valtavaa pinoa paperia.

Yläkoulun ja osittain lukion matematiikan taidot oletetaan olevan jo hankittu. Jos plus- ja kertolaskut reaaliluvuilla, polynomin derivointi tai yksinkertaisten yhtälöiden ratkaiseminen tökkii pahasti, tämä kurssi on mahdollinen vasta sitten, kun olet kerrannut koulumatikat! Sinua on varoitettu. Yliopistostamme löytyy erinomaisia kertauskursseja. Pienoiskertaus ja lähtötasotesti tehtiin 3. ja 4. luennolla vuonna 2019. Kaikki paikalla olleet pääsivät siitä läpi liehuvin lipuin!

Tässä monisteessa pyritään kuvailemaan kaikki "kansantajuisesti" siinä määrin kuin tällä kurssilla tarvitaan. Silti matemaattisen abstraktion ihanuutta ja kompaktia esitystapaa ei yritetä piilottaa vaan pikemminkin vaalia sen verran kuin tämän monisteen kirjoittaja vain suinkin osaa. Tässä tapauksessa kansantajuisuuden kohteena oleva "kansa" tarkoittaa ensisijaisesti niitä, joilla on vähintään vuoden verran kokemusta ohjelmoinnista esimerkiksi C# ja/tai Java-kielillä sekä alustava käsitys algoritmien kehittelystä, mutta ei välttämättä (vielä) puhtaasta matematiikasta. Aivan pystymetsästä vedetylle kansalaiselle tämä siis ei ole kirjoitettu.

Mikään ei korvaa yliopisto-opintojen tarjoamaa mahdollisuutta käyttää luvan kanssa aikaa ja tarjottua ohjausta myös varsinaisten matematiikan kurssien käymiseen. Vahva ymmärrys vaatii valtavasti enemmän tunteja kuin esimerkiksi tällä kurssilla on käytettävissä edes edellämainittuun "ylimääräiseen hikoiluun". Toivottavasti tietokonegrafiikasta jää käteen konkreettinen esimerkkisovellus ja motivaatio istahtaa vaikkapa Jyväskylän yliopiston matemaattisluonnontieteellisen tiedekunnan matikan kursseille. Mikä kurssi sieltä sitten kannattaisi ottaa? Tämän kurssin opettajan mielestä kaikki, mihin on aikaa ja mahdollisuus! Tietokonegrafiikan tekemistä toki hyödyttää kaikkein nopeiten erityisesti Lineaarinen algebra ja geometria sekä Calculus -kurssit. Kuitenkin grafiikassa, kuten muissakin tietotekniikan aihepiireissä, syvemmälle mentäessä aletaan tarvita melkein kaikkia matematiikan osa-alueita. Tietokonegrafiikan perusteiden kurssilla nähdään päällisin puolin esimerkkejä myös tällaisista asioista, joiden tekeminen vaatii pitkän reitin muun muassa matematiikan opiskelua.

Matematiikkaa jo ennalta tunteva ohittakoon halutessaan "untuvikoille" tarkoitetun johdannon matematiikan ihmeelliseen maailmaan. Sen tavoite on johdatella lukijaa tapaan, jolla mitä tahansa osittainkin matemaattista tekstiä tulisi lähestyä. Matematiikan tai fysiikan kursseja käyneelle nämä perusasiat lienevät jo tuttuja.

Avaus

Mitä lukijan pitää tehdä aina kohdatessaan matematiikkaa? Pitää pysähtyä ymmärtämään, mitä kaavoissa sanotaan ja varmistua itse, että niissä on järkeä. Tämä ei tapahdu hetkessä - ei missään nimessä edes ammattilaiselta, mikäli kaavat eivät satu olemaan hänen omaa erityisalaansa.

Pääsääntö numero yksi: Istu alas ja anna itsellesi aikaa ajatella. Kynä ja paperi on oltava käytössä ajattelun apuna, mikäli luettavana oleva aihe ei ole ennalta jo hyvin tuttu. "Istu alas" on kielikuva; esimerkiksi tämän tekstin kirjoittaja on oppinut matematiikasta paljon myös kävely- ja juoksulenkkien aikana sekä kuntosalilla. Istuminen toki helpottaa teknisesti niitä vaiheita, joissa käytetään kynää ja paperia. "Anna itsellesi aikaa ajatella" sen sijaan on enemmän kuin pelkkä kielikuva. Unohda kiire ja deadlinet, koska stressaaminen ja panikointi on huonointa ajankäyttöä oppimisen suhteen. Keskity työn alla olevaan asiaan ja unohda kaikki muu juuri sillä hetkellä. Myönnettäköön, että tämä ei ole aina helppoa.

Yllä olevan vektoriavaruuden määritelmän tarkoitus oli toistaa lyhyessä ja ytimekkäässä muodossa muutaman viimeisen vuosisadan aikana vakiintuneita, erittäin tunnettuja, asioita niillä nimillä, joita suomalaisessa puheenparressa tänä päivänä käytetään. Tiiviissä esitystavassa on symboleja, joita ei oleteta tunnetuksi ennen alla olevien alilukujen lukemista.

Pääsääntö numero kaksi: Sinun tulee ymmärtää kaikki merkinnät - jos jokin merkintä ei ole tuttu, sinun tulee selvittää sen merkitys jostakin! Selitys saattaa löytyä muutaman tekstikappaleen päästä ennen tai jälkeen kaavaa. Kuitenkin jos jokin merkintä oletetaan tunnetuksi oletetun kohderyhmän pohjakoulutuksella, niin eipä sitä ole mielekästä selitellä. Hyvä puoli nykyään on, että kaikki löytyy netistä, kun osaa vaan etsiä ja suodattaa tietoa.

Matemaattiset merkintätavat voivat riippua kirjoittajasta ja asiayhteydestä. Kirjoittajan vastuulla on yrittää selittää kaikki käyttämänsä merkinnät siten, että lukijalla on mahdollisimman hyvä mahdollisuus ymmärtää tarkoitettu sanoma. Koska kaikkea ei voi koskaan aivan alusta lähtien selittää, lukijan vastuulla on käyttää tarvittava aika ja energia siihen, että hänelle muodostuu omasta mielestään riittävä varmuus siitä, mitä kirjoittaja on tarkoittanut, ottaen huomioon että kirjoittaja on voinut tehdä virheitä tai olla lähtökohtaisestikin väärässä. Matematiikan kohdalla tämä vaatii aikaa ja esitietoja ehkä jopa enemmän kuin millään muulla alalla.

Matematiikan kieli on täsmällistä ja tiivistettyä proosaa. Sen voi avata kokonaisiksi lauseiksi esimerkiksi suomen kielellä. Jos lukeminen ääneen suomeksi ei onnistu, kaavassa on mahdollisesti virhe tai siinä on käytössä merkintä, joka ei ole lukijalle vielä tuttu.

Miten ensimmäiset sanat luetaan?

Luetaan vektoriavaruuden määritelmä yhdessä ja opetellaan samalla tapaa, jolla matematiikkaa yleensä kirjoitetaan. Ensiksi sanottiin, että "Vektoriavaruus on joukko \(V\)". Miten tämä toteamus pitää lukea, ja mitä sen on tarkoitus meille kertoa?

Matematiikassa merkitään asioita yleensä lyhyillä symboleilla, joiden luonne ilmoitetaan tarkoin. Koska tunnet jo ohjelmointia, voit ajatella analogiaa esimerkiksi C#:lla, Javalla tai C++:lla kirjoitettavaan ohjelmaan: Ohjelmassa muuttuja on esiteltävä ennen kuin sitä käytetään, ja esittelyn yhteydessä on ilmoitettava muuttujan tyyppi tai "luokka". Sen jälkeen muuttujan nimi symboloi tyypin mukaista asiaa omalla näkyvyysalueellaan. Toisessa ohjelmalohkossa sama nimi voidaan ottaa aivan eri käyttöön. Aivan samoin on matematiikassa. Symboli määritellään ensin, ja sen jälkeen sen luonne pysyy samana esimerkiksi tekstikappaleen, luvun tai oppikirjan loppuun asti. Kirjoittajan ja lukijan vastuulla on saada jatkuvasti pysymään yhteinen käsitys kunkin symbolin merkityksestä kussakin kohdassa matemaattista tekstiä. Samoin kuin ohjelmakoodissa, matematiikassa on luettava kokonaisuus järjestyksessä ja/tai palattava tarvittaessa aiempaan ja aiempaan kohtaan, kunnes löytyy määritelmät sen rivin asioille, joita ollaan tarkastelemassa.

Koska nyt sanottiin, että \(V\) on joukko, sen jälkeen tulevia virkkeitä lukiessa tiedetään, että nimi tai symboli \(V\) merkitsee joukkoa eli jonkinlaista kokoelmaa alkioita. Se on geneerisimpiä mahdollisia määritelmiä, koska esimerkiksi "kaikki IT-alan opiskelijat" tai "syksyn 2017 aikana kypsyneet omenat" voisivat hyvinkin olla joukkoja, joita voitaisiin symboloida kirjaimella \(V\). Se, että "\(V\) on joukko", kertoo meille jo paljon, mutta ei vielä täsmennä millään tavoin, millainen joukko olisi kyseessä. Tyypillistä onkin ryhtyä lyömään lukkoon myös muita ominaisuuksia, jotka määrittävät tarkemmin, millaisesta "aliluokasta" oikeastaan on kyse.

Eli sanamuotohan kuului "Vektoriavaruus on joukko \(V\), jonka alkioille on määritelty ..." ja sen kautta alettiin täsmentää, millaisin ominaisuuksin varustettu joukko ansaitsee tulla määritellyksi omaksi käsitteekseen (eli yleisen joukon "aliluokaksi") nimeltä vektoriavaruus. Yksi matematiikan historiallisista tehtävistä on todellisen maailman ilmiöiden mallintaminen, jolloin ei ole kummallista, että ominaisuudet kuvailevat täsmällisesti sellaisia ilmiöitä, joilla on analogia johonkin reaalimaailmaan sovellusongelmaan. Ohjelmoijana voinet nähdä matematiikan tavoitteessa ja toimintamallissa yhtymäkohtia esimerkiksi olio-ohjelman tekemiseen.

Vektoriavaruuden määritelmä ei ole mitenkään sattumanvarainen tai arvalla heitetty. Päinvastoin: se on viritetty niin, että siitä saadaan mitä tehokkain koneisto muun muassa kolmessa avaruusulottuvuudessa elävien olentojen päivittäisen toimintaympäristön ilmiöiden mallintamiseen. Esimerkiksi se, että tuotetaan ihmisen näköaistille ärsykkeitä, jotka johtavat hänen aivonsa tulkitsemaan ne kuvina jostakin olemassaolevasta tai kuvitellusta maailmasta, pitää kaikissa välivaiheissaan sisällään lähes ainoastaan kolmessa avaruusulottuvuudessa elävän olennon maailmaan liittyviä ilmiöitä... joiden käsittelyyn vektoriavaruus on kuin tehty. Abstraktin määritelmän hienous on se, että sama määritelmä mallintaa yhtä hyvin tuhansissa tai miljoonissa avaruusulottuvuuksissa elävien olentojen ympäristöä, tehtaan mittalaitedataa tai monia muita sangen hyödyllisiä sovelluskohteita.

Yllä oleva määritelmä jatkuu vaatimalla, että joukon \(V\) lisäksi täytyy olla määriteltynä kaksi laskutoimitusta. Olisikin ollut mahdollista kirjoittaa tarkemmin, että vektoriavaruus on nelikko \((V,\mathbb{F},+,\heartsuit)\), missä \(V\) on joukko, \(\mathbb{F}\) kunta ja \(+:V \times V \rightarrow V\) ja \(\heartsuit : \mathbb{F} \times V \rightarrow V\) kaksiargumenttisia laskutoimituksia. Tässä olisi valittu muutama symboli lisää, eli \(\mathbb{F}\), \(+\) ja \(\heartsuit\), ja niistäkin olisi ilmoitettu "tyyppi".

Nyt tekstin kirjoittaja selvästikin oletti, että lukija osaa joko aiemman koulutuksensa tai tämän avaustekstin lukemisen perusteella ymmärtää omassa päässään nämä tarkemmat tyyppimääritelmät sen perusteella, mitä hän kirjoitti, eli että tulee olla "yhteenlasku ja kunnan alkiolla kertominen".

Mikä on kunta tässä yhteydessä? Koko totuus kerrottaneen matematiikan kurssilla Algebra 1: ryhmät ja kunnat. Meille riitää nyt tietää, että kunta on sellainen joukko, jolle on määritelty koulumatematiikasta tutut peruslaskutoimitukset. Esimerkiksi murtoluvut, reaaliluvut ja kompleksiluvut ovat kuntia.

Voidaan sopia, että Tietokonegrafiikan perusteet -kurssilla alusta loppuun \(\mathbb F = \mathbb R\) eli kaikkien meille vastaantulevien vektoriavaruuksien kerroinkunta on reaalilukujen joukko \(\mathbb{R}\), jonka luvuilla ja laskutoimituksilla jokainen on tottunut laskemaan alakoulusta asti. Se riittää nyt meille, mutta ei unohdeta sitä, että sama matematiikka toimii eksoottisemmissakin sovelluksissa. Muistelepa tässä kohtaa, millaisia laskusääntöjä reaaliluvuilla olikaan, ja miten luvut \(0\) ja \(1\) ovat erityisiä plus- ja kertolaskun suhteen. Muut reaaliluvut ovat keskenään hyvin samanlaisia, mutta mikään niistä ei ole aivan kuin \(0\) eikä mikään aivan kuin \(1\), eihän? Miksi?

Merkintä \(+:V \times V \rightarrow V\) tarkoittaa, että kaksoispisteen vasemmalle puolelle kirjoitettu symboli \(+\) merkkaa "oliota", joka on "tyypiltään" funktio eli sääntö, joka liittää kuhunkin nuolen \(\rightarrow\) vasemmalla puolella olevan joukon eli ns. lähtöjoukon alkioon tasan yhden alkion oikealla puolella olevasta joukosta eli ns. maalijoukosta. Lähtöjoukon alkio kahden argumentin laskutoimitukselle on kahden alkion pari, esim. \((u,v)\). Kaikista mahdollisista pareista eli järjestetyistä kaksikoista muodostuvaa joukkoa merkitään ruksilla \(V \times V\) ja sanotaan kahden joukon karteesiseksi tuloksi. Joukkoon kuulumista merkitään lyhyesti esim. \((u,v) \in V \times V\), mikä luetaan, että "pari uuvee kuuluu vee ruksi veehen". Se tarkoittaa, että sekä \(u\) että \(v\) ovat alkioita \(V\):stä ja että niillä on keskinäinen järjestys tai "istumapaikkansa" siten, että \(u\) on parin ensimmäinen ja \(v\) toinen osallistuja. Funktion \(+\) antama tulos \(+(u,v)\) kuuluu maalijoukkoon eli \(V\):hen. Nyt kun on yhteenlaskun mallintamisesta kyse, niin tapana on merkitä symboli kahden argumenttinsa väliin eli \(u + v := +(u,v)\). Kaksoispiste ja yhtäsuuruusmerkki luetaan esimerkiksi "määritellään olemaan yhtä kuin". Huomaa, että laskutoimituksen osallistujien eli operandien järjestyksellä on väliä, ellei erikseen määritellä jotakin reaalilukujen vaihdantalain kaltaista ominaisuutta.

Vastaavalla tavoin symboli \(\heartsuit\) määriteltiin funktioksi sanomalla, että \(\heartsuit : \mathbb{F} \times V \rightarrow V\). Sen lähtöjoukon pareissa \((a,v) \in \mathbb{F} \times V\) ensimmäinen alkio \(a \in \mathbb{F}\) ja toinen alkio \(v \in V\). Funktion arvo on joukossa \(V\). Vektoriavaruuden määritelmässä halutaan mallintaa tällä tietynlaista kertolaskua, joten sovitaan lyhyt ja ytimekäs kirjoitustapa, jossa operaattori jätetään kokonaan kirjoittamatta kertojan ja kerrottavan välistä eli \(av := a \heartsuit v := \heartsuit(a,v)\). Kertolaskun symboliksi on tavallisempaa valita esimerkiksi \(\cdot\) tai \(\times\) tai \(\ast\) tai \(\odot\) tai \(\otimes\) tai muuta kertolaskuun päin paremmin vihjaavaa. Tässä tapauksessa kirjoittaja valitsi symbolin \(\heartsuit\), koska se on sydämellinen ja käy esimerkiksi siitä, että symboleiksi voidaan valita mitä vaan, kunhan niiden merkitys ja toiminta selitetään. Samoinhan on ohjelmoinnissa, kun nimetään muuttujia, luokkia ja metodeja. Yleensä kannattaa kuitenkin valita symbolit samalla tavoin kuin muutkin tekevät. Ei tule sekaannuksia. Tähän liittyen varoituksen sana mm. tämän kurssin pohjana olevista MIT:n luentokalvoista: niissä käytetään sekaisin monia eri merkintätapoja, luultavasti eri luennoitsijoiden taustoista riippuen. Joutuu hieman setvimään ja miettimään itse, mitä mikäkin tarkoittaa missäkin yhteydessä.

No niin. Nyt pitäisi olla keinot ymmärtää, mitä määritelmän ensimmäiset sanat tarkoittivat. Niissä ei vielä kerrottu enempää kuin että ryhdyttiin määrittelemään vektoriavaruuksien "luokkaa", jolla on ominaisuutena mahdollisuus summata eli ynnätä eli plussata alkioon toinen "samantyyppinen" alkio sekä kertoa alkio valitun kunnan, eli vaikkapa reaalilukujen joukon, alkiolla. Summan ja kertomisen pitää olla suljettuja operaatioita, eli niiden tulos on samalla lailla joukossa \(V\) kuin niiden joukossa \(V\) olleet operanditkin. Mitä tahansa operaatiot eivät saa olla, vaan summaus ja kertominen pitää tapahtua tarkempien rajoitteiden puitteissa. Nämä rajoitteet luetellaan määritelmässä listana vaadittuja ominaisuuksia fraasin "siten, että seuraavat ovat voimassa" jälkeen. Mitenkäs niitä luetaan?

Miten luetaan ominaisuuslistan ensimmäinen rivi

Määritettäville ominaisuuksille on hyvä antaa nimet, jotta niihin voi tarvittaessa vedota laskutoimituksia tehdessä. Vektoriavaruudelta haluttavat ominaisuudet ovat niin vanhoja tuttuja, että niiden nimet ja merkitykset ovat alakoulumatematiikasta tutut.

Tässä tapauksessa ensimmäiselle ominaisuudelle on annettu nimeksi "yhteenlaskun kommutatiivisuus eli vaihdannaisuus". Tämän ominaisuuden tarkoitus kun on vaatia, että vektoreiden yhteenlasku toimii laskujärjestyksen osalta "tutulla ja turvallisella" tavalla, jossa operandien järjestys ei vaikuta tulokseen. Vierasperäinen nimi tälle on kommutatiivisuus. Voidaan myös sanoa, että "kaikki vektoriavaruuden alkiot kommutoivat vektorien yhteenlaskussa" tai että "yhteenlasku kommutoi kaikille alkioille".

Vaikka jo nimike vaihdannaisuus kertoo peruskoulun käyneelle, mistä on kyse, on aina täsmällisempää kirjoittaa kaava symboleilla. Tulkinnanvaran poistamisen lisäksi kaavat ovat helpommin käytettävissä laskusääntöinä, ainakin kunnes ne ovat juurtuneet laskijan "selkäytimeen" itsestäänselvyyksiksi. Kerrataan tässä vaihdannaisuuden kaava ennen kuin pureksitaan se auki: \[u+v = v+u \quad \forall u,v \in V.\]

Suomen kielellä tämä luetaan esimerkiksi näin: "uu plus vee on yhtä kuin vee plus uu kaikilla uulla ja veellä joukosta Vee". Mukana on symboli \(\forall\), joka luetaan "kaikilla" (tai asiayhteydestä riippuen taivuttaen jollain tapaa). Toinen symboli tässä on \(\in\) joka voidaan lukea "kuuluu joukkoon" tai "otettuna joukosta" (tai asiayhteydestä riippuen taivuttaen jollain tapaa).

Kaavarivi tarkoittaa juuri sitä kuin voisi ääneen lukemisen perusteella olettaa: Valittiinpa joukosta \(V\) mitkä tahansa kaksi alkiota eli vektoria \(u\) ja \(v\), niin niille täytyy yhteenlaskun kommutoida tai sitten \(V\) (varustettuna juuri kyseisellä "huonolla" yhteenlaskutavalla) ei olekaan tämän määritelmän mukainen vektoriavaruus.

Symboli \(\forall\) on nimeltään universaalikvanttori. Sitä käytetään filosofiassa ja matematiikassa ilmaisemaan, että jokin väittämä on totta kaikille eli toisaalta mille tahansa yksittäiselle tietyn luokan oliolle. Symboli on ylösalaisin piirretty A-kirjain, mitä voi käyttää englannin kielestä tulevana muistisääntönä ("for All").

Universaalikvanttorin jälkeen nimetään symbolilla niin sanotusti mielivaltaisesti valittu eli todella mikä tahansa yksittäinen esimerkkiedustaja jostakin luokasta. Tässä nyt valitaan jopa kaksi erillistä, pilkulla erotettua, yksilöä annetuilta nimiltään \(u\) ja \(v\). Kvanttorin ja symboleiden "näkyvyysalue" on tämä yksittäinen rivi. Myöhemmin symbolit \(u\) ja \(v\) voidaan ottaa uuteen käyttöön, kunhan muistetaan mainita niiden uusi "tyyppi". Sen sijaan symbolit \(\mathbb{F}\) ja \(V\) on määritelty aiemmin, tämän listarivin ulkopuolella, "globaalisti", joten niiden merkitys pysyy samana listan riviltä toiselle. Oho... taas tuli käytettyä ohjelmoinnista tuttua käytännön terminologiaa, vaikka puhuttiin silkkaa filosofiaa!

On tyypillistä, että laskusäännössä käytetyt symbolit määritellään universaalikvanttorilla rivin lopussa tai joskus erillisessä, luonnollisella kielellä kirjoitetussa, sivulauseessa rivin jälkeen. Se on jopa niin tyypillistä, että tämän tekstin kirjoittaja päätti tehdä tässä niin, vaikka ohjelmointikielen rakenteita läheisempi tapa olisi ollut sanoa niin päin, että "kaikilla uulla ja veellä joukosta Vee pätee, että uu plus vee on yhtä kuin vee plus uu": \[ \forall u,v \in V : u+v = v+u.\]

Silloin tällä rivillä käytetyt uudet symbolit \(u\) ja \(v\) sekä niiden tyyppi olisi määritelty ennen kuin niitä käytetään johonkin. Sen verran siis matematiikan kielessä on tapana joustaa suhteessa C:n tapaisiin ohjelmointikieliin, että symbolit saatetaan määritellä myös ihan vähän sen jälkeen, kun niitä on jo käytetty. Toisaalta esimerkiksi Haskell-kielessä voidaan avainsanalla "where" antaa symboleille selitykset jälkikäteen, hyvin läheisesti matematiikan kaltaisesti. Kuitenkin matemaattisen lauseen symboleihin liittyvät määritelmät, "tyypit" sekä kvanttorit löytyvät jostain hyvin läheltä, jos niitä ei ole kiinnitetty aiemmin. Tai sitten kirjoittaja on unohtanut jotakin hyvin, hyvin tärkeätä, mikä on valitettavasti aina mahdollista myös...

Miten luetaan loput ominaisuudet

Nyt kun ensimmäinen ominaisuus on pureskeltu, niin seuraavien lukeminen onnistuu aivan samoilla eväillä. Kaikilla riveillä määritellään jokin joukolta \(V\) ja sen laskutoimituksilta edellytettävä ominaisuus, jolle on mahdollisuuksien mukaan muisteltu tuttu ja turvallinen nimi.

Listan toisessa kohdassa, liitännäisyyslaissa, tulee kaksi erillistä riviä, joista ensimmäinen määrää operaatiolle \(+\) ja toinen operaatiolle \(\heartsuit\) liitännäisyydeksi nimetyn säännön. Uusina symboleina tulevat vastaan sulkumerkit.

Liitännäisyyden ensimmäisen kaavarivin eli \[(u + v) + w = u + (v + w) \quad \forall u,v,w \in V\] voi lukea ääneen vaikka jotenkin niin, että "u:n ja v:n summa plus w on yhtä kuin u plus v:n ja w:n summa" tai "uu plus vee suluissa plus tuplavee on sama kuin uu plus suluissa vee plus tuplavee" tai jotain muuta, mikä resonoi omassa tajunnassasi sen asian kanssa, että sulkumerkkien paikkaa pitää voida vaihtaa ilman, että yhteenlaskun tulos muuttuu. Sulkumerkeillähän ilmaistaan laskujärjestys, eli ensiksi tehdään kaikkein sisimmissä suluissa olevat laskut, joiden tulos syötetään eteenpäin ulompiin sulkuihin. Näinhän kaarisulkujen toiminta on määritelty ohjelmointikielissäkin.

Jokainen yhteenlasku on kahden alkion välinen, koska muistetaan funktiomääritelmä \(+:V \times V \rightarrow V\). Niinpä vasta tämän liitännäisyysvaatimuksen pohjalta voidaan todeta, että sulkuja ei olekaan pakko merkitä peräkkäisten yhteenlaskujen välille, koska niiden paikoilla ei olisi lopputuloksen kannalta väliä.

Tämänkin rivin lopussa määrätään kvanttorilla \(\forall\), että kaavan tulee olla aina totta, valitaanpa mitkä tahansa kolme samaa tai eri alkiota nimillä \(u\), \(v\) ja \(w\) joukosta \(V\). Ja jos näin taas ei käy aina, niin sellainen \(V\) sellaisella \(+\):lla ei ole vektoriavaruus, jollaista tässä määritellään. Matematiikka on tältä osin ihanan mustavalkoista ja täsmällistä.

Liitännäisyyden toinen kaavarivi eli \[(ab)v = a(bv) \quad \forall v \in V, \ a,b \in \mathbb{F}\] luetaan vaikkapa "skalaaritulo aan ja been tulosta ja veestä on yhtä kuin skalaaritulo aasta ja been ja veen skalaaritulosta kaikilla veellä joukosta Vee ja aalla ja beellä joukosta äf." tai "aabee kertaa vee on aa kertaa beevee kaikilla veellä joukosta Vee ja aalla ja beellä joukosta äf"... Puhekielessä ei pääse helposti samaan täsmällisyyteen, johon kaavalla päästään sulkumerkkien avulla. Luonnollisella kielellä tarvittaisiin täsmällisyyden lisäämiseen ehkä vähän pidempiä lauserakenteita, kuten "aan ja been välisellä kuntakertolaskulla saadulla skalaarilla kerrottu vee pitää olla sama kuin skalaarilla aa kerrottu vektori, joka on saatu kertomalla vee skalaarilla bee". Tai jotain muuta monisanaista. Onneksi matemaattisessa proosassa voidaan tarvittaessa kirjoittaa kaavoja!

Tässä sovitaan sulkujen siirtämisestä kuntakertolaskun ja skalaaritulon välillä. Kun pidät tarkkaa kirjaa kaavassa olevien olioiden tyypeistä, huomaat, että vasemmalla puolella \((ab)v\) sisältää koulumatematiikasta tutun kertolaskun "\(a\) kertaa \(b\)", jos kerroinkunta on koulumatematiikasta tuttu \(\mathbb{R}\). Oikealla puolella \(a(bv)\) taas ei ole olemassa yhtään koulusta tuttua kuntakertolaskua, vaan ainoastaan kaksi peräkkäistä \(\heartsuit\) -symbolilla määriteltyä skalaarikertolaskua! Ohjelmoijalle tuttuna funktiosyntaksina kirjoitettunahan oikea puoli on \(\heartsuit(a, \heartsuit(b,v))\).

Kolmas listakohta määrittelee ihan suomen kielellä, että vektoriavaruudessa tulee olla jonkinlainen "nolla", jonka nimeksi annetaan nollavektori. Kaava sitten vielä täsmentää lyhyillä symboleilla, mitä tässä ajetaan takaa: \[\exists 0 \in V : v + 0 = v \quad \forall v \in V.\]

Nyt on mukana symboli \(\exists\) joka luetaan "On olemassa". Kaksoispiste \(:\) luetaan "siten, että". Siis tämä kaava sanoo, että "on olemassa alkio 'nolla' joukossa Vee siten, että vee plus 'nolla' on vee kaikilla veellä Veestä". Symboli \(\exists\) on eksistenssi- eli olemassaolokvanttori. Sitä käytetään määräämään tai ilmoittamaan, että jokin tietynlainen olio on olemassa. Vektoriavaruudessa on nollavektori, jonka lisääminen mihin tahansa vektoriin antaa tulokseksi identtisesti tuon toisen vektorin. Jos joukossa \(V\) ei ole tällaista nolla-alkiota operaation \(+\) suhteen, niin se ei ole vektoriavaruus kyseisen \(+\):n kanssa.

Sitten, kun nolla-alkiosta on sovittu, niin sovitaan vasta-alkioista. Kaavarivi \[\forall v \in V \ \exists w \in V : v + w = 0\] luetaan jo aiemmasta tutulla tavalla "kaikille veelle joukosta Vee on olemassa tuplavee Veessä siten, että veen ja tuplaveen summa on 'nolla'". Eli otettiinpa taas "mielivaltaisesti" mikä tahansa alkio, niin joukosta löytyy myös sellainen alkio, joka voidaan summata ensiksi valittuun alkioon niin, että tulos on edellisessä kohdassa sovittu nollavektori. Jälleen kerran, jos jollekin alkiolle ei olisi löydettävissä tällaista vasta-alkiota, niin kyseessä ei olisi vektoriavaruus.

Eksistenssikvanttorin symboli \(\exists\) muistuttaa peilikuvana kirjoitettua kirjainta 'E', mikä liittynee sen englanninkieliseen ääneen luettuun muotoon "there Exists".

Lopuissa ominaisuuksissa ei tule mitään uusia merkintätapoja, ja ne voidaan lukea samalla periaatteella kuin edellisetkin.

Mitä muuta kannattaisi tehdä lukiessa

Mielikuvitus saa lennellä matematiikkaa lukiessa. On aivan hyvä pohtia, millaiset joukot voisivat olla vektoriavaruuksia ja millaiset eivät. Millainen \(+\) ja \(\heartsuit\) pitäisi olla millekin potentiaaliselle \(V\):lle.

Voisiko "vuoden 2017 aikana kypsyneet omenat" olla vektoriavaruus jollakin plus- ja skalaarikertolaskulla varustettuna? Jos joukko koostuu kokonaisista omenoista ja halutaan skalaarien olevan reaalilukuja, niin ajatusleikki loppuu lyhyeen, kun yritetään määritellä skalaarikertolaskua. Joukossa pitäisi silloin olla mukana esimerkiksi puolikkaat ja kaksinkertaiset omenat. Mitä ihmettä ne olisivat? Omenoiden joukosta ei siis ehkä kannata hahmotella vektoriavaruutta ainakaan reaalilukuskalaareille.

Voisivatko koulusta tutut reaaliluvut \(\mathbb R\) olla myös vektoriavaruus, jos otettaisiin \(V=\mathbb R\) ja \(\mathbb F = \mathbb R\) eli sekä avaruus että kerroinkunta olisivat reaalilukuja, summa olisi reaalilukujen tavallinen summa ja skalaarikertolasku tavallinen kertolasku. Tämä vaikuttaa jo paljon lupaavammalta joukolta vektoriavaruudeksi kuin edellisen kesän omenat. Esimerkki on triviaali, mutta kyllä ohjelmoijan täytyy aina muutenkin ajatella läpi myös triviaalit erityistapaukset!

Vääräänkin osuvat ajatusleikit valmistelevat aivojasi kohtaamaan ja sisäistämään sen todennäköisen vaiheen, jossa oppikirja tai muu materiaali antaa esimerkkejä tunnetuista ja hyödyllisistä vektoriavaruuksista. Tässäkin prujussa sellainen pätkä lienee tulossa.

Lineaarialgebra

Nyt kun on todettu vektoriavaruuden määritelmä, niin määritellään lisäksi yksi tosi tärkeä juttu:

Olkoon \(V\) ja \(U\) vektoriavaruuksia. Lineaarikuvaus avaruudesta \(V\) avaruuteen \(U\) on sellainen kuvaus \(\mathcal{L}:V \rightarrow U\), jolle \(\mathcal L (a + b) = \mathcal L(a) + \mathcal L(b)\) ja \(\mathcal L (\lambda a) = \lambda \mathcal L (a)\) kaikille vektoreille \(a,b \in V\) ja skalaareille \(\lambda \in \mathbb F\).

Aina voidaan asia kääntää toisin päin ja miettiä vastaesimerkkejä: vaikka jokin kuvaus \(f:V\rightarrow U\) olisi kahden vektoriavaruuden välillä hyvin toimiva, niin se ei ole lineaarikuvaus, jos määritelmässä mainittu ehto ei kaikissa tapauksissa ole totta. Sellaisen kuvauksen ominaisuuksia ei voida tutkia lineaarialgebran keinoin. Siis mitä on lineaarialgebra?

Lineaarialgebra on matematiikan ala, joka tutkii, mitä kaikkea siitä seuraa, että on sovittu edellämainitut pari yksinkertaista määritelmää eli ensimmäisessä luvussa todeksi sovitut lauseet avaruuden rakenteesta eli aksioomaat sekä tässä sovitut funktion ominaisuudet. Matematiikka kehittää näiden pohjalta uusia lauseita eli väittämiä, joille kehitetään aukoton todistus. Todistus on tiivistettyä proosaa, jossa osoitetaan vaiheittain aksioomiin ja aiemmin todistettuihin lauseisiin vedoten, että myös uutena esitetty lause on totta, jos kaikki aiemmin väitettykin on. Tietokonegrafiikka on suurelta osin lineaarialgebran tuottamien lauseiden soveltamista, kun piirrettävä kohde on mallinnettu vektoriavaruuksien alkioina eli kohteeseen liittyvät reaalimaailman oliot on samaistettu tarkoituksenmukaisella tavalla sopivien vektoriavaruuksien alkioiden kanssa.

Tällä kurssilla otamme jatkossa soveltajan roolin. Todistuksista on hyvä ymmärtää joitakin perusperiaatteita, joita silloin tällöin käydään läpi. Kuitenkaan meidän ei grafiikkaa tehdessä tarvitse vaivata päätä uusien lauseiden ja todistusten luomiseksi. Luotamme yli sadan vuoden aikana huolellisesti luotuun lineaarialgebraan ja käytämme sitä "suvereenisti" siistien juttujen tuottamiseksi tietokoneen näytölle! Kaikki tarvitsemamme matemaattiset tulokset löytyvät esimerkiksi Wikipediasta, kun vain osataan lukea niitä edellä kuvatuin menettelytavoin. Kurssilla opettelemme kaavojen siirtämistä tietokoneohjelmaan suoritettavaksi koodiksi, joka piirtää. Voidaan ajatella, että se on yleensä "copy-paste-modify" menettelyä, jossa pitää ajatella ja muokkailla hieman enemmän kuin pelkkä "Control-C" + "Control-V" -näppäily vaatii.

Analyysiä

Analyysi on toinen matematiikan ala, joka toki syvemmälle mentäessä yhdistyy myös lineaarialgebraan. Analyysissä sovitaan asioita funktioiden jatkuvuudesta ja funktion arvon muutosherkkyydestä argumenttien suhteen. Sitten tutkitaan, mitä näistä sopimuksista seuraa.

Tällä kurssilla tulee vastaan lähinnä polynomifunktioiden herkkyys niiden argumentin (eli parametrin) suhteen. Kolmannen asteen reaalinen polynomi on funktio \(p:\mathbb R \rightarrow \mathbb R\), joka voidaan kirjoittaa muodossa \[p(t) = a_3 t^3 + a_2 t^2 + a_1 t + a_0,\]

missä \(a_0,a_1,a_2,a_3 \in \mathbb R\) ovat parametrin \(t\) kokonaislukupotensseja vastaavia vakioita. Analyysi antaa meille laskukaavat, joiden avulla kolmannen asteen polynomin derivaatta eli hetkellinen muutosnopeus argumentin \(t\) suhteen on \[p'(t) = 3a_3 t^2 + 2a_2t + a_1.\]

Tämän verran toivottavasti muistetaan koulumatematiikasta. Kertaa, jos et muista! Koulussa argumenttina eli parametrina oli useimmiten symboli \(x\), mutta tässä on valittu \(t\), joka viittaa esimerkiksi aikaan (englanniksi time), jonka suhteen hetkellinen muutosnopeus saa luonnollisemman merkityksen. Symboleissa \(a_3\), \(a_2\), \(a_1\) ja \(a_0\) on nyt käytetty alaindeksiä ilmentämään, että ne ovat eri olioita. Kaikkien tyyppi on tässä nyt reaaliluku, kun puhutaan reaalilukujen polynomeista.

Lineaarialgebran hienouksia on, että tällä kurssilla tulee riittämään derivoida erikseen \(t^3\), \(t^2\), \(t\) ja vakiofunktio \(1\). Voit tehdä tämän kynällä ja paperilla, ja todeta, että homma on kohtalaisen helppoa!

Tullaan myös miettimään useampiulotteisten funktioiden derivaattoja, erityisesti funktioiden \(f:\mathbb R \rightarrow \mathbb R^3\) tai \(f:\mathbb R^2 \rightarrow \mathbb R^3\), mutta näistä meille tällä kurssilla riittää käsitteellinen ymmärrys ilman kummempaa kaavojen pyörittelyä. Matematiikan kurssit Calculus 1-3 ja/tai Johdatus matemaattiseen analyysiin kertovat näistä sitten riittämiin lisää.

Täydellisyyden vuoksi selitetään tässä auki, että \(S^n\) tarkoittaa "S:stä otetuista alkioista muodostettua järjestettyä ännikköä" eli joukon \(S\) \(n\)-kertaista karteesista tuloa itsensä kanssa. Eli esimerkiksi \(\mathbb R ^3 = \mathbb R \times \mathbb R \times \mathbb R\) on joukko, jonka alkiot voidaan kirjoittaa kolmikkona \((a, b, c)\) niin että \(a,b,c \in \mathbb R\). Esimerkiksi on selvästi totta sanoa, että \((0.1, 2, -3.01) \in \mathbb R ^3\). Voit koestaa omaa ymmärrystäsi kehittämällä pari esimerkkiä, jotka kuuluisivat joukkoon \(\mathbb R^4\).

Analyysin toinen puoli on derivoinnin vastakohta eli integrointi eli käytännössä esimerkiksi pinta-alojen, tilavuuksien, kuljettujen kokonaismatkojen tai muiden "kertymien" laskeminen. Tätä tullaan sivuamaan kurssin loppupuolella melko kursorisesti, kun puhutaan mm. siitä, miten mallinnetaan eri valonlähteistä pintojen kautta katsojan silmään heijastuvien fotonien kertymää tai niiden tietyissä silmän reseptorisoluissa aiheuttaman hermosignaalin intensiteettiä.

Ohjelmoija voi useimmiten ajatella integraalia summana, koska loppujen lopuksi tietokoneella on useimmiten aivan pakkokin laskea integraalit äärellisen monen osasen summana, ja se riittää useimpiin tarkoituksiin varsin hyvin.

Trigonometriaa

Trigonometria on matematiikan ala, joka nimensä mukaisesti tutkii kolmioiden mittailua. Tietokonegrafiikassa tarvitaan trigonometrian perusmääritelmiä ja matemaatikoiden löytämiä totuuksia. Mitäpä tässä toistelemaan näitä asioita, jotka jo muinaiset kreikkalaiset tiesivät ja jotka nykyään löytyvät Wikipediasta. Tässä linkit suomenkieliseen ja englanninkieliseen trigonometriaa käsittelevään Wikipedia-sivuun. Kuten tavallista, englanninkielinen sivu kertoo asiasta paljon laajemmin kuin suomenkielinen. Siinä on yksi hyvä syy siihen, että tällä kurssilla käytetään paljon englanninkielisiä lähteitä ja terminologiaa. Tietoa löytyy englanniksi niin paljon paremmin kuin suomeksi!

Kannattaa piirrellä paperille yksikköympyrä eli ympyrä, jonka säde on yhden mittayksikön mittainen, vaikka nyt tuuma tai peukalosi laitimmaisen nivelen mitta, jos haluat sopivan kokoisen konkreettisen mittayksikön kiinnittää. Sitten kannattaa hahmotella ympyrästä lohkaistun sektorin muodostamaa kulmaa ja sitä, miten tietyn suorakulmaisen kolmion (katso Wikipedian kuvia) sivujen pituudet saadaan laskemalla yksikköympyrän sektorin sisäkulmasta sini ja kosini. Englanninkielisen Wiki-sivun 20.1.2019 ladattu versio näyttää antavan sinin ja kosinin määritelmille myös muistisäännön, johon liittyy vanha hippi.

C++ -ohjelmointikieli

C++ -ohjelmointikieli tulee alustavasti tutuksi kurssin aikana. Syvällisempi oppiminen vaatii vuosia aktiivista harjoittelua. Kuten perusmatematiikankin osalta, Internet on pullollaan tietoa ja tutoriaaleja. Harjoiteltava taito on löytää, suodattaa, ja soveltaa kaikkea tuota uuden tiedon liittämiseksi siihen, mitä jo ohjelmoinnin perusteista osaat. Se perustietämyskin kasvaa väistämättä samalla huimasti. C++ tukee olio-ohjelmointia, joten C#:n ja Javan kautta opitut mielikuva- ja suunnittelumallit toteutuvat myös C++:ssa. Alkuvaiheessa haastavimpia asioita voi olla se C++:n laiteläheisyydestä johtuva asia, että polymorfismin hyödyntäminen edellyttää useimmiten suorien muistiosoitteiden eli pointterien käyttöä ohjelmakoodissa. Tähän johdatellaan kurssin harjoituksissa nousujohteisesti. Ensimmäisessä demossa ei vielä tarvita pointtereita, eikä niitä kannata yrittää väkisin käyttää siinä. Pääsääntö: jos pointteria ei tarvita perustellusta syystä, sitä ei tule käyttää!

Esitietona oletetaan siis olio-ohjelmoinnin ja C#:n ja/tai Javan tunteminen sillä tasolla kuin ne meidän yliopistossamme käydään kursseilla Ohjelmointi 1 ja Ohjelmointi 2, joissa on tehty yhteensä 14 op eli noin 378 tuntia aktiivista harjoittelua. Se on tietyn (keskimääräisen ja kiistanalaisenkin) nyrkkisäännön mukaan vähän vajaa 4% siitä ajasta, joka vaaditaan asiantuntemuksen kehittymiseen jostakin asiasta. Kolmantena ohjelmointikurssina käytynä tämä kurssi tarjoaa 135 tunnillaan noin kolmasosan lisää kokemusta johtaen yhteensä 503 tunnin kokemukseen eli 5% asiantuntemuksesta. Nämä ovat aina nyrkkisääntöjä ja keskimääräisiä suosituksia ja muutenkin hyvin pehmeitä lukuja. Pointti lienee, että pitää olla nöyrä ja tehdä kovasti töitä.

Kehitysympäristö eli IDE

Kokemus on osoittanut, että parin ensimmäisen ohjelmointikurssin jälkeen melkein kaikilla opiskelijoilla on vielä paljon opittavaa IDE:n käytössä. Harjaannutetaan tätä, eikä päästetä itseämme helpolla ennen kuin IDE laulaa sormien alla kuin saksofoni taitavan soittajan puhaltamana. Huomioitavaa:

  • Debuggerin käyttö, breakpointtien asettaminen, askeltaminen funktioihin sisään ja ulos ja datan tutkiminen pitää saada sujuvaksi.

  • Lähdekoodin selaaminen ja muokkaaminen pitää saada tapahtumaan nopeammin kuin ajatus, toisin sanoen hitaasta hiirestä kannattaa pitää pääosin näpit irti ja opetella oman IDEn näppäinkomennot mm. seuraaviin asioihin:

    • Nimien automaattinen täydennys

    • Siirtyminen kursorin alla olevan symbolin määritelmään

    • Siirtyminen edelliseen editointikohtaan (eli esim. takaisin tarkistettavan symbolin määritelmästä)

    • Kursorin siirtäminen sana ja rivi kerrallaan

    • Sanojen ja rivien maalaaminen ja cut-paste

    • Yksinkertaiset refaktoroinnit kuten muuttujan nimen vaihtaminen siihen tarkoitetulla automaattisella toiminnolla.

  • Suurin osa ajankäytöstä pitäisi saada tapahtumaan ajattelun, uusien juttujen lukemisen ja kynän ja paperin puolella; koodin näpräys pitäisi saada tuntumaan sivutoiminnolta, joka hoituu saman tien, kun ajatus on syntynyt.

  • IDEn näyttämien lokien eli virheilmoitusten ja varoitusten tulkitseminen; kääntäjä ei yleensä varoita aivan turhaan. Virhetilanteessa lokin ensimmäinen virheilmoitus on avain päällimmäisen virheen korjaamiseen, joten se tulee paikantaa, lukea ja ymmärtää, ennen kuin korjaustoimenpiteisiin on mielekästä ryhtyä.

  • jne.

Harjoitellaan loppuelämä ja tälläkin kurssilla taas vähän lisää, aktiivisesti ja tietoisesti. Pakotetaan itsemme tekemään asiat uudella, aiempaa paremmalla tavalla!

Ohjelman suoritusympäristö: argumentit, syöttövirta

Muistetaan, tai opitaan tässä kohtaa, että ohjelma saa käyttöönsä standardisyöttövirran sekä mahdollisesti erinäisen määrän argumentteja komentoriviltä. Kaikissa tämän kurssin esimerkkikoodeissa sovelletaan näitä asioita, ja omasta IDEstä kannattaakin varmistaa, miten IDEn kautta debugatessa saadaan ohjattua tiedosto stdin-virtaan ja miten IDEstä saadaan annettua komentoriviargumentit.

Matriisit

Tässä luvussa kerrotaan matriiseista kohderyhmälle, joka ei ole välttämättä kuullutkaan niistä aikaisemmin.

Matriisien mekaaniset laskut on mahdollista ja sopivaa opetella erillisenä asiana, ennen kuin niiden yhteyttä vektoreihin aletaan miettiä.

Hämärästä aamunkoittoon, jaarittelusta selkokieleen

Kulttielokuvassa Hämärästä aamunkoittoon (From dusk till dawn) vaihtuu tyylilaji täydellisesti noin 45 minuutin kohdalla.

Samoin käy tälle kurssimateriaalille nyt.

Seuraavat osiot ovat kirjoittajan yritys tuottaa selkokieltä.

Selkokielessä sanotaan vain kaikkein olennaisimmat asiat, ja siinä pyritään käyttämään mahdollisimman yksinkertaisia virkkeitä.

Virkkeet aloitetaan sivun vasemmasta laidasta, ja niiden väliin jätetään valkoista tilaa.

Aikuiskouluttajan pedagogisissa opinnoissa kerrottiin, että selkokieli soveltuu kaikille.

Siitä on erityistä hyötyä henkilöille, joilla on niin sanottuja lukemisen vaikeuksia.

Lukemisen ja avaruudellisen hahmottamisen haasteet tekevät ohjelmoinnista ja grafiikasta jo muiltakin osin työlään aihepiirin.

Siitä syystä on perusteltua tuottaa oppimateriaalin teksti selkokielellä, mikäli siihen on mahdollisuus.

Tämä on uutta materiaalia, joka tuotetaan nyt kokeeksi ohjeiden mukaisella selkokielellä.

Ehkä materiaali lähtee nyt kunnolla lentoon, kuten Hämärästä aamunkoittoon -elokuva zombien ilmestyessä.

Matriisit ja matriiseilla laskeminen

Matriisi

Matriisi on neliskulmainen taulukko jonkinlaisista olioista.

Tavallisimmin matriisi sisältää esimerkiksi reaalilukuja tai lausekkeita, joista auki laskemalla tulisi reaalilukuja.

Tällä kurssilla joissakin matriiseissa on myös muunlaisia olioita.

Esimerkiksi seuraava taulukko on reaaliluvuista koostuva matriisi:

\[ \begin{bmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \end{bmatrix} \]

Matriisin ympärille kirjoitettavat sulkumerkit voivat yhtä hyvin olla kaarisulut kuin hakasulut:

\[ \begin{pmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \end{pmatrix} \]

Jos matriisin ympärillä on muuta kuin kaari- tai hakasulut, tarkoitetaan yleensä jotakin muuta, kuten jotakin matriisin ominaisuutta kuvaavaa tunnuslukua.

Tässä tekstissä käytetään matriiseille hakasulkuja, jotta ei tule tarpeetonta sekaannusta matriisien ja tavallisten, kaarisulkuihin kirjoitettujen, järjestettyjen listojen välille.

Matriisin koko ja tyyppi

Olkoot tästä eteenpäin \(n,m,p \in \mathbb N\). Toisin sanoen sovitaan, että symboleilla \(n\), \(m\) ja \(p\) kuvataan joitakin tiettyjä, mielivaltaisesti valittuja, nollaa suurempia kokonaislukuja.

Jos matriisissa on \(m\) riviä ja \(n\) saraketta, sanotaan, että se on \(m\) kertaa \(n\) -matriisi, tai lyhyemmin kirjoitettuna \(m \times n\) -matriisi.

Edellisen esimerkin matriisi on siis \(2 \times 3\) -matriisi.

Rivien määrä ilmoitetaan ensiksi ja sarakkeiden määrä toiseksi.

Matriisin tarkka "tyyppi" määrittyy sen muodon ja sisällön tyypin perusteella.

Sekä matematiikassa että ohjelmoidessa laskutoimitus on mahdollista vain silloin, kun sen operandien tyypit ovat yhteensopivat.

Tämä sama asia pätee matriiseille.

Pidä aina huolta olioiden tyyppien yhteensopivuudesta!

Jos on vaikeuksia muistaa tuliko rivit vai sarakkeet ensin, lineaarisen algebran ja geometrian kurssin opettaja Tero Kilpeläinen antoi hyvän muistisäännön: aakkosjärjestys!

13 Dec 21

Matriisin alkiot ja indeksointi

Matriisin sisältönä olevat oliot eli alkiot eli elementit indeksoidaan kahdella indeksillä.

Ensimmäinen indeksi ilmoittaa rivin, jossa alkio on.

Jälkimmäinen indeksi ilmoittaa sarakkeen, jossa alkio on.

Matriiseille käytetään usein symbolina isoa kirjainta ja sen alkioille vastaavaa pientä kirjainta, jossa on indeksit mukana.

Rivi- ja sarakeindeksit voidaan kirjoittaa pilkulla erotettuina peräkkäin, pienellä fontilla, alaoikealle alkion symbolista katsoen.

Yleisesti ottaen \(m \times n\) -matriisi \(A\) kaikkine elementteineen \(a_{i,j}\), missä \(i=1,\ldots,m\) ja \(j=1,\ldots,n\) voidaan kirjoittaa auki kolmen pisteen avulla seuraavasti:

\[ A = \begin{bmatrix} a_{1,1} & \dots & a_{1,n} \\ \vdots & \ddots & \vdots \\ a_{m,1} & \dots & a_{m,n} \end{bmatrix} \]

Matriisin elementtien lukumäärä on \(mn\). Varmistu itse esimerkkien avulla.

Esimerkiksi \(3 \times 5\) -matriisi \(B\) alkioinaan \(b_{i,j}, i=1,\ldots,3, j=1,\ldots,5\) voitaisiin kirjoittaa seuraavasti:

\[ B = \begin{bmatrix} b_{1,1} & b_{1,2} & b_{1,3} & b_{1,4} & b_{1,5} \\ b_{2,1} & b_{2,2} & b_{2,3} & b_{2,4} & b_{2,5} \\ b_{3,1} & b_{3,2} & b_{3,3} & b_{3,4} & b_{3,5} \end{bmatrix} \]

Alkiot voidaan kirjoittaa myös laittamalla matriisin oman nimen perään alaindeksit. Esimerkiksi \(B_{2,4}\) olisi sama kuin \(b_{2,4}\) yllä olevassa esimerkissä.

Jos tiedetään, että indeksit ovat yksinumeroisia tai kirjainsymboleita niin pilkku jätetään usein kirjoittamatta.

Siis edelleen \(B_{24}\), \(b_{24}\), \(a_{1n}\), \(A_{m1}\) voisivat olla poimintoja edellä nähtyjen esimerkkimatriisien \(A\) ja \(B\) sisältämistä alkioista.

Matemaattisen tekstin kirjoittaja saattaa helposti olettaa, että lukija tunnistaa minkä tahansa näistä merkintätavoista.

Huolellinen kirjoittaja ei kuitenkaan käytä saman kirjallisen tuotoksen sisällä kuin yhtä merkintätapaa.

Valitettavasti kaikki kirjoittajat eivät aina ole huolellisia.

Matriisien peruslaskutoimitukset

Käydään läpi muutamia matriisien laskutoimituksia.

Ne ovat skalaarikertolasku, matriisisumma, transponointi ja matriisikertolasku.

Meidän kannaltamme tärkein on matriisikertolasku, mutta muitakin käytetään.

Näitä mekaanisia toimenpiteitä on syytä harjoitella kynällä ja paperilla paljon, jotta ne juurtuvat mieleen.

Keksi ja laske auki esimerkkejä, joissa alkiot ovat reaalilukuja ja matriisit eri kokoisia, mutta sopivan pieniä käsipelillä laskemiseen.

Tee sitä niin kauan, että osaat unissasikin!

Yksi opeteltava taito myös ohjelmoinnissa on yksinkertaisten esimerkkien tekeminen ja varmistaminen käsipelillä ennen kuin ohjelmoidaan tai edes tehdään varsinaiset automaattiset testitapaukset ohjelmalle.

Pitää tietää, mitä on tekemässä, ja konkreettinen näppituntuma on siihen hyvä keino.

Matriisin kertominen skalaarilla

Tarkastellaan \(m \times n\) matriisia A

\[ A = \begin{bmatrix} a_{1,1} & \dots & a_{1,n} \\ \vdots & \ddots & \vdots \\ a_{m,1} & \dots & a_{m,n} \end{bmatrix}. \]

Määritellään matriisille kertominen skalaarilla \(\lambda \in \mathbb F\) niin, että kaikki sen alkiot kerrotaan \(\lambda\):lla:

\[ \lambda A := \begin{bmatrix} \lambda a_{1,1} & \dots & \lambda a_{1,n} \\ \vdots & \ddots & \vdots \\ \lambda a_{m,1} & \dots & \lambda a_{m,n} \end{bmatrix}. \]

Esimerkiksi

\[ \frac{1}{6} \begin{bmatrix} 1 & -3 & 3 & -1 \\ 4 & 0 & -6 & 3 \\ 1 & 3 & 3 & -3 \\ 0 & 0 & 0 & 1 \end{bmatrix} = \begin{bmatrix} 1/6 & -3/6 & 3/6 & -1/6 \\ 4/6 & 0/6 & -6/6 & 3/6 \\ 1/6 & 3/6 & 3/6 & -3/6 \\ 0/6 & 0/6 & 0/6 & 1/6 \end{bmatrix} = \begin{bmatrix} 1/6 & -1/2 & 1/2 & -1/6 \\ 2/3 & 0 & -1 & 1/2 \\ 1/6 & 1/2 & 1/2 & -1/2 \\ 0 & 0 & 0 & 1/6 \end{bmatrix}. \]

Tämä esimerkki tulee vastaan kurssin toisessa harjoitustehtävässä.

Matriisien alkioittainen summa

Tarkastellaan kahta samankokoista eli \(m \times n\) matriisia A ja B:

\[ A = \begin{bmatrix} a_{1,1} & \dots & a_{1,n} \\ \vdots & \ddots & \vdots \\ a_{m,1} & \dots & a_{m,n} \end{bmatrix} \quad \text{ja} \quad B = \begin{bmatrix} b_{1,1} & \dots & b_{1,n} \\ \vdots & \ddots & \vdots \\ b_{m,1} & \dots & b_{m,n} \end{bmatrix}. \]

Määritellään näille yhteenlasku niin, että vastaavissa indekseissä olevat alkiot lasketaan aina yhteen keskenään:

\[ A + B := \begin{bmatrix} a_{1,1} + b_{1,1} & \dots & a_{1,n} + b_{1,n} \\ \vdots & \ddots & \vdots \\ a_{m,1} + b_{m,1} & \dots & a_{m,n} + b_{m,n} \end{bmatrix}. \]

Keksi itse esimerkki tai pari, ja laske auki paperilla.

Muista tyyppien yhteensopivuus: Kahta erikokoista matriisia ei voi laskea tällä tavoin yhteen keskenään, koska joillekin alkioillehan ei silloin löytyisi vastinparia toisessa matriisissa!

Kun keksit esimerkkejä, on hyvä miettiä myös vastaesimerkkejä eli sellaisia esimerkkejä, joille ei voikaan tehdä jotakin. Esimerkiksi siis eri muotoisten matriisien yhteenlasku.

Vastaesimerkki saa sinut ymmärtämään asiasta lisää aivan samoin kuin "myötäesimerkit".

Matriisin transpoosi

Tarkastellaan \(m \times n\) matriisia A

\[ A = \begin{bmatrix} a_{1,1} & \dots & a_{1,n} \\ \vdots & \ddots & \vdots \\ a_{m,1} & \dots & a_{m,n} \end{bmatrix}. \]

Määritellään sille operaatio nimeltä transpoosi, jota merkitään \(A^T\) ja joka tarkoittaa, että matriisin rivit ja sarakkeet vaihdetaan päikseen:

\[ A^T = \begin{bmatrix} a_{1,1} & \dots & a_{m,1} \\ \vdots & \ddots & \vdots \\ a_{1,n} & \dots & a_{m,n} \end{bmatrix}. \]

Esimerkiksi

\[ \begin{bmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \end{bmatrix}^T = \begin{bmatrix} 1 & 4 \\ 2 & 5 \\ 3 & 6 \end{bmatrix} . \]

Vastaavasti tietenkin

\[ \begin{bmatrix} 1 & 4 \\ 2 & 5 \\ 3 & 6 \end{bmatrix}^T = \begin{bmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \end{bmatrix} . \]

Kuten aina, pysy kärryillä tyypeistä:

  • Huomaa, että transpoosi tekee \(m \times n\) -matriisista \(n \times m\) -matriisin.

  • Jos matriisissa oli eri määrä rivejä kuin sarakkeita, niin sen transpoosi on kokonaisuudessaan eri tyyppinen olio.

  • Sen sijaan, jos kyseessä on neliömatriisi eli \(m=n\), niin transpoosi voi muuttaa matriisin sisältöä, mutta ei sen tyyppiä!

Tällaisilla "pikkujutuilla" on väliä muun muassa tietokonegrafiikassa.

Kun matriisista otetaan transpoosi, on tyypillistä sanoa, että se transponoidaan.

Matriisien kertominen keskenään

Varsinkin matriisien kertolaskua on syytä harjoitella kynällä ja paperilla eri kokoisten matriisien kanssa niin kuin Karate Kid -elokuvan poika jynssää mestarin autoa pyörivin liikkein ja oppii samalla taistelussa tarvittavat liikeradat. Kirjoittaja meinasi divergoida selkokielestä. Sori siitä.

Matriisien kertolaskua on syytä harjoitella kynällä ja paperilla eri kokoisten matriisien kanssa.

Ilman käytännön kokemusta ja konkreettista tuntumaa matriisikertolaskusta tietokonegrafiikka ja moni muu mielenkiintoinen asia jää helpommin käsityskyvyn ulkopuolelle.

Harjoitellessa tulet myös huomaamaan, että laskemisessa ei ole mitään vaikeaa, kun sitä harjoittelee riittävästi.

Matriisien kertolasku määritellään sellaisille matriiseille, joissa kertoja eli vasemmanpuoleinen operandi sisältää saman verran sarakkeita kuin kerrottavassa eli oikeanpuoleisessa operandissa on rivejä.

Määritellään matriisikertolasku seuraavaksi ensin matemaattisesti.

Koetetaan sitten löytää algoritmi, jolla laskenta onnistuu käsin tai tietokoneella.

Olkoon meillä \(m \times n\) -matriisi \(A\) ja \(n \times p\) -matriisi \(B\) seuraavasti \[ A = \begin{bmatrix} a_{1,1} & \dots & a_{1,n} \\ \vdots & \ddots & \vdots \\ a_{m,1} & \dots & a_{m,n} \end{bmatrix} \quad \text{ja} \quad B = \begin{bmatrix} b_{1,1} & \dots & b_{1,p} \\ \vdots & \ddots & \vdots \\ b_{n,1} & \dots & b_{n,p} \end{bmatrix}. \]

Silloin näille voidaan määritellä kertolasku \(AB\) seuraavasti:

\[ AB := \begin{bmatrix} \sum_{k=1}^{n} a_{1,k} b_{k,1} & \dots & \sum_{k=1}^{n} a_{1,k} b_{k,p} \\ \vdots & \ddots & \vdots \\ \sum_{k=1}^{n} a_{m,k} b_{k,1} & \dots & \sum_{k=1}^{n} a_{m,k} b_{k,p} \\ \end{bmatrix}. \]

Nyt tässä on käytetty symbolia \(\sum\), jota ei tule pelästyä.

Se on kreikkalainen kirjain, iso sigma, ja sillä tarkoitetaan summaa, jossa juoksutetaan sigman alaindeksissä esiteltyä muuttujaa yläindeksiin asti ja yhdistetään pluslaskulla kaikki sigman jälkeen tulevan lausekkeen esiintymät niin, että indeksimuuttujan arvo on sijoitettu paikalleen.

Ohjelmoijana voit ymmärtää sigman merkityksen helposti for -silmukkana, jonka sisällä tehdään operaatio "summa += termi".

Älä jää kuitenkaan suoritusjärjestyksen kahleisiin. Summan laskujärjestyksellä ei ole väliä!

Jokainen tulosmatriisin alkio \((AB)_{i,j}\) lasketaan siis kaavalla \[ (AB)_{i,j} = \sum_{k=1}^{n} a_{i,k} b_{k,j} = a_{i,1} b_{1,j} + a_{i,2} b_{2,j} + \ldots + a_{i,n} b_{n,j} \] tulosmatriisin indekseille \(i=1,\ldots,m\) ja \(j=1,\ldots,p\).

Tärkeätä on hahmottaa matriisikertolaskusta \(AB\) matriisin \(A\) rivin ja matriisin \(B\) vastaavan sarakkeen yhteys kuhunkin tulosmatriisin alkioon.

Loput laskusta on vain toisiaan vastaavien rivi- ja sarakealkioiden kertominen keskenään ja plussien laittaminen tulojen väliin.

Esimerkki:

\[ \begin{bmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \end{bmatrix} \begin{bmatrix} 7 & 8 \\ 9 & 10\\ 11 & 12 \end{bmatrix} = \begin{bmatrix} 1\cdot 7 + 2\cdot 9 + 3 \cdot 11 & 1 \cdot 8 + 2 \cdot 10 + 3 \cdot 12 \\ 4\cdot 7 + 5\cdot 9 + 6 \cdot 11 & 4 \cdot 8 + 5 \cdot 10 + 6 \cdot 12 \end{bmatrix} = \begin{bmatrix} 58 & 64 \\ 139 & 154 \end{bmatrix} \]

Esimerkki on laskettu käsin, joten siinä voi olla laskuvirheitä.

Matriisikertolaskun tuloksen tyyppi

Huomaa, että tulosmatriisin muoto perustuu kertojan rivien ja kerrottavan sarakkeiden määrään.

Kun kerrotaan \(m \times n\) -matriisi ja \(n \times p\) -matriisi, niin tulos on \(m \times p\) matriisi.

Jos kerrottavat eivät ole neliömatriiseja, niin tulosmatriisi on vääjäämättä eri muotoinen ja siten "eri tyyppinen" kuin kumpikaan kerrotuista matriiseista.

Lisää esimerkkejä matriisikertolaskusta:

Tässä on esimerkki, jossa oikeanpuoleinen kerrottava sattuu olemaan leveämpi kuin vasemmanpuoleinen:

\[ \begin{bmatrix} 1 & 0 & 3 \\ 4 & 2 & 2 \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} 1 & -1 & 1 & -1 & 1 & -1\\ 0 & 1 &0 & 1 &0 & 1 \\ 1 & 1 & 1 & 1 & 1 & 1 \end{bmatrix} = \begin{bmatrix} 4 & 2 & 4 & 2 & 4 & 2\\ 6 & 0 & 6 & 0 & 6 & 0 \\ 1 & 1 & 1 & 1 & 1 & 1 \end{bmatrix} \]

(tämäkin esimerkki päässä laskettu, joten voi olla virheitä; tarkista itse!)

Seuraavassa esimerkissä \(m=p=1\) eli vasemmassa matriisissa on yksi rivi ja oikeanpuoleisessa yksi sarake:

\[ \begin{bmatrix} 1 & 2 & 3 \end{bmatrix} \begin{bmatrix} 4 \\ 5 \\ 6 \end{bmatrix} = \begin{bmatrix} 4 + 10 + 18 \end{bmatrix} = \begin{bmatrix} 32 \end{bmatrix}. \]

Vielä yksi valmiiksi auki laskettu esimerkki:

\[ \begin{bmatrix} 4 \\ 5 \\ -6 \end{bmatrix} \begin{bmatrix} 1 & -0.1 & 0.001 \end{bmatrix} = \begin{bmatrix} 4 & -0.4 & 0.004 \\ 5 & -0.5 & 0.005 \\ -6 & 0.6 & -0.006 \end{bmatrix} \]

Keksi itse lisää!

Tutki käytännössä, miten vasemman ja oikeanpuoleisen matriisin muoto vaikuttaa tuloksen muotoon.

Tutustu vastaesimerkkien kautta sen muotoisiin matriiseihin, joita ei voisikaan laskea yhteensopimattoman muodon vuoksi.

Muotoja voi hahmotella myös piirtämällä numeroiden sijaan matriiseihin vain pisteitä, pallukoita ja possunaamoja ja miettimällä, minkä sarakkeiden ja minkä rivien alkioita pitäisi kertoa ja summata keskenään tuloksen minkäkin possunaama-alkion laskemiseksi.

Voit kehitellä luovasti esimerkkilukuja, joilla on helppo laskea, mutta jotka vaikuttavat tulokseen.

Esimerkiksi 0, 1, 10, 100, jne ovat helppoja reaalilukuja kerto- ja pluslaskussa.

Jotta omat esimerkit pysyvät täydellisenä, kannattanee kokeilla myös muutama negatiivinen ja murtoluku, jotta muistetaan, että lasketaan reaaliluvuilla.

Voi myös laskea käyttäen matriisin alkioina symboleita \(a, b, c, x, y, z, \ldots\) tai lausekkeita kuten \(p(t)\) tai \(p'(t)\).

Tärkeitä huomioita matriisien kertolaskusta

Kannattaa muistaa seuraavat tärkeät asiat matriisien kertolaskusta:

Matriisikertolasku ei kommutoi kaikille matriiseille, ei edes neliömatriiseille, eli ei ole aina \(AB = BA\).

Koeta keksiä itse jotkut matriisit \(A\) ja \(B\), joille voi laskea sekä \(AB\) attä \(BA\), mutta \(AB \ne BA\).

Matriisikertolaskuja voi yhdistellä peräkkäin, jos matriisien muodot ovat sopivat.

Esimerkiksi jos \(A\), \(B\) ja \(C\) ovat sopivan muotoisia matriiseja, niin voitaisiin laskea määritelmän mukaisesti joko \(A(BC)\) tai \((AB)C\).

Lopputuloksen muoto riippuu silloin \(A\):n rivien ja \(C\):n sarakkeiden määrästä.

Lineaarialgebran kurssin käyneet ovat selvittäneet, että \(A(BC)=(AB)C\), eli että matriisikertolasku on assosiatiivinen.

Luotetaan me nyt heihin ja muihin matemaatikoihin, ja uskotaan, että laskujärjestystä ilmaisevat sulut voidaan jättää pois assosiatiivisuuden perusteella: \(ABC=(AB)C=A(BC)\).

Matemaatikot kertovat myös esimerkiksi, että \((ABC)^T = C^T B^T A ^T\).

Muita matriisien ominaisuuksia löytyy esimerkiksi Internetistä ja oppikirjoista.

Niiden syväoppiminen, perustelu ja luonteva käyttely uusien kaavojen luomisessa jätettäköön kurssille Lineaarialgebra ja geometria 1, joka keskittyy niihin täydellä teholla.

Näitä ja muitakin matriisilaskun ominaisuuksia käytellään kuitenkin tietokonegrafiikassa päivittäin, ja joistakin niistä tulemme näkemään esimerkkejä jo peruskurssin aikana.

Joitain erityisiä matriiseja

Nyt tiedetään, millainen on yleinen matriisien "luokka", eli minkälaiset taulukkomaiset oliot voivat olla tyypiltään \(m \times n\) -matriiseja.

Seuraavaksi katsotaan joitakin tietokonegrafiikassa ja muissa sovelluksissa vastaan tulevia erityisen muotoisia matriiseja.

Neliömatriisi

Matriisi on neliömatriisi, jos siinä on yhtä paljon rivejä kuin sarakkeita.

Esimerkiksi seuraava matriisi on \(3 \times 3\) -neliömatriisi:

\[ \begin{bmatrix} 1.0 & 2.0 & 3.0 \\ 4.0 & 5.0 & 6.0 \\ 7.0 & 8.0 & 9.0 \end{bmatrix} \]

Matriisikertolasku on \(n \times n\) -reaalilukumatriisien joukossa suljettu laskutoimitus, koska tuloksen tyyppi on sama kuin kahden operandinsa tyyppi.

Neliömatriisien kertolaskuja voidaan siis yhdistellä peräkkäin niin paljon kuin halutaan.

Esimerkiksi, jos \(A, B, C, D, E, F, G\) ovat \(4 \times 4\) -matriiseja, niin myös kertolaskun tulos \(ABCDEFG\) on \(4 \times 4\) -matriisi.

Koska kertolasku on assosiatiivinen, niin kertolaskuun voidaan laittaa sulkuja, miten vain halutaan. Esimerkiksi voidaan luottaa siihen, että \[ ABCDEFG = (ABC)DE(FG) = A(BC(DE)F)G \] ja niin edelleen.

Samalla on erittäin tärkeä muistaa, että neliömatriiseillekaan kertolasku ei kommutoi aina.

Yleensä siis esimerkiksi \(ABCDEFG \ne ABCDFEG\), ellei esimerkissä tiedettäisi jotakin hyvin syvällistä ja varmaa matriisien \(E\) ja \(F\) keskinäisestä luonteesta.

Kolmiomatriisit

Joskus ilmiön mallinnus tai hyödyllisen algoritmin rakentaminen johtaa matriiseihin, joissa nollien ja mahdollisesti nollasta poikkeavien alkioiden sijoittumisessa on mallista johtuvaa säännönmukaisuutta.

Joskus pyritään etsimään mahdollisimman paljon nollia sopivissa kohdissa sisältäviä matriiseja.

Syy voi olla esimerkiksi, että mallista tai algoritmista saadaan silloin tehokkaampi tai ymmärrettävämpi.

Jos \(n \times n\) -neliömatriisissa \(A\) on varmasti nollia alkioissa \(A_{i,j}\), joiden rivi-indeksi \(i\) on suurempi kuin sarakeindeksi \(j\), niin A on yläkolmiomatriisi.

Lyhyemmin sanoin A on yläkolmiomatriisi, jos \(A_{i,j} = 0\), kun \(i>j\).

Esimerkiksi seuraava on yläkolmiomatriisi:

\[ \begin{bmatrix} 0.1 & 2.1 & 0 & -4 \\ 0 & 6 & 7 & 0 \\ 0 & 0 & 11 & 0 \\ 0 & 0 & 0 & 16 \end{bmatrix}. \]

Esimerkistä voi nähdä, että myös yläkolmion puolella voi olla nollia.

Määritelmän kannalta tärkeää on, että kohdissa \(i>j\) on aina varmasti 0.

Vastaavasti \(n \times n\) -matriisi \(A\) on alakolmiomatriisi, jos \(A_{i,j} = 0\), kun \(i<j\).

Esimerkiksi seuraava on alakolmiomatriisi:

\[ \begin{bmatrix} 0.1 & 0 & 0 & 0\\ 2.1 & 6 & 0 & 0 \\ 0 & 7 & 11 & 0 \\ -4 & 0 & 0 & 16 \end{bmatrix}. \]

Tämä esimerkki sattuu olemaan edellisen esimerkin transpoosi.

Matemaatikot tietävät muun muassa, että \(n \times n\) -yläkolmiomatriisien joukko on suljettu matriisikertolaskun suhteen ja muodostaa siksi jotakin, mitä heidän on mielekästä sanoa \(n \times n\) -neliömatriisien muodostaman algebran alialgebraksi.

Diagonaalimatriisi

Millainen on matriisi \(A\), joka on \(n \times n\) -neliömatriisi ja samaan aikaan sekä yläkolmiomatriisi että alakolmiomatriisi?

Siinä täytyy olla nollia alkioissa \(A_{i,j}\), joissa indekseille joko \(i<j\) tai \(i>j\) eli aina, kun \(i \ne j\).

Muita kuin nollia voi olla siis vain alkioissa \(A_{i,j}\), joissa \(i=j\).

Tällaisen matriisin nimi on diagonaalimatriisi.

Diagonaalimatriisissa on \(n\) mahdollisesti nollasta eroavaa alkiota paikoissa \(A_{i,i}\), \(i=1,\ldots,n\), joita sanotaan neliömatriisin diagonaaliksi.

Esimerkiksi seuraava on diagonaalimatriisi:

\[ \begin{bmatrix} 0.1 & 0 & 0 & 0\\ 0 & 6 & 0 & 0 \\ 0 & 0 & 11 & 0 \\ 0 & 0 & 0 & 16 \end{bmatrix}. \]

Kolmio- ja diagonaalimatriiseja merkitessä on tyypillistä kuvata nolla-aluetta yhdellä sopivaan kohtaan piirretyllä nollalla.

Esimerkiksi seuraava voisi olla tapa kirjoittaa edellisen esimerkin diagonaalimatriisi:

\[ \begin{bmatrix} 0.1 & & & 0\\ & 6 & & \\ & & 11 & \\ 0 & & & 16 \end{bmatrix}. \]

Sama voidaan kirjoittaa myös \(\mathop{Diag}(0.1,6,11,16)\).

Diagonaalimatriisilla kertomisella on helppo ja hyödyllinen tulkinta.

Kun diagonaalimatriisilla kerrotaan vasemmalta, tuloksessa on matriisin rivit skaalattuna diagonaalin alkioilla.

Esimerkiksi

\[ \begin{bmatrix} 10 & 0 & 0 \\ 0 & 100 & 0 \\ 0 & 0 & 1000 \end{bmatrix} \begin{bmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 9 \end{bmatrix} = \begin{bmatrix} 10 & 20 & 30 \\ 400 & 500 & 600 \\ 7000 & 8000 & 9000 \end{bmatrix}. \]

Kun diagonaalimatriisilla kerrotaan oikealta, tuloksessa on vasemmanpuoleisen matriisin sarakkeet skaalattuna diagonaalin alkioilla.

Esimerkiksi

\[ \begin{bmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 9 \end{bmatrix} \begin{bmatrix} 10 & 0 & 0 \\ 0 & 100 & 0 \\ 0 & 0 & 1000 \end{bmatrix} = \begin{bmatrix} 10 & 200 & 3000 \\ 40 & 500 & 6000 \\ 70 & 800 & 9000 \end{bmatrix}. \]

Jos et aiemmin keksinyt esimerkkiä, jossa \(AB \ne BA\), niin tässä on yksi sellainen.

Identiteettimatriisi

Tärkeä diagonaalimatriisi on identiteettimatriisi, jossa kaikki diagonaalin alkiot ovat \(1\in \mathbb F\).

Esimerkiksi reaaliluvuista koostuva \(4 \times 4\) -identiteettimatriisi on

\[ \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} \]

Tällä on oma merkintänsä, \(I_4\) eli iso I-kirjain, jossa on neliömatriisin koko alaindeksinä.

Jos matriisin koko on selvä asiayhteydestä, ei alaindeksiä tarvita.

Esimerkiksi, jos tunnetusti \(A\) on \(100 \times 100\) -matriisi, niin seuraavassa yhtälössä myös \(I\) on \(100 \times 100\) -matriisi, jossa on \(100\) kappaletta ykköstä diagonaalilla ja nollia muissa \(9900\) alkiossa:

\[ AI=IA=A. \]

Yhtälö \(AI=IA=A\) itsessään on aina totta, kun \(A\) on mikä tahansa neliömatriisi ja \(I\) samankokoinen identiteettimatriisi.

Se sanoo, että identiteettimatriisilla voi kertoa oikealta ja vasemmalta niin, että tulokseksi jää matriisikertolaskun toinen operandi.

Tämä ominaisuus on identiteettimatriisin nimityksen takana.

Identiteettimatriisi on neliömatriisien matriisikertolaskun suhteen neutraalialkio.

Käänteismatriisi

Jos sattuu olemaan niin, että \(AB=BA=I\), kun \(A\) ja \(B\) ovat \(n \times n\) -matriiseja ja \(I=I_n\), sanotaan, että \(A\) on kääntyvä ja \(B\) on \(A\):n käänteismatriisi.

Matriisin \(A\) käänteismatriisi kirjoitetaan \(A^{-1}\) eli käytetään samaa merkintää kuin reaaliluvun käänteisluvuille.

Kaikilla matriiseilla ei ole käänteismatriisia, vaikka suurella osalla on.

Jos matriisi ei ole kääntyvä, sanotaan, että se on singulaarinen.

Muistisääntönä voinee ajatella, että singulaarinen matriisi on "yksin" ilman vastinparia, jolla kertomalla tulisi tulokseksi nätti identiteettimatriisi.

Käänteismatriisin löytäminen ei ole aivan helppo laskutoimitus.

Sitä ei kannata lähteä etsimään kynän ja paperin kanssa ennen lineaarialgebran kurssin käymistä.

Numeerinen lineaarialgebra on tieteenala, jonka tavoitteena on löytää mahdollisimman tehokkaita menetelmiä isojen matriisien kääntämiseksi.

Soveltaja, kuten tietokonegrafiikan tekijä, käyttää valmista kirjastoa tai netistä haettua, tunnetusti hyvää, algoritmia, kun hän havaitsee koodissaan tarpeelliseksi kääntää jokin matriisi.

Käänteistranspoosi

Jos \(n \times n\) -matriisi \(A\) on kääntyvä, niin matriisi \((A^{-1})^T\) eli käänteismatriisin transpoosi on nimeltään A:n käänteistranspoosi.

Ali- ja lohkomatriisit

Poimimalla \(m \times n\) -matriisista tietyt rivit ja sarakkeet uuteen matriisiin, voidaan muodostaa alimatriisi, jonka koko on korkeintaan niin iso kuin alkuperäisen matriisin.

Esimerkiksi \(3 \times 4\) -matriisista

\[ \begin{bmatrix} 1 & 2 & 3 & 4 \\ 5 & 6 & 7 & 8 \\ 9 & 10& 11& 12 \end{bmatrix} \]

voitaisiin poimia riveiltä 1 ja 2 ja sarakkeista 2 ja 3 uusi \(2 \times 2\) -matriisi

\[ \begin{bmatrix} 2 & 3 \\ 6 & 7 \end{bmatrix}. \]

Matriisin voidaan ajatella koostuvan neliskanttisista alimatriiseista eli lohkoista, joissa on jokin määrä peräkkäisiä rivejä ja sarakkeita.

Annetaan seuraavaksi esimerkki \(4 \times 4\) -matriisista, joka koostetaan useasta lohkosta.

Vasempaan ylälaitaan asetetaan lohkoksi \(3 \times 3\) -matriisi \(L\), jossa on alkiot \(l_{i,j}\) indekseillä \(i=1,2,3\) ja \(j=1,2,3\). Oikeaan ylälaitaan asetetaan lohkoksi \(3 \times 1\) -matriisi \(A\), jossa on alkiot \(a_1\), \(a_2\) ja \(a_3\). Vasemmassa alalaidassa on lohkona \(1 \times 3\) -nollamatriisi, ja oikeassa alalaidassa \(1 \times 1\) -matriisi, jonka ainoa alkio on \(1\):

\[ \begin{bmatrix} L & A \\ \mathbf 0 & 1 \end{bmatrix} = \begin{bmatrix} \begin{bmatrix} l_{1,1} & l_{1,2} & l_{1,3} \\ l_{2,1} & l_{2,2} & l_{2,3} \\ l_{3,1} & l_{3,2} & l_{3,3} \end{bmatrix} & \begin{bmatrix} a_1 \\ a_2 \\ a_3 \end{bmatrix} \\ \begin{bmatrix} 0 & 0 & 0 \end{bmatrix} & \begin{bmatrix} 1 \end{bmatrix} \end{bmatrix} = \begin{bmatrix} l_{1,1} & l_{1,2} & l_{1,3} & a_{1} \\ l_{2,1} & l_{2,2} & l_{2,3} & a_{2} \\ l_{3,1} & l_{3,2} & l_{3,3} & a_{3} \\ 0 & 0 & 0 & 1 \end{bmatrix}. \]

Tällaiseen matriisiin on kiva vaikka lisäksi piirtää vaaka-ja pystyviivat erottamaan toisistaan lohkoja: \[ \left[ \begin{array}{ccc|c} l_{1,1} & l_{1,2} & l_{1,3} & a_{1} \\ l_{2,1} & l_{2,2} & l_{2,3} & a_{2} \\ l_{3,1} & l_{3,2} & l_{3,3} & a_{3} \\ \hline 0 & 0 & 0 & 1 \end{array} \right]. \]

Matriisiin voidaan ajatella jokin lohkorakenne, jos siihen on hyvä syy ilmiössä, jota mallinnetaan.

Tässä viimeisimmäksi nähty esimerkki tulee vastaan tietokonegrafiikan ensimmäisten perusteiden joukossa.

Ohjelmoidessa laskentakirjasto mahdollistaa yleensä matriisien käsittelyn myös alimatriiseittain ja lohkoittain.

Matriisit ohjelmointikielissä

Matriisit grafiikassa

Tällä kurssilla tehdään MIT Open CourseWaren grafiikkakurssin harjoituksia, joiden mallikoodissa on annettu valmiina vecmath -niminen kirjasto, joka tarjoaa valmiina kaikki yksinkertaisessa grafiikassa tarvittavat tyypit ja laskutoimitukset C++:lla toteutettuina.

Samat operaatiot löytyvät hyvin samanlaisina myös varjostinkielistä, joilla tehdään suuri osa esimerkiksi tietokonepelien grafiikasta.

Esimerkkikoodien ja -kirjaston oppiminen antaa siis vaivihkaa myös osaamisen modernien grafiikka-alustojen käyttöön.

Tärkeää on osata laskea pienet matriisit myös käsin.

Sillä tavoin syntyy todellinen tuntuma siihen, millaisia matriiseja mihinkin kohtaan on hyvä käyttää.

Käsin laskemalla ja ymmärtämällä saa keinot esimerkiksi selviytyä tilanteista, joissa esimerkiksi jonkin kirjaston tai työkalun matriisit ovatkin transpooseja suhteessa johonkin toiseen kirjastoon, joka saattaa olla aiemmasta elämästä tuttu.

Matriisit muissa kuin grafiikkasovelluksissa

Tietokonegrafiikassa valtaosa matriiseista on aika pieniä ja keskenään pääosin samanmuotoisia, joten grafiikkaan käytetään spesifejä pienten matriisien kirjastoja tai alustoja.

Ei kuitenkaan kannata ajatella asiaa niin suppeasti kuin pelkästään tämän kurssin esimerkit antavat ymmärtää.

Esimerkiksi tieteellisessä laskennassa suosittu työkalu Matlab ja vastaava avoimen lähdekoodin työkalu Octave käsittelevät ensisijaisena tyyppinään matriiseja.

Lohkojen ja alimatriisien käsittely on näissä kielissä erityisen luontevaa.

Tieteellisessä laskennassa käytetään suurten matriisien laskemiseen vakiintuneita rajapintoja, kuten BLAS ja LAPACK, joita voidaan käyttää melkein missä tahansa kielessä.

Pidemmälle mentäessä myös tietokonegrafiikassa tulee vastaan tarpeita suurten matriisien käyttöön.

Data-analyysissä, koneoppimisessa, virtaus- ja lujuuslaskennassa ja lukemattoman monessa muussa sovelluksessa on tyypillistä kasata matriisi, jossa ovat ilmiöön liittyvät todelliset tai hypoteettiset mittausarvot sopivissa alkioissa.

Ilmiöön liittyvä kysymys ratkaistaan usein teknisesti laskemalla käänteismatriisi tai etsimällä matriisikaava, jossa on mukana diagonaalimatriisi.

Nämä menettelyt läpäisevät koko laskennan kentän, joten toki myös tietokonegrafiikan perusteissa nähdään sovelluksia näistä.

Valmiina löytyvät kirjastot tekevät yleensä kaikki laskutoimitukset.

Tehtäväsi on siis ymmärtää mallinnettava ongelma ja se, kuinka, miksi ja millaisia matriiseja ja matriisilaskuja kannattaisi käyttää ongelman ratkaisemiseksi.

Siihen puuhaan lähdetään tässä prujussa seuraavaksi!

Peruskäsitteet: vektori, piste, suunta, kehys

Vektoriavaruus ja kanta

Lienee selvää, että tietokonegrafiikassa malinnetaan tietokoneella ainakin seuraavia asioita:

  • kolmiulotteisen maailman sijainnit, suunnat ja siirtymät suhteessa toisiinsa
  • fotonien eli valoa kuljettavien kvanttien heijastuminen ja taittuminen kolmiulotteisessa maailmassa
  • ihmisen aistijärjestelmän vastaanottamat visuaaliset ärsykkeet.

Luonnontieteen kandidaatin opinnoissa asia tehdään luonnontieteellisen menetelmän kautta eli matemaattisen mallintamisen avulla.

Tämä on loppujen lopuksi läheisesti sama menettely kuin se, mitä ohjelmien suunnittelussa tehdään.

Ohjelmoidessa on hyödyllistä tutustua konkreettisiin esimerkkeihin olioista, joita kehitettävällä luokalla halutaan mallintaa.

Esimerkiksi Jyväskylän yliopiston Ohjelmointi 2 -kurssilla käytetään hyvän syyn vuoksi aikaa jäsenrekisteriin liittyvien konkreettisten Aku Ankka -esimerkkien luomiseen ennen kuin aletaan tehdä ohjelmaa jäsenrekisterin hoitoon.

Jo Ohjelmointi 1 -kurssin luentomateriaalissa (vuoden 2019 versiossa) muistutetaan, että laivanupotuspeliä on vaikea ohjelmoida tietokoneelle tuntematta pelin sääntöjä ja yksityiskohtia, jotka selviävät pelaamalla peliä ensin.

Samalla tavoin matematiikassa on hyödyllistä tutustua konkreettisiin esimerkkeihin olioista, joita kehitettävällä määritelmällä halutaan mallintaa.

Sieltä etsitään ominaisuudet, joita konkreettisilla esimerkkiolioilla on, ja menetelmät eli metodit, joilla niitä on (tai olisi) tarpeen käsitellä.

Sekä ohjelmoinnissa että matematiikassa pyritään yksinkertaisuuteen eli tärkeimpien, määrittelevien ominaisuuksien kuvaamiseen.

Tätä sanotaan abstrahoinniksi, ja se on ajattelultaan samankaltaista matematiikassa ja ohjelmoinnissa.

Yleiskäyttöisen eli abstraktin mallin yksityiskohdat voidaan tarkentaa sitten siinä kohtaa, kun malli jalkautetaan käyttöön jonkin konkreettisen asian mallintamiseksi.

Ohjelmoija voi ajatella analogiaa koodiin, jossa abstraktista luokasta peritään konkreettinen luokka tai jopa siihen hetkeen, kun luokkamääritys instantoituu olioksi, joka tekee tietyssä ohjelmassa tietyn tehtävän tietokonelaitteiston käskysarjana.

Toisaalta hyödyllinen abstrakti matemaattinen malli löydetään vasta pohtimalla, ehkä matemaatikkosukupolvien ajan, joitakin konkreettisia esimerkkejä, joihin mallin halutaan purevan.

Lineaarialgebran osalta perustyö on tehty, eikä avoimia kysymyksiä perusteissa enää juurikaan ole.

Seuraavaksi käydään läpi ajattelu konkreettisesta esimerkistä abstraktiin malliin ja sieltä takaisin hyötykäyttöön konkreettisten, grafiikassa mallinnettavien, olioiden parissa.

Mitä vektoriavaruus mallintaa

Millaisten olioiden luokkaa matemaattinen vektoriavaruuden määritelmä pyrkii mallintamaan?

Nimen "vektori" tausta kertoo jo jotakin

Wikipedia ja sanakirjat näyttäisivät kertovan, että 1800-luvulta alkaen käytössä olleen sanan "vektori" taustalla on latinan verbi vehere, joka merkitsee kantamista.

Latinankielinen taivutusmuoto vector tarkoittaa "kantaja".

Tyypilliset matematiikan oppikirjat valitsevat ensimmäiseksi esimerkiksi kahden pisteen eli sijainnin välisen suoraviivaisen siirtymän.

Oppikirjat yleensä sisältävät myös kuvan, jossa on kaksi pistettä ja niitä yhdistävä suora, suunnattu nuoli, josta sanotaan, että se suora nuoli kuvaa sellaista vektoria eli "asian paikasta toiseen kantajaa", jota halutaan ryhtyä mallintamaan.

Ole tarkkana olioiden tyypeistä: lähtökohtaisesti, ainakaan vielä tässä ajattelun vaiheessa, piste ei ole vektori.

Piste on konkreettinen sijaintipaikka esimerkiksi paperilla tai jalkapallokentällä.

Mallinnettavana asiana on kahden pisteen välinen suoraviivainen siirtymä.

Opettaja piirsi näitä nuolia paperille kevään 2019 grafiikkakurssin luennolla 4.

Tavoite oli rohkaista sinua piirtämään vastaavia kuvia itse, omin käsin, jotta pisteen, siirtymän ja lineaarialgebran vektorin yhteys olisi lopulta helpompi sisäistää.

Siirtymien yhdistäminen ja skaalaus

Jo piirretyt nuolet ovat malli, koska eihän nuoli ole todellisessa maailmassa tapahtuva siirtymä.

Nuoli on malli todellisessa maailmassa tapahtuvalle siirtymälle.

Siirtymä kuvitellaan kahden pisteen välille ja visualisoidaan nuolena, että kuvitelma on helpompi pitää mielessä, kun sen ominaisuuksia tutkitaan.

Analogia tälle ajatukselle löytyy esimerkiksi René Magritten maalauksesta "La trahison de images" (linkki Wikipediaan).

Nuolilla halutaan mallintaa siirtymiä seuraavasti:

  • Nuolella on silminnähden suunta ja pituus tai siirtymän voimakkuus.

    Näyttää paperille piirreltynä ja kolmessa ulottuvuudessakin kuviteltuna vääjäämättömältä totuudelta, että kaikkien mahdollisten arkisen maailman pisteparien välille voidaan kuvitella viivasuoraa reittiä pitkin kulkeva siirtymä, jolla on nämä kaksi ominaisuutta.

  • Näyttää vääjäämättömältä myös, että jokaista siirtymää kohden on olemassa myös vastakkaiseen suuntaan tapahtuva käänteinen siirtymä takaisin päin.

  • Halutaan, että siirtymiä voidaan yhdistää eli summata niin, että kun ensimmäisen nuolen kärjestä piirretään uusi siirtymä, voidaan katsoa, että lähtöpisteestä yhdistetyn siirtymän päätepisteeseen muodostuu uusi, suoraviivainen siirtymä, joka voidaan piirtää samanlaisena nuolena.

    Yhdistetty siirtymä paikasta A paikkaan B ja sieltä vielä paikkaan C halutaan tulkita siten, että se onkin sama kokonaissiirtymä kuin suoraviivainen siirtymä suoraan paikasta A paikkaan C.

    Filosofisesti ajatellen: päätepisteessä halutaan unohtaa mahdollisesti käänteitä sisältänyt matkareitti ja sen mahdolliset vaikutukset matkantekijään.

    Ollaan kiinnostuneita siirtymien kokonaisvaikutuksesta sijaintiin, ei siirtyjään itseensä.

    Voisi sanoa, että siirtymän ominaisuutena ei ole muistia matkan osavaiheista.

    Näin mallintaen suora matka päätepisteeseen on siis kaikilta vaikutuksiltaan sama kuin samaan pisteeseen päätyvä matka kahden tai useamman suoraviivaisen välietapin kautta.

    Mallinnetaan siis erityisesti siirtymiä lähtöpisteestä päätepisteeseen. Loppujen lopuksi jää ajateltavaksi edelleen vain yksittäisiä suoraviivaisia siirtymiä kahden pisteen välillä.

    Eihän yhdellä suoralla nuolella voi kuvata muunlaisia kuin yksittäisiä suoraviivaisia siirtymiä.

    Matemaatikon sanoin summaus on näin määriteltynä suljettu operaatio kaikkien mahdollisten suunnattujen nuolten joukossa.

    Ohjelmoija voi ajatella, että summauksen tulos on saman tyyppinen eli saman luokan olio kuin summauksen operandit.

  • Halutaan, että siirtymiä voidaan skaalata eli kertoa perinteisillä luvuilla:

    Esimerkiksi halutaan, että voidaan mallintaa siirtymä samaan suuntaan, mutta puolet jonkin siirtymän alkuperäisestä pituudesta, ja voidaan jälleen piirtää nuolena tämä skaalattu siirtymä.

  • Halutaan, että myös "ei siirtymää" on yhdenlainen siirtymä. Sanotaan sitä vaikka "nollasiirtymäksi".

    Mihin tahansa siirtymään kun summataan nollasiirtymä, niin halutaan tuloksen olevan alkuperäinen siirtymä ilman muutoksia.

    Nollasiirtymä on kummallinen otus, koska sillä ei voi katsoa olevan suuntaa.

    Kuitenkin sellainen otus tarvitaan, että mitkä tahansa kaksi siirtymää voidaan varmasti summata niin, että tuloskin on siirtymä.

    Muutenhan siirtymän ja vastakkaissiirtymän summa eli "ei siirryttykään loppujen lopuksi" ei olisi itsessään enää siirtymä, eikä summa olisi suljettu operaatio siirtymien joukossa.

  • Halutaan, että perinteisellä luvulla \(1\) skaalatessa siirtymä pysyy samana. Silloin on enemmän järkeä myös puolikkaissa ja kaksinkertaisissa siirtymissä!

Eli halutaan määritellä summa ja skalaarikertolasku, joiden tuloksena on edelleen samanlainen olio, joka vastaa hyödyllistä arkihavaintoa: suoraviivaista siirtymää paikasta toiseen, joka on lopputulos mahdollisesti useista vaihtelevan suuntaisista ja pituisista suoraviivaisista siirtymistä.

Arkihavaintoja vektorien ominaisuuksista

Sitten, kun tutkitaan tällaisia nuolia ja niille sovittua summaa ja skaalausta, niin niillä huomataan olevan seuraavat ominaisuudet:

  • Siirtymien summauksen järjestyksellä ei ole väliä:

    Kun siirrytään vaikkapa jalkapallokentän kulmasta ensin kentän pituuden verran yhtä laitaa pitkin ja sitten leveyden verran toista laitaa pitkin, niin päädytään samaan kulmaan kuin valitsemalla ensin siirtyä leveyden verran ja sitten pituuden verran toista kautta.

    Summaksi tulee sama suoraviivainen yhteissiirtymä viistosti jalkapallokentän nurmen yli.

  • Silläkään ei ole väliä, yhdistetäänkö monen siirtymän yhdistelmästä jotakin suoraviivaisempia "oikotiesiirtymiä" jossain järjestyksessä. Eli seuraavista siirtymistä muodostuu loppujen lopuksi sama suoraviivainen kokonaissiirtymä Kortepohja \(\rightarrow\) Väinönkatu:

    • Kortepohja \(\rightarrow\) Agora \(\rightarrow\) Opinkivi \(\rightarrow\) Väinönkatu

    • Kortepohja \(\rightarrow\) Opinkivi \(\rightarrow\) Väinönkatu

    • Kortepohja \(\rightarrow\) Agora \(\rightarrow\) Väinönkatu.

    Tehtiinpä nämä miten päin vaan, niin lopullinen siirtymä on:

    • Kortepohja \(\rightarrow\) Väinönkatu.
  • Kun siirtymää skaalataan ensin jollain luvulla ja tuloksena tullutta siirtymää taas uudella luvulla, niin tuloksena on sama siirtymä kuin jos ensin olisi kerrottu luvut keskenään tavallisella lukujen kertolaskulla ja sitten skaalattu vain kerran.

    Piirrä uskoaksesi.

    Näin ne nuolet eli konkreettisten reaalimaailman siirtymien mallit nyt vaan näyttävät toimivan.

  • Kun kaksi siirtymää skaalataan samalla luvulla ja summataan, niin siitä tulee sama siirtymä kuin jos olisi ensin summattu siirtymät ja sitten skaalattu lopputulos.

  • Jos siirtymä skaalataan joidenkin lukujen summalla, niin kokonaissiirtymä on sama kuin jos olisi yhdistetty peräkkäin summan termeillä skaalatut siirtymät.

Arkihavainnosta kaavoiksi

Prujun alussa oleva vektoriavaruuden määritelmä kuvailee matematiikan kielellä suoraviivaisista siirtymistä äsken tehdyt havainnot.

Matematiikassa on tärkeää määritellä vain olennainen aksioomiksi.

Lineaarialgebrassa on todettu, että täsmälleen edellä kuvatut ominaisuudet riittävät siirtymien mallintamiseen.

Niistä voidaan johtaa lauseina mukavia laskusääntöjä, kuten että vastakkainen siirtymä saadaan kertomalla skalaarilla \(-1\) ja nollasiirtymä kertomalla skalaarilla \(0\).

Vaikka nämäkin olisi voitu tehdä arkihavaintoina nuolista, niitä ei tarvitse erikseen sopia määritelmässä, koska ne seuraavat matemaattisen logiikan kautta pienemmästä joukosta sopimuksia.

Matemaattinen määritelmä antaa mahdollisuuden käsitellä monia erilaisia asioita vektoreina, jos niillä voidaan nähdä olevan samat ominaisuudet kuin summattavilla ja skaalattavilla nuolilla.

Silloin ne aina käyttäytyvät samoin kuin paperiin piirretyt suorat nuolet.

Nuolten välisten laskutoimitusten piirtäminen silmiesi eteen auttaa siis ratkomaan vektorien laskutehtäviä, vaikka vektoreina mallinnettavat asiat itsessään olisivat vaikeampia piirtää.

Samalla tavoin olio-ohjelmoinnissa pyritään tekemään luokkia, jotka soveltuvat moneen erilaiseen käyttöön.

Esimerkiksi jonoa kuvaava luokka kuvaa jonottelevien alkioiden käyttäytymistä ottamatta juurikaan kantaa siihen, millaisia olioita jonossa on.

Olisi epäilyttävää kirjoittaa erikseen jonotukseen liittyvää koodia Asiakasjonolle, Parkkipaikkajonolle ja Tukkutilausjonolle.

Sen sijaan yleensä alustakirjastoista löytyy valmiina yleinen Jono, josta edellämainitut erityiset jonot saadaan aikaan määrittämällä tyyppi T, jonka jonotusta mallinnetaan.

Kantavektorit ja ulottuvuudet

Entä sitten ne pisteet tai sijainnit?

Eikö niitä voi mallintaa vektoreilla?

Vastaus näihinkin kysymyksiin on tulossa.

Ensimmäisenä kuitenkin kysytään yksi aika perustavanlaatuinen kysymys: miten tuollaisen nuolena piirretyn siirtymävektorin ominaisuutena silminnähdenkin oleva pituus tai suunta voitaisiin mitata tai kirjoittaa ylös?

Miten pitkä tämä tietty nuoli nyt on? Mihin suuntaan se oikeastaan osoittaa?

Vastaus liittyy siihen, että kaikki on suhteellista, ja pitää sopia, mihin suhteutetaan.

Minkä mittaisia siirtymät ovat

Täytyy valita mittakaava ja sopia jostakin "standardinuolesta", jonka pituus on sopimuksen mukaan tasan \(1\).

Kevään 2019 luentoesimerkissä opettaja askarteli ruutupaperista viivottimen, jolla voi mitata etäisyyksiä ruutupaperin ruudun leveyden mittaisilla yksiköillä.

Viivottimella oli mahdollista piirtää nuoli, jonka pituus on tasan yksi Jyväskylän yliopistossa käytetyn tenttipaperin ruudun leveys.

Mittakaavan valinta on mielivaltaista, mikä luennolla havainnollistui, kun mittayksikkö vaihdettiin esitysteknisistä syistä jossakin vaiheessa tuplasti pidempään kuin se, millä demonstraatio oli aloitettu.

Monesti on hyvä sopia mittayksiköksi metri eli se matka, jonka valo kulkee tyhjiössä \(1/299 792 458\) sekunnissa.

Samalla hetkellä, kun piirretään nuoli, jonka pituus sovitaan olemaan 1, kiinnittyy tietysti myös nuolen toinen ominaisuus eli suunta.

Tällainen tietty, sovittu, vektori on nimeltään kantavektori.

Se antaa mahdollisuuden tehdä täsmälleen tunnetun mittaisia skaalattuja siirtymiä tiettyyn, sopimuksen kautta tunnettuun, suuntaan.

Ennen kantanuolen piirtämistä ei voi puhua täsmällisesti suunnasta "oikealle", "alas" tai "yläviistoon", koska näilläkään ei ole merkitystä ilman lisäsopimuksia.

Arkihavainnossa meillä on yleensä konteksti, josta syntyy yhteisymmärrys, mikä on ylös tai alas.

Oikea ja vasen on hankalampaa: kasvotusten oltaessahan minun oikea on sinun vasen.

Ylös ja alas tuskin ovat kovin käyttökelpoisia nimiä avaruusaseman painottomassa tilassa työskenteleville.

Matematiikassa ja ohjelmoinnissa ei ole mitään määritelty, ennen kuin se määritellään.

Kantavektori määrää yhden suunnan vektoriavaruudessa.

Sen jälkeen voidaan puhua siirtymistä kantavektorin suuntaan niin pitkälle kuin kantavektorin kertominen reaaliluvulla meidät vie.

Luvulla 0 skaalatessa tuloksena on nollavektori ja negatiivisilla luvuilla skaalatessa vastakkaissuuntainen suhteessa kantavektoriin.

Kantavektorin skaalaaminen eri reaaliluvuilla antaa siis mahdollisuuden matkata suuntaan ja toiseen vektorin kiinnittämällä suoralla.

Suunta ja suhteellinen pituus kantavektorin skaalauksena on nyt selvää.

Vektoriavaruuden määritelmään ei kuitenkaan kuulu mitään "absoluuttista pituutta", vaan se riippuu mallintajan valitsemasta kantavektorista, jonka todellinen luonne ei ole mukana mallissa! Muistetaan René Magritten "piippu, joka ei ole piippu".

Ulottuvuudet

Yksi kantavektori mahdollistaa siirtymät vain yhteen (positiivisella skalaarilla kerrottuun) suuntaan tai täysin vastakkaiseen (negatiivisella skalaarilla kerrottuun) suuntaan.

Useammista suunnista tai ulottuvuuksista ja myös niihin päin ulottuvista pituuksista voidaan puhua vasta sitten, kun sovitaan jokin toinen kantavektori, joka ei ole täsmälleen saman- tai vastakkaissuuntainen ensimmäisen kanssa!

Luennolla piirrettiin esimerkkinä ensimmäistä kantavektoria vastaan kohtisuora vektori, jonka pituus oli myös tasan \(1\) viivottimen määräämä mittayksikkö.

Näin muodostui paperille kohtisuora eli ortogonaalinen kantavektoripari, jonka kumpikin vektori olivat valitun mittakaavan normaaliyksikön mittaisia eli pituudeltaan normaaleja.

Mikä tahansa siirtymä paperin pinnalla tuli nyt mahdolliseksi ilmoittaa summana kahdesta sopivasti skaalatusta siirtymästä, joista ensimmäinen on ensimmäisen ja toinen toisen kantavektorin suuntainen.

Sama menettely selvästi toimisi kolmannen ulottuvuuden lisäämiseksi sopimalla vaikkapa kolmas edellisten kanssa kohtisuora kantavektori niin, että se on suoraan ylöspäin paperin pinnasta ja yksikön mittainen.

Silloin kaikki 3-ulotteisen maailman siirtymät saataisiin skaalaamalla kukin 3 kantavektorista sopivalla skalaarilla ja summaamalla näin syntyneet 3 siirtymää toisiinsa.

Kanta

Vektorien järjestetty lista on nimeltään kanta silloin, kun siihen on valittu kantavektorit niin, että avaruuden kaikki vektorit saadaan joillakin skalaareilla skaalattuina ja summattuina yhdistelminä eli lineaarikombinaatioina kantavektoreista, eikä kannassa ole mukana yhtään tarpeetonta vektoria.

Kantavektorien tulee olla keskenään lineaarisesti riippumattomat, mikä on hieno nimi sille, että ei saa olla sellaista kantavektoria, joka saataisiin skaalattuna ja summattuna muista kantavektoreista.

Silloin uusi kantavektori ei voisi antaa uutta ulottuvuutta.

Kannassa on kantavektoreita saman verran kuin vektoriavaruudessa on ulottuvuuksia.

Se onkin täsmällinen määritelmä vektoriavaruuden ulottuvuuksien määrälle.

2-ulotteisen avaruuden kantaan täytyy tulla valituksi tasan 2 kantavektoria, 3-ulotteisen avaruuden kantaan 3, ja niin edelleen.

Vektorin komponenttiesitys

Otetaan käyttöön vektoriavaruuden matemaattinen määritelmä nyt, kun uskotaan, että nuolivektorit samaistuvat tämän luentomateriaalin alussa esiteltyihin kaavoihin.

Otetaan ja nimetään 3-ulotteisia siirtymiä kuvaava vektoriavaruus \(V_{\vec 3}\) ja sieltä kannaksi kelpaava kolmikko siirtymävektoreita \((\vec{b_1}, \vec{b_2}, \vec{b_3})\).

Kantavektoreille valituissa symboleissa pieni kirjain \(b\) viittaa kannan englanninkieliseen termiin "basis".

Alaindeksi viittaa kantavektorin järjestysnumeroon.

Symbolin päällä oleva nuoli viittaa siihen, että kyseessä on tässä esimerkissä vektori, jolla yhä mallinnetaan nuolia kuten edellä.

Lineaarialgebraa tuntevat matemaatikot ovat luvanneet meille, että mikä tahansa vektori voidaan esittää yksikäsitteisesti kantavektorien suuntaisten skaalattujen vektorien summana ihan niin kuin nuolilla piirreltiin paperille.

Mille tahansa 3-ulotteiselle siirtymälle \(\vec{a} \in V_{\vec 3}\) on siis olemassa tasan tarkkaan kolme tiettyä reaalilukua \(s_1\), \(s_2\) ja \(s_3\) niin, että

\[\vec{a} = s_1 \vec{b_1} + s_2 \vec{b_2} + s_3 \vec{b_3}.\]

Symboleissa pieni kirjain \(s\) viittaa skalaariin ja alaindeksi siihen nimenomaiseen kantavektoriin, jota kukin skalaarikomponentti skaalaa.

Kantavektorien suuntaiset komponenttivektorit eli komponentit ovat \(s_1 \vec{b_1}\), \(s_2 \vec{b_2}\) ja \(s_3 \vec{b_3}\).

Kantavektorien suuntaan tarvittavien siirtymien skalaareita \(s_1\), \(s_2\) ja \(s_3\) sanotaan siirtymän skalaarikomponenteiksi.

Yksikäsitteisyys on hieno asia, koska sen ansiosta ja kannan kiinnittämisen jälkeen voidaan huoletta samaistaa toisiinsa vektori \(\vec{a}\) ja sen komponenttiesitys suhteessa valittuun kantaan.

Mitä tämä tarkoittaa? Esimerkiksi tässä esimerkissä on turvallista puhua vektorista \(\vec a\) tarpeen mukaan yhtä hyvin skalaarikolmikkona \((s_1, s_2, s_3) \in \mathbb R^3\), kun tiedossa on kantavektorikolmikko \((\vec{b_1}, \vec{b_2}, \vec{b_3})\).

Yksikäsitteisyyden vuoksi kellään ei ole epäselvyyksiä siitä, että kolmikko \((s_1, s_2, s_3)\) kannassa \((\vec{b_1}, \vec{b_2}, \vec{b_3})\) mallintaa samaa asiaa kuin vektori \(\vec a\).

Tämän havainnon kautta tullaan yhdistämään matriisilaskennan käytäntö lineaarialgebran teoriaan erittäin hedelmällisesti muun muassa tietokonegrafiikan, mutta myös suurin piirtein kaiken muun laskentaan päin vivahtavan tietotekniikan kannalta.

Ennen sitä kuitenkin vielä ihan pari juttua.

Esimerkiksi ollaan toistaiseksi mallinnettu vasta paperille piirrettyjä siirtymiä, eikä sijainteja.

Jotta kuitenkin jännitys säilyisi, jonkinlaista tuntumaa saattaa saada laskemalla auki matriisikertolaskun \[ \begin{bmatrix} s_1 & s_2 & s_3 \end{bmatrix} \begin{bmatrix} \vec{b_1} \\ \vec{b_2} \\ \vec{b_3} \end{bmatrix}. \]

Enemmän kuin kolme ulottuvuutta

Matemaatikon on helppo lisätä neljäs suunta neljännen ulottuvuuden suuntaan ja antaa sille uusi symboli \(\vec{b_4}\).

Samoin on matemaattisesti helppo lisätä viides, kuudes ja niin edelleen ulottuvuus.

Esimerkiksi mikä tahansa 1000-ulotteisen maailman suoraviivainen siirtymä voidaan ilmaista skaalaamalla ja summaamalla 1000 kannaksi sopivaa suoraviivaista siirtymää.

Ohjelmoinnissakin lisäulottuvuuksien toteuttaminen on helppoa.

Tarvitsee vain tehdä skalaarikomponentit sisältävästä taulukko-oliosta isomman kokoinen.

Paperiin piirtäminen on vaikeata jo 3 ulottuvuuden tapauksessa ja vielä vaikeampaa 4 ulottuvuudelle.

Se ei kuitenkaan haittaa, koska vektorien tärkeät ominaisuudet ovat samat riippumatta ulottuvuuksien määrästä.

Nuolien ja 2- tai 3-ulotteisten havainnekuvien tai joskus jopa 1-ulotteisen "lukusuoran" piirtely antaa todella helposti vastauksia, jotka lineaarialgebran teorian kautta toimivat miljoonissa ulottuvuuksissa.

(Äärettömiin ulottuvuuksiin ei kajota tällä kurssilla.)

Pisteiden mallintaminen

Origo ja koordinaatisto

Harjoitus

Seuraavassa ohjataan sinut tekemään samalla pieni harjoitus omin käsin.

Mallia tähän suuntaan nähtiin jo kevään 2019 luennolla 4.

Piirrä paperille piste ja anna sille nimi origo.

Origoa voi symboloida pienellä \(\tilde o\)-kirjaimella, jossa on vaikka tilde eli mato yläpuolella.

Sanan "origo" alkuperä on latinan kielessä, ja se tarkoittaa alkupistettä, lähdettä, syntymää tai jotakin sellaista.

Jos sinulla ei ole viivotinta, jossa on mitta-asteikko, niin askartele sellainen, kuten luentoesimerkissä.

Piirrä sitten viivottimen avulla suora, 1 mittayksikön mittainen, nuolivektori niin, että se alkaa origosta ja suuntautuu jotakuinkin oikealle päin.

Anna tälle vektorille nimeksi \(\vec{i}\) eli i-kirjain, jonka päällä on nuoli.

Piirrä toinen suora, 1 mittayksikön mittainen, nuolivektori niin, että sekin alkaa origosta mutta suuntautuu ylöspäin, mahdollisimman kohtisuorassa ensiksi piirtämääsi nuolta kohden.

Anna tälle vektorille nimeksi \(\vec{j}\) eli j-kirjain, jonka päällä on nuoli.

Tehtävän tehtyäsi näet paperilla edessäsi karteesisen koordinaatiston, johon on kiinnitetty 2-ulotteisen euklidisen avaruuden kantavektorit.

Pisteen mallintaminen koordinaatistossa

Edelliset luvut omaksuttuasi voit nyt havaita, että siirtymä origosta mihin tahansa pisteeseen paperilla on summa viivottimella mitatuilla skalaareilla kerrotuista kantavektoreista.

Sama pätee teoriassa myös pisteille paperin ulkopuolella maailmankaikkeuden ääriin asti siinä 2-ulotteisessa tasossa eli 3-ulotteisen avaruuden aliavaruudessa, jonka piirtämäsi karteesinen koordinaatisto määrittää.

Tiedät myös, että komponenttiesitys on yksikäsitteinen.

Seuraa tärkeä löydös: mikä tahansa 2-ulotteisen avaruuden piste voidaan hyvin mallintaa skalaarikomponenteilla \((x,y) \in \mathbb R^2\), koska siirtymä origosta sinne on yksikäsitteisesti \(x \vec{i} + y \vec{j}\).

Pisteen skalaarikomponentteja sanotaan sen koordinaateiksi valitussa koordinaatistossa.

Tämä todellisen maailman mallinnus ei onnistuisi pelkillä paikkaan ankkuroimattomilla siirtymävektoreilla, jotka eivät ota kantaa sijaintiin.

Täytyi siis kannan \((\vec{i}, \vec{j})\) lisäksi kiinnittää origo!

Koordinaatiston ominaisuuksia

Koordinaatisto on olio, jonka ominaisuutena on avaruudesta mielivaltaisesti valittu keskipiste sekä ulottuvuuksien mukainen määrä suuntia.

Koska ominaisuutena on suuntien lisäksi origon sijaintipaikka, se on spesifimpi malli kuin vektoriavaruus.

Pidä huolta tyypeistä: Piste ei edelleenkään ole vektori, mutta koska sinne päästään tunnetulla siirtymällä origosta lähtien, niin se voidaan mallintaa koordinaateilla.

Koordinaatiston kautta pisteille määrittyy yksikäsitteinen koordinaattiesitys.

Viivottimella voit edelleen piirtää pidemmät kantavektoreidesi suuntaiset suorat, jotka jatkuvat molempiin suuntiin origosta.

Näitä periaatteessa maailman ääriin asti jatkuvia suoria sanotaan koordinaattiakseleiksi.

Niihin voi viivottimella mitaten merkitä pienillä poikkiviivoilla positiivisten ja negatiivisten skalaarien arvoja, joilla komponentit pitää skaalata, että tunnistetaan vaikkapa tasan kokonaislukujen mittaiset siirtymät origosta akseleiden suuntaan.

Voit myös hahmotella koordinaattiakselien suuntaista ruudukkoa, josta pisteiden koordinaatteja on helppo määrittää silmäilemällä.

Koulumatematiikassa ja -fysiikassa on luultavasti käytetty tällaista koordinaatistoa pisteiden ja funktion kuvaajien piirtelyyn.

Tietokonegrafiikan algoritmeja miettiessä auttaa paljon piirtää paperiin koordinaatisto.

Kaksi samasta paikasta alkavaa suurin piirtein saman pituista nuolta riittää.

Sellaiset raapustaa noin sekunnissa.

Sen jälkeen näkee silmillään edessään aivan riittävän tarkasti origon ja koordinaatiston, johon voi ryhtyä piirtämään pisteitä, viivoja, kaaria, ympyröitä, kolmioita, kameroita, valonlähteitä ja muuta, mihin liittyviä graafisia kysymyksiä milloinkin halutaan ratkoa.

Olet siis kehittämässä tärkeää ydintaitoa, ja harjoitusta on hyvä jatkaa:

Piirrä pari pistettä ja määritä niille koordinaatit.

x-, y- ja z-akselit

2-ulotteisessa karteesisessa koordinaatistossa on tyypillistä sanoa ensimmäisen kantavektorin määräävää suuntavektoria nimellä \(\vec{i}\) ja sen suuntaista akselia \(x\)-akseliksi.

Toisen kantavektorin symbolina on usein \(\vec{j}\) ja sen suuntaista akselia sanotaan \(y\)-akseliksi.

Mielessäsi voit ajatella kolmannen kohtisuoran vektorin, joka tököttää kohtisuoraan ylöspäin paperistasi.

Ajatustyön helpottamiseksi voit väliaikaisesti laittaa origoon kynän tai hammastikun pystyyn kolmannen kohtisuoran suunnan merkiksi.

Yksikön mittainen, pystyssä tököttävä suunta, on tyypilliseltä nimeltään \(\vec{k}\) ja sen suuntainen akseli on \(z\)-akseli.

Kolmella kantavektorilla saat määritettyä minkä tahansa maailmankaikkeuden pisteen mittayksikkösi mukaisilla koordinaateilla.

Meillä on siis arkihavaintoa ja koulumatematiikkaa vastaavassa 3-ulotteisessa avaruudessa \(x\)-, \(y\)- ja \(z\)-akselit, joiden suuntaisia koordinaatteja sanotaan vastaavasti x-, y- ja z-koordinaateiksi. Aika tyypillistä on myös kirjoittaa ne symbolein \((x,y,z) \in \mathbb R^3\).

Jälleen kerran, ole tarkkana tyypeistä: \((x,y,z) \in \mathbb R^3\) teknisesti ottaen tarkoittaa kolmikkoa \(\mathbb R\):n alkioista ilman muita sopimuksia lukujen merkityksestä minkään kannalta.

Se, että kyseessä on malli kolmiulotteiselle maailmalle, vaatii lisätietoa kontekstista.

Tavallista on, että asia ilmoitetaan tyyliin "\((x,y,z)\) on 3D-maailman piste" tai "\((x,y,z)\) on 3-ulotteisen euklidisen avaruuden piste".

Vasta silloin tiedetään, että on olemassa kanta, origo ja karteesinen koordinaatisto, johon \((x,y,z)\) antaa koordinaatit.

3-ulotteisessa koordinaatistossa on mielekästä puhua jonkun tietyn koordinaattiakselin suuntaan tai sen ympäri tapahtuvista asioista.

Silloin tarkoitetaan valittujen kantavektoreiden suuntaisia asioita.

Nyt, kun kynä on pystyssä \(z\)-akselin merkiksi, kokeile pyörittää paperia z-akselin ympäri vastapäivään.

Tätä samaa harjoiteltiin kevään 2019 ensimmäisellä luennolla, ja pian sitä tehdään matriisilaskennan keinoin.

Pian, pian, malttia vielä pieni hetki...

Tässä vaiheessa ota huomioon, että kun paperi pyörii \(z\)-akselin ympäri, niin voidaan havaita ainakin seuraavaa:

  • Kantavektorit \(\vec i\) ja \(\vec j\) pyörivät.
  • \(x\) ja \(y\) -akseli pyörivät.
  • \(z\) -akseli ei pyöri.
  • Origo ei pyöri.
  • Paperiin piirretyt pisteet pyörivät.
  • Paperiin piirrettyjen pisteiden koordinaatit eivät muutu.
  • Miksi eivät muutu? Koska koordinaatisto pyörii.
  • Nenänpääsi koordinaatit muuttuvat, koska se ei sijaitse pöydällä pyörivän koordinaatiston origossa eikä (välttämättä?) \(z\)-akselin suunnassa!
  • Jos taas asetat nenänpääsi \(z\)-akselille, sen koordinaatit lakkaavat muuttumasta!

Näillä ajatuksilla on aika hyvä lähteä miettimään 3-ulotteisten kappaleiden keskinäisten liikkeiden mallintamista.

Haaste tulee olemaan hallita, mikä pyörii, mikä ei, mikä muuttuu, mikä ei. Ja miksi.

Onneksi olet nyt harjoitellut koordinaatiston piirtämistä jo ainakin kerran.

Avaruuden rakenteesta ja koordinaatistoista

Aiemmassa harjoituksessa sanottiin, että piirsit paperiin "karteesisen koordinaatiston ja euklidisen avaruuden kantavektorit".

Sen jälkeen teitkin sitten harjoitusta 2- ja lopulta 3-ulotteisessa euklidisessa avaruudessa.

Niiden vektorit voidaan samaistaa \(\mathbb R^2\):n ja \(\mathbb R^3\):n kanssa ja puhua ylipäätään koordinaattivektoreista.

Tätä toteamusta on syytä vähän avata, koska tietokonegrafiikassa on kyse muotojen ja sijaintien mallintamisesta.

Aiheen taustat johtavat vähäksi aikaa filosofian historian hämäriin, jos päivittäin käytössä olevien termien nimityksiä ei halua jättää sanahelinäksi.

Karteesinen koordinaatisto on se, jossa akselit ovat kohtisuorassa toisiaan vastaan ja kaikki kantavektorit ovat pituudeltaan 1 yksikkö.

Se on saanut nimensä René Descartes'ltä, joka 1600-luvulla yhdisti algebrallisen lähestymistavan euklidisen avaruuden geometrian tutkimiseen.

Antiikin kreikkalainen filosofi Eukleides Aleksandrialainen kirjoitti yli 2000 vuotta sitten aina 1700-luvulle asti oppikirjakäytössä säilyneen perusteoksen, jonka nimi oli osuvasti Alkeet.

Teoksessa tutkitaan geometriaa eli todellisista olioista koostuvan maailman rakennetta aksiomaattisella tavalla, joka on jäänyt matematiikan ja loogisen päättelyn perusmenettelyksi siitä asti.

Eukleideen rakennelman pohjalta on vuosisatojen ajan mallinnettu menestyksekkäästi todellisen maailman esineisiin liittyviä fysikaalisia ja teknologisia ilmiöitä.

Suoraviivainen ja suorakulmainen malli ei planetaarisen mittakaavan ulkopuolella ajan ja avaruuden kaareutumisen vuoksi toimi ilman Albert Einsteinin suhteellisen äskettäin esittämiä korjauksia.

Vähemmän kosmisissa mittakaavoissa ja tietokonegrafiikassa euklidinen avaruus toimii kuitenkin työkaluna täysin suvereenisti.

Euklidinen avaruus mallintaa kolmiulotteisten siirtymien ja sijaintien lisäksi myös suuntien välisiä kulmia, minkä vuoksi tietokonegrafiikassa ammennetaan paljon hyödyllisiä laskukaavoja sen pohjalta.

Niin paljon hyödyllisiä laskukaavoja sieltä löytyy, että ne kannattaa käsitellä omana asianaan eri luvussa jäljempänä.

Muunlaisia koordinaatistoja

Tällä kurssilla huomataan pian, että suoraviivaistenkaan koordinaatistojen ei tarvitse olla suorakulmaisia, eikä suuntavektorien saman mittaisia.

Voit ihan hyvin hahmotella paperille vinokulmaisia koordinaatistoja.

Kaarevia koordinaattiakseleita ei kuitenkaan tulla näkemään.

Todellisessa maailmassahan käyräviivaisia koordinaattijärjestelmiä on käytössä paljon, esimerkiksi paikkojen ilmaiseminen leveys- ja pituuspiireillä.

Mitä tahansa pituuspiiriä pitkin kulkemalla joutuu aina Pohjois- ja Etelänavalle vuorotellen, vaikka toinen koordinaateista ei koskaan vaihdu.

Euklidisessa avaruudessa koordinaattiakselin suuntaisilla siirtymillä ei päästä koskaan takaisin mihinkään samaan pisteeseen, eivätkä samansuuntaiset eri linjoja kulkevat kulkijat kohtaa koskaan.

Molemmat esimerkit ovat kuitenkin vain erilaisia tapoja ilmaista todellisen maailman sijainteja mitattujen lukujen avulla.

Todellinen maailma itse ja sen avaruuden rakenne pysynee samanlaisena riippumatta koordinaatistosta, jonka mallintaja valitsee.

Todelliset pisteet, suunnat, pituudet, nopeudet ja kiihtyvyydet ovat samoja olioita, vaikka niiden esittämiseen käytettäisiin millaista tahansa koordinaatistoa.

Niitä kuvaavat kaavat voivat kuitenkin olla yksinkertaisempia joissain koordinaatistoissa kuin toisista.

Se johtuu siitä, että jotkut ilmiöt ja rakenteet ovat luonteeltaan esimerkiksi pallomaisia, kuten Maapallon pinta tai sylinterimäisiä kuten telat paperikoneen linjastolla.

Niissä voidaan saada yksinkertaisempi tai tehokkaampi malli käyttämällä esimerkiksi pallo- tai sylinterikoordinaatteja.

Luonnollisesti tietokonegrafiikan tekeminen myös käyräviivaisiin koordinaatistoihin on joskus tarpeen, ja vekkuleilla avaruuden rakenteilla voidaan mallintaa vekkuleita asioita.

Tietokonegrafiikassa monet mallinnettavat ilmiöt etenkin perustilanteissa ovat suoraviivaisia, joten suoraviivainen koordinaatisto ja euklidinen avaruus ovat niihin erittäin hyvä malli.

Vektorien ja pisteiden yhteyksiä

Vasta-alkio ja vektorien erotus

Sovitaan tässä pari juttua, jotka lineaarialgebran opiskelijat löytävät tarkemmalla loogisella päättelyllä opintojensa alkutaipaleella.

Otetaan \(v,w \in V\) reaalikertoimisesta vektoriavaruudesta \(V\) siten, että \(v+w=0\) eli että \(w\) on \(v\):n "vasta-alkio".

Uskotaan matemaatikoita, että tällainen \(w\) on yksikäsitteinen ja \(w = (-1)v\).

Siksi uskalletaan määritellä merkintä \(-v := (-1)v\) ja sanoa että \(-v\) on vektorin \(v\) vastavektori.

Sitä kautta sovitaan vektorien \(u,v \in V\) miinuslasku eli erotus, \(u-v := u + (-v)\), että päästään käyttämään alakoulusta tutun vähennyslaskun näköistä operaattoria.

Uskotaan sekin, että reaalikertoimisiksi vektoreiksi todetuilla alkioilla voidaan tehdä näillä plus-, miinus- ja skalaarikertolaskuilla hyvin samanlaista algebraa eli "kaavojen pyörittelyä" ja yhtälöratkaisua kuin koulussa opittiin tekemään reaalilukujen plus-, miinus- ja kertolaskulla.

Symbolit suunnille ja sijainneille

Seuraavaksi täsmennetään merkintätavat 1-, 2-, tai 3-ulotteisen maailman suuntavektorille ja pisteelle.

Symbolin päälle merkitty nuoli tarkoittaa jatkossa, että symbolilla kuvataan "nuolivektoria" eli siirtymää, suuntaa, nopeutta tai muuta suuretta, jolla on ainoastaan suunta ja pituus, mutta ei muita ominaisuuksia, kuten sijaintipaikkaa.

Esimerkki: "Tässä dokumentissa kirjoitettuna symboli \(\vec a\) on nimi vektorille, jonka ominaisuutena ei ole tiettyä sijaintia maailmassa, vaan ainoastaan suunta ja pituus. Muutoin dokumentissa on virhe, josta sen kirjoittaja haluaa tulla tietoiseksi mahdollisimman pian."

Symbolin päälle merkitty tilde eli "matomerkki" tarkoittaa, että symbolilla kuvataan pistettä eli sijaintia avaruudessa.

Esimerkki: "Tässä dokumentissa kirjoitettu symboli \(\tilde p\) on nimi jollekin sijainnille maailmassa eli 3-ulotteisen avaruuden pisteelle".

Piste- ja suuntalaskujen yhdistäminen

Uskotaan pohdinnat siirtymistä pisteiden välillä, ja sovitaan merkinnät vektorien ja pisteiden välillä laskemiseksi:

Kirjoitetaan summana \(\tilde p + \vec a = \tilde q\) se, että \(\vec a\) on siirtymä pisteestä \(\tilde p\) pisteeseen \(\tilde q\).

Kirjoitetaan erotuksena \(\tilde q - \vec a = \tilde q + (- \vec a) = \tilde p\) sama asia toiseen suuntaan kuljettuna.

Kirjoitetaan erotuksena \(\tilde q - \tilde p = \vec a\) edelleen sama asia.

Nuolilla tehdyt piirrokset ja Eukleideen ajoilta periytyvä käsitys maailman suoraviivaisista siirtymistä tukevat näiden laskutoimitusten tekemistä.

Euklidisessa avaruudessa \(\mathbb R^n\) pisteet samaistuvat täysin koordinaateittaisiin siirtymiin origosta kuhunkin pisteeseen. Sen laskutoimituksissa edellämainitut kaavat eivät olisi tarpeen.

Vaikka laskenta tullaan ohjelmointikielessä tekemään käytännössä samanlaisilla olioilla, tietokonegrafiikassa on tilanteita, joissa on hyötyä ajatella tarkempaa tulkintaa vektorin ja pisteen välillä.

Niinpä nämä tietyt pisteitä ja vektoreita yhdistävät laskutoimitukset piti tässä nyt määritellä erikseen, että saadaan sovittua yhteensopivista tyypeistä ja merkityksistä.

Tarkkana:

  • Pisteen ja siirtymän summa on piste.

    Mielekäs tulkinta on siirtyminen pisteestä toisaalle vektorin "mukana".

  • Pisteen ja pisteen erotus on siirtymä.

    Mielekäs tulkinta on yksilöidä, mikä siirtymä vie ensimmäisen operandin mukaiseen pisteeseen toisen operandin mukaisesta pisteestä.

    Vaikka määritelmässä ei ole koordinaatistoa, sen operandit ovat tietysti järjestyksessä, joka on yhteensopiva euklidisen avaruudenkin kanssa; järjestyksen muistelemiseksi voi siis piirtää tavallisen koordinaatistokuvan ja katsoa, kumminko päin nuolen piti tulla.

  • Pisteen ja pisteen summaa ei edelleenkään määritelty.

    Järkevää tulkintaa ei löydy arkihavainnoista eikä mallinnuksen tarpeista.

  • Pisteelle ei edelleenkään ole määritelty skalaarikertolaskua.

    Järkevää tulkintaa ei löydy.

Näissä määritelmissä ei käytetty koordinaatteja, ja ainoa näissä vilahtanut skalaari oli \(-1\).

Näitä ei siis voi eikä pidä yrittää ajatella laskuina, joissa koordinaatteja käytettäisiin tai tarvittaisiin.

Paikalliset koordinaatistot

Kertaus on opintojen äiti.

Kertaus on tarpeen.

Tee siis jälleen harjoitus kynällä ja paperilla:

Mallinnuskoordinaatisto

Piirrä nopeasti, mutta "riittävän" siististi kaksi suurin piirtein kohtisuoraa nuolta lähtemään jostakin sijainnista paperin pinnassa.

Eli tee jotakuinkin "tasasivuinen ja suorakulmainen L-kirjain, jossa on nuolenkärjet".

Esimerkiksi mittakaavalla ei ole väliä, vaan idealla, että sellainen tuli kiinnitettyä, kun piirsit nuolet.

Aiemman harjoituksen sisäistettyäsi ymmärrät jo, että määritit tietyn keskipisteen eli origon ja piirsit euklidisen avaruuden kantavektorit, joista muodostuu karteesinen koordinaatisto 2-ulotteisen maailman pisteiden sijaintien ja niiden välisten suuntien esittämiseksi reaaliluvuista muodostuvina koordinaattivektoreina mallia \((x,y) \in \mathbb R^2\).

Tätä ymmärrystä on hyvä tukea mietiskelemällä hetki tätä itse piirtämääsi koordinaatistoa.

Pyri hahmottamaan "sielusi silmillä" kuvitteelliset \(x\)- ja \(y\)-koordinaattiakselit ja vaikkapa niiden määrittämä ruudukkokin.

Hae vahva ymmärrys siitä, että nuolten kärjissä ovat kooordinaatit \((1,0)\) ja \((0,1)\).

Harjoituksen seuraavaa vaihetta varten: nimeä kantavektorisi symboleilla \(\vec{b}_1\) ja \(\vec b_2\) ja origo nimellä \(\tilde o\).

Antamissasi nimissä on tarkoitus muistaa b-kirjaimesta, alaindekseistä ja kirjaimen päälle piirretyistä pikkunuolista, että kyseessä on kaksi kantavektoria eli englanniksi "basis vectors".

Nimestä \(\tilde o\) on tarkoitus muistaa, että kyseessä on origo eli englanniksi "origin".

Tilde o-kirjaimen päällä kuvastaa sitä, että origo on tyypiltään erilainen olio (eli piste) kuin suunnat (jotka ovat vektoreita).

Viimeistele harjoituksen ensimmäinen vaihe piirtämällä jokin kolmio eli kolme pistettä, joiden kaikkien välillä on suorat viivanpätkät.

Nyt voit havaita, että kolmion kärkipisteet voidaan mallintaa yksikäsitteisesti koordinaattiesityksinä kiinnittämässäsi koordinaatistossa.

Tämä harjoitus, kuten suuri osa grafiikassa vastaan tulevista ongelmanratkaisuista, on helpompaa tehdä 2 ulottuvuudessa.

On hyvä kuitenkin muistuttaa itselleen, että piirroksesi määrittää itse asiassa myös 3-ulotteisen karteesisen koordinaatiston, jossa on kolmas kantavektori kohtisuoraan paperin pinnasta ylöspäin.

3-ulotteisen karteesisen koordinaatiston kolmas kantavektori kun on määritelmän mukaan välttämättä kohtisuorassa kahta jo määriteltyä vastaan.

Piirtämäsi kolmio on siis yhtä hyvin 3-ulotteisen maailman kolmio kuin 2-ulotteisen.

Se vain sijaitsee xy-tasolla eli 3-ulotteisen koordinaattivektoriavaruuden 2-ulotteisella hypertasolla, jossa kaikkien pisteiden \(z\)-koordinaatti on \(0\).

Hypertaso on aliavaruus, jossa on 1 ulottuvuus vähemmän kuin siinä avaruudessa, joka sisältää sen.

Arkihavainnon mukainen taso on siis euklidisen 3-ulotteisen avaruuden hypertaso.

Tämä 3-ulotteinen maailma taas on 4-ulotteisen euklidisen avaruuden hypertaso ja niin edelleen.

Mitä harjoituksessa tapahtui tietokonegrafiikan termein?

Määritit mallinnuskoordinaatiston, jonka mukaisilla koordinaattivektoreilla pystytään täsmällisesti mallintamaan kolmio tai sitä kautta mikä tahansa esimerkiksi OpenGL-rajapinnan avulla piirrettävissä oleva todellisen maailman muoto suhteessa origoon ja sitä kautta muihin kolmioihin, joita mallissa voi olla hyvinkin monta.

Jo Assignment 0:ssa havaitsit, että OBJ-tiedostossa on tallennettuna kolmioiden kärkipisteet riveinä, joissa jokaisessa on kolme liukulukua.

Rivit ovat mallinnusohjelmistosta ulos tallennettu esitystapa mallinnetun esineen sijaintien koordinaattiesityksille eli niiden koordinaattivektoreille mallin tekijän käyttämässä mallinnuskoordinaatistossa.

Mallinnuskoordinaatistossa on jokin origo ja yleensä karteesinen koordinaatisto.

Malli muodostetaan niin, että sen pisteet on aseteltu jotenkin sopivasti suhteessa origoon ja standardivektoreihin \((1,0,0)\), \((0,1,0)\), \((0,0,1)\).

Esimerkiksi 218-senttistä koripallon pelaajaa kuvaavassa mallissa voitaisiin asettaa pelaajan jalkapohjat \(xy\)-tasolle eli niin, että jalkapohjien \(z\)-koordinaatti on \(0\).

Tällöin suorassa seisovan pelaajan päälaki voitaisiin mallintaa \(z\)-koordinaattiin \((0,0,2.18)\).

Tällaisen pelaajamallin pisteiden sijainnit ja etäisyydet vastaisivat todellisessa maailmassa tehtyjä mittauksia, jos mittakaavaksi muistetaan valita \(1\) metri.

Silloin olisi selkeätä mallintaa samaa mittakaavaa käyttäen koripallon sääntöjen mukainen kenttä, jonka leveys olisi kansainvälisissä peleissä 15 ja pituus 28.

Samoin olisi selkeätä mallintaa korin yläreunan \(z\)-koordinaatti useimpien koripallosääntöjen mukaisesti reaalilukuarvoon \(3.05\).

Mallin ei tietenkään välttämättä tarvitse seisoa \(xy\)-tasolla.

Toinen mielekäs vaihtoehto origon sijainnille voisi mahdollisesti olla mallintaa pelaaja niin, että mallinuskoordinaatiston origo sattuu massakeskipisteen kohdalle eli jotakuinkin lannerangan kolmannen nikaman runko-osan etupuolelle, navan taakse (lähde)

Jos mallintaja haluaisi, että pelaaja seisoo \(xz-tasolla\) niin, että päälaki tulee \(y\)-akselin suuntaan, niin sehän olisi häneltä aivan järkevä valinta myös.

Erikoisemmat vaihtoehdot vaatisivat perusteluja, joita tämän kirjoittaja ei juuri nyt keksi.

Mittakaava ja origo on kuitenkin mielivaltainen sopimuskysymys, joka tehdään aina tilanteen mukaan.

Tarkoitettu mittakaava on syytä mainita mallin dokumentaatiossa, koska koordinaateissa tätä tietoa ei ole.

Sekin täytyy muistaa, että osa maailman ihmisistä haluaa mallintaa pituuksia jalkoina ja tuumina.

Jos jalkayksiköillä mallinnetun pelaajan koordinaattivektoreita käytetään vahingossa metriyksiköillä mallinnetun kentän koordinaattien kanssa, niin kyllä kentälle tulee silloin todellinen jättiläinen, jota sinne ei välttämättä haluttu!

Linkki lähteeseen on vanhentunut. http://tule-liikunta.fi/wp-content/uploads/TULE-ABC-biomekaniikan-perusteet-UKKi.pdf

02 Mar 22 (edited 02 Mar 22)

Useat paikalliset koordinaatistot

Harjoitus jatkuu.

Väliotsikko saattaa jo kertoa, mitä seuraavaksi tehdään, ja mihin sen on tarkoitus johtaa.

Arvasit ehkä oikein.

Seuraava tehtäväsi on piirtää samaan paperiin toinen, erilainen koordinaatisto.

Valitse jokin uusi piste origoksi ja kiinnitä kaksi kantavektoria, jotka ovat selvästi eri suuntaisia kuin edelliset.

Voit käyttää luovuutta: koordinaatistohan voi olla myös vinokulmainen, ja kantavektorit voivat olla keskenään eri pituiset, eikä minkään kantavektorin pituuden ole pakko olla täsmälleen jonkin standardin mittatikun mittainen.

Koordinaatisto on nimittäin ihan hyvä koordinaatisto, vaikka se ei olisi karteesinen.

Anna uudelle origolle symboliksi \(\tilde p\) ja kantavektoreille nimiksi \(\vec a_1\) ja \(\vec a_2\).

Symbolien valintaperuste on, että ne ovat aakkosissa viereisiä aiemmin nimeämiesi olioiden kanssa.

2-ulotteiset koordinaatistot voidaan ajatella kolmikkona, joka sisältä kantavektorit ja origon.

Sinulla on nyt nimettynä ja visualisoituna koordinaatistot \((\vec b_1, \vec b_2, \tilde o)\) ja \((\vec a_1, \vec a_2, \tilde p)\)

Nyt tulee tämän asian pihvi. (Voi olla hyvin myös vegepihvi.)

Koordinaattivektorin ja koordinaatiston suhde

Asian pihvi liittyy siihen, että kaikki on suhteellista.

Hahmottele koordinaatistoon \((\vec b_1, \vec b_2, \tilde o)\) piirtämäsi kolmio koordinaatistoon \((\vec a_1, \vec a_2, \tilde p)\) niin, että kärkipisteiden koordinaattivektorit pysyvät samana.

Toisin sanoen jos kärkipiste oli \((x,y)\) eli siirtymän \(x \vec b_1 + y \vec b_2\) päässä origosta \(\tilde o\) ollut piste, niin tee uusi kärkipiste, joka on siirtymän \((x \vec a_1 + y \vec a_2)\) päässä origosta \(\tilde p\).

Karkea hahmotelukin auttaa saamaan käsityksen tarkasteltavasta kysymyksestä, mutta käytä toki viivotinta ja mittaa, jos se auttaa harjoitteluvaihetta.

Tehdään havaintoja:

  • Samat koordinaatit \((x,y)\) kuvaavat eri pisteitä eri koordinaatistossa.

  • Kärkipisteiden koordinaattivektorien määrittämä kolmio pysyy koordinaatiston vaihtuessa kolmiona, eli suorat pysyvät suorina.

  • Jos teit luovia ratkaisuja toisen koordinaatiston piirrossa, kolmion muoto on kuitenkin voinut muuttua venymällä tai litistymällä tai muuttumalla peilikuvakseen, riippuen käyttämäsi luovuuden määrästä.

Koordinaatisto suhteessa toiseen koordinaatistoon

Piirros on nyt valmis, mutta ajattelu sen parissa jatkuu.

Tehdään havainto:

Siirtymä alkuperäisen koordinaatiston origosta \(\tilde o\) uuden koordinaatiston origoon \(\tilde p\) voidaan ilmoittaa skaalaamalla ja summaamalla kantavektorit \(\vec b_1\) ja \(\vec b_2\) sopivasti.

Samoin uuden koordinaatiston ensimmäinen kantavektori \(\vec a_1\) saadaan skaalaamalla ja summaamalla kantavektorit \(\vec b_1\) ja \(\vec b_2\) sopivasti.

Edelleen myös uuden koordinaatiston toinen kantavektori \(\vec a_2\) saadaan skaalaamalla ja summaamalla kantavektorit \(\vec b_1\) ja \(\vec b_2\) sopivasti.

Näkeminen on uskomista. Onneksi piirsit asiasta kuvan!

Viivottimen avulla voisit myös hahmotella jollakin tarkkuudella kertoimet, joilla skaalaukset tulee tehdä.

Tietokonegrafiikassa haluamme sijoitella useita, omassa mallinnuskoordinaatistossaan koordinaattivektoreina mallinnettuja kohteita hallitusti ja tarkoituksenmukaisesti yhteiseen virtuaalimaailmaan, josta otetaan kuvia virtuaalisella kameralla.

Virtuaalimaailma ajatellaan jollain tapaa kiinnitettyyn maailmankoordinaatistoon.

Virtuaalikamera ottaa kuvan suhteessa omaan kamerakoordinaatistoonsa.

Tietokonegrafiikassa on elintärkeää pysyä kärryillä koordinaatistomuutoksista, jotta mallinnettavat kohteet eivät sijoitu näkymissä miten sattuu.

Idean jatkaminen rekursiivisesti

Ei tarvitse piirtää sitä (vielä), mutta tehdään vähintään ajatusleikki:

Voisit piirtää paperiin kolmannen koordinaatiston ja neljännen ja niin edelleen.

Voisit selvästikin määrittää kolmannen koordinaatiston origon ja kantavektorit suhteessa toiseen koordinaatistoon.

Koska saat toisen koordinaatiston suhteessa ensimmäiseen, niin ilmeisesti syntyy joku kerto- ja pluslaskuun perustuva reitti myös siihen, miten ilmaistaisiin kolmas koordinaatisto suhteessa ensimmäiseen.

Useimmiten koordinaatisto halutaan liittää nimenomaan suhteessa johonkin toiseen koordinaatistoon, jonka mukana se kulkee.

Esimerkiksi oma käsivartesi kulkee olkanivelen mukana, kyynärvarsi kulkee käsivarren mukana, käsi kulkee käsivarren mukana, sormet kulkevat käden mukana, sormien nivelet sormien mukana, ...

Löytyy luonnostaan hierarkkisia malleja, joissa mallin osasella on välitön "vanhempi", jonka mukana se kulkee.

Näistä osista ja niiden koordinaatistoista muodostuu puumainen rakenne, jonka nimi tietokonegrafiikassa on näkymägraafi.

Asiaan perehdytään kurssin puolivälin paikkeilta alkaen.

Tämän harjoituksen tavoite oli...?

Tietokonegrafiikassa voidaan haluta näkymiä, joissa on satoja tai tuhansia eri koordinaatistoja jossain hallitussa suhteessa toisiinsa.

Peruskurssilla etsitään keinoja selviytyä tästä haasteesta.

Tämän pienoisoppaan kirjoittajan mielestä yksi tärkeimmistä keinoista on sellainen, jonka jo edellisen harjoituksen jälkeen osaat:

Osaat hahmotella koordinaatistoja, pisteitä ja suuntavektoreja paperille, mikä helpottaa aivojasi miettimään kysymyksiä, joita koordinaatistojen suhteesta toisiinsa tarvitsee pohtia (usein ja hartaasti).

Samalla muista edelleen pysyä tarkkana mallinnettavien olioiden tyypeistä:

Vektori ei ole piste.

Kumpikaan niistä ei ole myöskään koordinaattivektori, vaikka sopivilla koordinaattivektoreilla voidaan yksikäsitteisesti kuvata kaikki maailman vektorit ja pisteet suhteessa tiettyyn koordinaatistoon.

Kehys

Sovitaan muutama sana, joita tullaan käyttämään koordinaatistojen hallinnan yhteydessä.

Sanotaan, että 3-ulotteisen maailman kehys on nelikko \((\vec b_1, \vec b_2, \vec b_3, \tilde o)\), missä \((\vec b_1, \vec b_2, \vec b_3\)) on kanta 3-ulotteisten suuntavektorien joukossa ja \(\tilde o\) on 3-ulotteinen piste.

Sana on suora suomennos MIT OCW:n kalvosarjassa käytetystä termistä "frame", ja sillä on yhteyksiä vastaaviin yleisessä käytössä oleviin käsitteisiin.

Kehys kiinnittää origon ja kanta kiinnittää suunnat ja "peruspituudet" eri ulottuvuuksien suuntaan.

Se siis määrittää paikallisen koordinaatiston.

Kehys tulee olemaan perustyökalu, jonka avulla otamme tietokonegrafiikassa tarvittavat koordinaattimuunnokset haltuun.

Sen nimi on enne siitä, että sopivanlainen kehys voidaan ajatella Frenet'n kehyksenä, jota käytetään niin tällä kurssilla kuin oikeissa sovelluksissa mallina avaruudessa toistensa suhteen liikkuvien paikallisten koordinaatistojen suhteen.

Paperille piirtäessä tai 2D-grafiikkaa tehdessä tarvitaan vastaavaa määritelmää 2-ulotteisen maailman kehykselle. Se olisi kolmikko \((\vec b_1, \vec b_2, \tilde o)\), missä \((\vec b_1, \vec b_2)\) on kanta 2-ulotteisten suuntavektorien joukossa ja \(\tilde o\) on 2-ulotteinen piste.

Vaikka 1-ulotteinen määritelmä olisi mahdollinen, sitä ei ehkä tarvita käytännössä eikä edes harjoituksen vuoksi.

Vektorit, matriisit ja lineaarikuvaukset

Luodaan yhteys matriisien ja vektorien välille.

Yksi tulkinta on, että edellämainittujen esitietojen sisäistämisen jälkeen tämä luku muodostaa "tietokonegrafiikan perusteet".

Tulkinnan mukaan loput tietokonegrafiikasta on sitten näiden asioiden soveltamista.

Tästä eteenpäin materiaali on olennaisesti Massachusett's Institute of Technologyn opettajien tuotantoa, ja se on (hieman laajempana) julkaistu MIT Open CourseWare -alustalla syksyllä 2012 (linkki alkuperäiseen).

Samalla tarttuu lisenssi:

Osuudet tästä eteenpäin on lisensoitu Creative Commons -lisenssillä BY-NC-SA, eli lisenssin mukainen käyttö rajoittuu akateemiseen tai muuhun ei-kaupalliseen käyttöön ja siitä tehdyt muokatut versiot tulee jakaa eteenpäin samalla lisenssillä.

Alkuperäisen ovat tehneet Wojciech Matusik ja Frédo Durand vuonna 2012. Suomentanut ja Jyväskylän yliopiston kurssikäyttöön kustomoinut Paavo Nieminen vuodesta 2019 alkaen.

Tuunataan matematiikka

Kertaus edellisestä: 3D-avaruuden piste \(\tilde p\) samaistuu valitussa kehyksessä \((\vec b_1, \vec b_2, \vec b_3, \tilde o)\) johonkin siirtymävektoriin \(\vec v\), jolle voi laskea \(\tilde p = \tilde o + \vec v\).

Kaikilla vektoreilla ja sitä kautta pisteillä on myös kantaan \((\vec b_1, \vec b_2, \vec b_3)\) kiinnitetty koordinaattiesitys \((x,y,z) \in \mathbb R^3\), jolle \(\vec v = x \vec b_1 + y \vec b_2 + z \vec b_3\) ja \(\tilde p = \tilde o + \vec v = \tilde o + x \vec b_1 + y \vec b_2 + z \vec b_3\).

Tämä kaikki on yksikäsitteistä, ja sen takia pisteille voitaisiin antaa lupa laskea koordinaattiesityksillä aivan samoja laskuja kuin vektoreilla.

Kuitenkin nyt mallinnetaan maailmaa, jossa ilmeisesti piste ei ole samanlainen olio kuin siirtymä.

Vaikka voitaisiin tehdä mitä vain laskuja, niin halutaan käytännössä tehdä vain sellaisia, joilla on mielekäs tulkinta.

Esimerkiksi Kuokkalan, Kortepohjan ja Mattilanniemen sijaintien summa ei välttämättä ole mielekäs, mutta sen sijaan niiden väliin jäävä kolmion muotoinen alue tai sen maantieteellinen keskipiste on!

Lähdetään katsomaan, millaisia mielekkäitä tulkintoja ja kaavoja grafiikassa käytellään.

Se hoidetaan matriisilaskennalla, jonka olet onneksi harjoitellut jo täysin kuntoon tähän kohtaan mennessä!

Pysty ja vaakavektorit, koordinaatit matriisina

Otetaan 3D-suuntavektorien joukosta jokin \(\vec v\), jota vastaa koordinaattikolmikko \((x,y,z) \in \mathbb R^3\) kannan \(\vec b_1, \vec b_2, \vec b_3\) suhteen niin, että \(\vec v = x \vec b_1 + y \vec b_2 + z \vec b_3\)

Koordinaatteja voidaan sanoa koordinaattivektoriksi ja se voidaan samaistaa pystyvektoriin eli \(3 \times 1\) -matriisiin, jonka riveillä koordinaatit ovat:

\[ \mathbf c = \begin{bmatrix} x \\ y \\ z \end{bmatrix} \]

Pystyvektorin symboliksi on tässä valittu lihavoitu c-kirjain eli \(\bf c\).   Kirjain viittaa englannin sanaan "coordinates" tai "coordinate vector".   Lihavointi on tyypillinen tapa ilmoittaa, että symboli kuvaa oliota, jonka tyyppi on pystyvektori eli yhden sarakkeen muodostama matriisi.   Kynällä tai liitutaululla lihavoinnin voi merkitä tuplaamalla jonkin pystyviivan sopivasti.   TIM-järjestelmä osaa näköjään piirtää esimerkin vain isoille kirjaimille: \(\mathbb{A, B, C, D, G, X}\). Samalla idealla pystyy kuitenkin lihavoimaan kynällä myös pienet kirjaimet, joita tällä kurssilla tarvitsee lihavoida, eli esimerkiksi \(\mathbf a, \mathbf b, \mathbf c, \mathbf f\).

Pystyvektori voidaan transponoida, kuten mikä tahansa matriisi, ja silloin saadaan samat alkiot sisältävä vaakavektori:

\[ \mathbf c^T = \begin{bmatrix} x & y & z \end{bmatrix} \]

On tärkeää muistaa, että oletuksena koordinaattivektorin symboli kuvaa aina pystyvektoria.

Sen vuoksi kirjoitetaan koordinaattilistan perään transpoosi, jos ei haluta käyttää palstamillimetrejä pystyvektorin kirjoittamiseen:

\[ \mathbf c = \begin{bmatrix} x & y & z \end{bmatrix}^T \]

Jos käytettävissä ei ole kynää tai muita välineitä matemaattisen tekstin latomiseen, niin yläindeksi merkitään sirkumfleksillä eli "hattumerkillä":

  Esimerkiksi sähköpostissa tai lähdekoodin kommentissa voisi lukea (0,0,1)^T 
  tai [0 0 1]^T kohdassa, jossa tarkoitetaan pystyvektoreiksi kirjoitettuja
  koordinaatteja.

  Jos yläindeksi ^T puuttuu, niin kirjoittaja ei ole ehkä ollut aivan tarkka.
  Pystyvektori on yhteisön oletus, joten koordinaatteja vaakaan kirjoittaessa
  ei passaa jättää transponointia merkkaamatta!

Muistetaan, että kolmen alkion matriisi \(\mathbf c\) on eri tyyppinen olio kuin kolmikko \((x,y,z)\).

Sen ominaisuutena on alkioiden lisäksi myös rivien ja sarakkeiden määräämä muoto.

Myös transpoosi \(\mathbf c ^T\) on eri tyyppinen kuin \(\mathbf c\) tai \((x,y,z)\), vaikka kaikki niistä mallintavat samaa todellisen tai kuvitellun maailman pistettä tai suuntaa.

Sopivalla tavalla rivejä ja sarakkeita vaihtelemalla saadaan aikaan lyhyitä merkintätapoja asioille, joiden laskemisesta ollaan kiinnostuneita.

Esimerkiksi, jos \(\mathbf a\) ja \(\mathbf b\) ovat pystyvektoreina esitetyt karteesisen koordinaatiston koordinaatit kahdesta 3D-maailman suunnasta, niin \(\sqrt{\mathbf a ^T \mathbf a}\) ja \(\sqrt{\mathbf b ^T \mathbf b}\) ovat vektorien pituudet, \(\mathbf a ^T \mathbf b\) on mittari suuntien väliselle kulmalle, yhtälö \(\mathbf a ^T \mathbf b = 0\) kuvaa tilannetta, jossa vektorit ovat keskenään kohtisuorat ja yhtälö \(\mathbf a^T \mathbf a < 4\) kertoo, pysyykö koordinaattien kuvaama siirtymä origosta sellaisen pallon sisällä, jonka keskipiste on origossa ja säde \(2\).

Kaikki toimii samoin useammissa ulottuvuuksissa kuin 2 tai 3.

Sekä peruskurssin jälkeen vastaan tulevassa grafiikassa että muissa jännittävissä tietokonesovelluksissa käytetään paljon pystyvektoreina ajateltuja koordinaatteja tuhansissa tai miljoonissa ulottuvuuksissa.

Esimerkiksi 48000-alkioinen pystyvektori \(\mathbf w = [w_1, w_2, \ldots, w_{48000}]^T\) voisi mallintaa \(1\) sekunnin mittaista digitaalista ääninäytettä \(48\) kilohertsin näytteenottotaajuudella.

Silloin laskun \(\mathbf w ^ T \mathbf w\) tuloksena olevaa reaalilukua sanottaisiin näytesignaalin energiaksi, ja se olisi yksi vertailukelpoinen mittari näytteessä olevan äänen voimakkuudelle.

Kannan esitys pystyvektorina

Myös kantoja ja kehyksiä on näppärää kirjoittaa matriiseiksi laskutoimituksia varten.   Jos vektorikolmikko \((\vec b_1, \vec b_2, \vec b_3)\) on 3D-avaruuden kanta, niin merkitään \(\vec{\mathbf{b}} = {\begin{bmatrix} \vec b_1 & \vec b_2 & \vec b_3 \end{bmatrix}}^T\) eli \[ \vec{\mathbf{b}} = \begin{bmatrix} \vec b_1 \\ \vec b_2 \\ \vec b_3 \end{bmatrix}. \]

Symbolissa b-kirjain viittaa edelleen kantaan eli "base".   Nuoli viittaa edelleen perustyyppiin eli siirtymävektoreihin.   Lihavoitu kirjasin kertoo, että kyseessä on pystyvektoriksi kirjoitettuja alkioita.

Nyt voidaan mallintaa vektori \(\vec v\) matriisilaskuna

\[ \vec v = \mathbf c^T \vec{\mathbf b}= \begin{bmatrix} x & y & z \end{bmatrix} \begin{bmatrix} \vec b_1 \\ \vec b_2 \\ \vec b_3 \end{bmatrix} = x \vec b_1 + y \vec b_2 + z \vec b_3, \]

missä \(\vec v\) on ilmoitettu koordinaateilla \(\mathbf c\) kannassa \(\vec{\mathbf b}\).

Kehys pystyvektorina, suunta ja piste lisäkoordinaatilla

Sovitaan merkintätapoja

Kirjoitetaan kehys \((\vec b_1, \vec b_2, \vec b_3, \tilde o)\) pystyvektoriksi \(\vec{\mathbf f}\) seuraavasti:

\[ \vec{\mathbf f} = \begin{bmatrix} \vec b_1 \\ \vec b_2 \\ \vec b_3 \\ \tilde o \end{bmatrix}. \]

Sovitaan, että kuvataan 3D-kehykseen kiinnitettyjä pisteitä ja suuntia \(4 \times 1\) -pystymatriiseilla \([x\ y\ z\ w]^T\), joissa merkitään suuntiin koordinaatti \(w=0\) ja pisteisiin \(w=1\).

Näin otetaan käyttöön Möbiuksen 1800-luvulla kehittelemä rakenne nimeltä homogeeninen koordinaatisto.

Aiheeseen ja muihin \(w\):n arvoihin kuin \(0\) tai \(1\) palataan myöhemmin.

Tässä vaiheessa otetaan viritelmästä käyttöön vasta elämää helpottavat matriisilaskut, joissa aina \(w=0\) tai \(w=1\).

Esimerkki pisteen \(\tilde p\) koordinaateista kehyksessä \(\vec{\mathbf f}\) pystyvektorina:

\[ \mathbf p = \begin{bmatrix} x \\ y \\ z \\ 1 \end{bmatrix}. \]

Esimerkki suunan \(\vec v\) koordinaateista kehyksessä \(\vec{\mathbf f}\) pystyvektorina: \[ \mathbf v = \begin{bmatrix} x' \\ y' \\ z' \\ 0 \end{bmatrix}. \]

Ohjelmoijana voit hetkellisesti ajatella koordinaattia \(w\) bittinä, jonka asento \(1\) tai \(0\) määrittää, onko 4-alkioinen reaalilukutaulu tyypiltään piste vai suunta.

Ohjelmoidessa käytetään liukulukuja, jolloin \(0\) ja \(1\) lakkaavat yleensä muutaman laskutoimituksen jälkeen olemasta täysin tarkkoja.

Tämä pitää ottaa huomioon, jos yritetään selvittää \(w\)-koordinaatin perusteella, onko tulos suunta tai piste.

Laskeminen

Jotta asiat tulevat määritellyiksi, ja niillä laskeminen on järkevää, tehdään joitakin lisämääritelmiä.

Sovitaan, että piste voidaan kertoa luvulla \(1\) niin, että se on identiteettioperaatio:

\[ 1 \tilde p = \tilde p 1 = \tilde p,\] kun \(\tilde p\) on piste (eli sijainti avaruudessa).

Sovitaan, että piste voidaan kertoa luvulla \(0\) niin, että tuloksena on nollavektori:

\[ 0 \tilde p = \tilde p 0 = \vec 0,\]

jolloin piste ei vaikuta laskun tulokseen, mutta pysyy yhteensopivana suuntien summalaskussa.

Näillä sopimuksilla saadaan helppo ja toimiva matriisikaava 2D ja 3D-maailman kehysten käsittelemiseen.

Jos meillä on kehys \(\vec{\mathbf f}\), ja sen suhteen annettu koordinaattiesitys \(\mathbf v\) suunnalle \(\vec v\) ja koordinaattiesitys \(\mathbf p\) pisteelle \(\tilde p\), niin yhteys mallinnettuihin vektoreihin ja pisteisiin saadaan matriisilaskulla:

\[ \vec v = \mathbf v^T \vec{\mathbf f} = \begin{bmatrix} x & y & z & 0 \end{bmatrix} \begin{bmatrix} \vec b_1 \\ \vec b_2 \\ \vec b_3 \\ \tilde o \end{bmatrix} = x \vec b_1 + y \vec b_2 + z \vec b_3 \]

ja

\[ \tilde p = \mathbf p^T \vec{\mathbf f} = \begin{bmatrix} x' & y' & z' & 1 \end{bmatrix} \begin{bmatrix} \vec b_1 \\ \vec b_2 \\ \vec b_3 \\ \tilde o \end{bmatrix} = x' \vec b_1 + y' \vec b_2 + z' \vec b_3 + \tilde o. \]

Huomataan, että tyypit pysyvät järkevinä kaikissa laskuissa, kun tehtiin edeltävät sopimukset pisteen kertomisesta.

Vektorin kaavassa ei ole missään vaiheessa vaikutusta kannan sijaintipaikalla eli origolla \(\tilde o\).

Tulos pysyy vektorina kaikissa vaiheissa.

Pisteen kaavassa taas kulkee mukana tieto kannan origosta.

Tulos pysyy pisteenä kaikissa vaiheissa.

Laskeminen koordinaattivektoreilla

Tutkitaan, ovatko matriisien plus- ja miinuslaskut mielekkäitä vektorien ja pisteiden koordinaattiesityksille.

Olkoon meillä pisteet \(\mathbf p = [p_x\ p_y\ p_z\ 1]^T\) ja \(\mathbf q = [q_x\ q_y\ q_z\ 1]^T\) sekä suunnat \(\mathbf u = [u_x\ u_y\ u_z\ 0]^T\) ja \(\mathbf v = [v_x\ v_y\ v_z\ 0]^T\) annettu koordinaatteina jonkin kehyksen suhteen.

Huomataan, että tyypit pysyvät mielekkäinä, kun tehdään aiemminkin mielekkääksi nähtyjä laskuja pisteiden ja vektorien välillä.

Suunnat pysyy suuntina summatessa (koordinaatti \(w=0\)):

\[ \begin{bmatrix} u_x \\ u_y \\ u_z \\ 0 \end{bmatrix} + a \begin{bmatrix} v_x \\ v_y \\ v_z \\ 0 \end{bmatrix} = \begin{bmatrix} u_x + a v_x \\ u_y + a v_y \\ u_z + a v_z \\ 0 \end{bmatrix} \]

Pisteeseen voi lisätä suunnan, niin tulos on siirtynyt piste (koordinaatti \(w=1\)):

\[ \begin{bmatrix} p_x \\ p_y \\ p_z \\ 1 \end{bmatrix} + a \begin{bmatrix} v_x \\ v_y \\ v_z \\ 0 \end{bmatrix} = \begin{bmatrix} p_x + a v_x \\ p_y + a v_y \\ p_z + a v_z \\ 1 \end{bmatrix} \]

Kahden pisteen erotus on niiden välinen matka suuntana (koordinaatti \(w=0\)):

\[ \begin{bmatrix} q_x \\ q_y \\ q_z \\ 1 \end{bmatrix} + (-1) \begin{bmatrix} p_x \\ p_y \\ p_z \\ 1 \end{bmatrix} = \begin{bmatrix} q_x - p_x \\ q_y - p_y \\ q_z - p_z \\ 1 - 1 \end{bmatrix} = \begin{bmatrix} q_x - p_x \\ q_y - p_y \\ q_z - p_z \\ 0 \end{bmatrix} \]

Pisteitä ei saa noin vain summata, koska esimerkiksi kahden pisteen summassa olisi \(w=2\), eikä sellaisesta ole sovittu mitään.

Myöskään pisteiden skaalaaminen muulla kuin \(1\):llä tai \(0\):lla ei anna vastausta tähän asti sovitun puitteissa.

Ennakoivasti voidaan kuitenkin huomata, että sopivilla painokertoimilla saadaan pisteiden painotettu keskiarvo pysymään pisteenä:

\[ (1-t) \begin{bmatrix} p_x \\ p_y \\ p_z \\ 1 \end{bmatrix} + t \begin{bmatrix} q_x \\ q_y \\ q_z \\ 1 \end{bmatrix} = \begin{bmatrix} (1-t)p_x + t q_x \\ (1-t)p_y + t q_y \\ (1-t)p_z + t q_z \\ 1 - t + t \end{bmatrix} = \begin{bmatrix} (1-t)p_x + t q_x \\ (1-t)p_y + t q_y \\ (1-t)p_z + t q_z \\ 1 \end{bmatrix} \]

Tämä voidaan tulkita sijainniksi pisteitä \(\tilde p\) ja \(\tilde q\) yhdistävällä suoralla, esimerkiksi niiden puoliväliksi silloin, kun \(t=\frac{1}{2}\).

Edelleen tehtiin lasku, jossa viimeinen koordinaatti selviytyi laskutoimitusten välivaiheiden jälkeen tasan tiukan tulkinnan mukaisena lukuna 1.

Tyypeistä ja neljännen koordinaatin sisällöstä on syytä olla kärryillä!

Yleensä ohjelmoidessa käytetään nimittäin sekä suunnille että pisteille samaa tietorakennetta (esimerkiksi "Vector4f" tällä kurssilla tai "vec4" GLSL-kielessä), jossa on vain koordinaatit eikä tarkempaa tyyppitietoa.

Lisäksi samalla tietotyypillä kuvataan 3D-suuntien ja pisteiden ("XYZW") lisäksi "RGBA"-värejä ja "STPQ"-tekstuurikoordinaatteja.

Grafiikkakoneiston toiminta ja kuvien piirtyminen "oikein" perustuu siihen, että yksityiskohdat, kuten \(w=0\) tai \(w=1\) ovat aina oikein.   Tätä asiaa ei kuitenkaan tarkkaile kukaan muu kuin ohjelmoija itse!   Eli tarkkana pitää olla!

Tieto siitä, mitä kaikki tarkoittaa on vain ohjelmoijan päässä ja toivottavasti osittain koodin kommenteissakin.

Normaalia ihmisbiologista päätä voi joutua avustamaan kynällä ja paperilla, mikäli XYZW-, RGBA- ja STPQ-nelikoita vilisee koodissa kovinkin paljon ja niillä on erilaisia geometrisia merkityssuhteita keskenään.

Vektorin skaalaus oikealta

Sovitaan, että nuolella symboloitu suuntavektori \(\vec v\) voidaan skaalata myös "oikealta":

\[ \vec v c = c \vec v,\] kun \(c\in \mathbb R\) ja \(\vec v\) on suuntavektori.

Tullaan nimittäin haluamaan näppärä matriisikertolasku, jossa on vasemmalla puolella vektoreita ja oikealla puolella reaalilukuja.

Tarkkaan ottaen operandien vaihtoehtoinen järjestys pitää sopia erikseen, koska yleinen vektoriavaruuden \(V\) skalaarikertolasku määriteltiin ottamaan skalaari vasemmanpuoleisena operandina ja vektori oikeanpuoleisena.

Toivottavasti missään vaiheessa tätä tekstiä ei ole ennen tätä kohtaa menty kirjoittamaan skalaarikertolaskun kerrointa muualle kuin vektorin vasemmalle puolelle.   Se olisi ollut kirjoittajalta virhe.

Sydämellinen kertolaskuoperaatiohan määriteltiin funktiona \(\heartsuit : \mathbb R \times V \rightarrow V\), mutta tarpeen olisi tehdä myös \(\heartsuit_R : V \times \mathbb R \rightarrow V\) niin että \(\heartsuit_R (v,a) := \heartsuit (a,v)\).

Ohjelmoinnissakin parametrien järjestyksellä on väliä, ja niin sanotut ylikuormitetut tavat käyttää metodeita täytyy määritellä erikseen.

Näin on silloinkin, kun aliohjelman tarvitsisi vain kutsua toista esimerkiksi seuraavasti:

  public static double trouble(Lohikaarme a, Kuningatar b) {
    return trouble(b,a);
  }

Käsitteellistä ongelmaa meillä ei nyt sopimuksessa \(\vec v c = c \vec v\) ole, koska vektorin skaalaaminen voidaan tehdä vain yhdellä tavalla.

Matriiseilla teknisenä laskuvälineenä voitaisiin kuitenkin kertoa muitakin kuin vektoriavaruuden ja skalaarikunnan alkioita keskenään, jolloin oikealta kertominen saattaisi olla erilainen operaatio, jos ollenkaan määritelty!

Toistetaan jälleen kerran, että koko ajan pitää olla selvillä olioiden tyypit ja niiden kanssa yhteensopivat operaatiot. Aivan kuin aina ohjelmoidessakin!

Kehyksen tai kannan "vasen notaatio"

Nyt kun katsottiin laskutoimitukset kuntoon niin voidaan kiepsauttaa kehykseen kiinnitetyn pisteen tai suunnan merkintätapa \(\mathbf c^T \vec{\mathbf f}\) ympäri:

\[ \mathbf c^T \vec{\mathbf f} = \vec{\mathbf f}^T \mathbf c. \]

Varmista tarvittaessa itse, että uskot.

Tämä \(\vec{\mathbf f}^T \mathbf c\) on notaatio, jota tällä kurssilla käytetään todellisen tai kuvitellun maailman pisteiden ja suuntien käsittelemiseen.

Siihen on kirjoitettu nyt oikealle puolelle koordinaattiesitys \(\mathbf c = [x\ y\ z\ w]^T\) eli reaaliluvuista muodostuva matriisisarake.

Koordinaatit voivat olla esimerkiksi taiteilijan mallinnusohjelmassa määrittämiä suhteessa mallinnuskoordinaatistoon.

Koordinaatilla \(w=1\) kuvataan pisteet, esimerkiksi taiteilijan määrittämän kolmioverkon kärikipisteet.

Koordinaatilla \(w=0\) kuvataan suunnat, esimerkiksi taiteilijan määrittämän kolmioverkon kärkipisteiden ulkosuunnat eli normaalit.

Vasemmalla puolella kulkee mukana kehys \(\vec{\mathbf f}\), jonka suhteen notaatio määrittää konkreettiset pisteet ja suunnat.

Tietokonegrafiikassa kysymys on, että jos mallintaja on laittanut 5-metrisen kirahvin korvan kohtaan \(\vec{\mathbf m}^T \mathbf c\) mallinnuskoordinaatistossa \(\vec{\mathbf m}\), niin miten meidän omassa animaatiossa saadaan tehtyä 4-metrisen kirahvin korva maailmankoordinaatistossa \(\vec{\mathbf w}\) paikkaan \(\vec{\mathbf w}^T \mathbf s\), mistä 10-senttinen orava kuiskaisi 4-metrisen kirahvin korvaan.

Ennakoivana havaintona huomataan, että nyt kaikki on teknisesti matriisilaskua, ja notaatiosta löytyy kivasti lokero neliömatriisille \(M\) niin, että tuloksen tyyppi ei muutu:

\[ \vec{\mathbf f}^T M \mathbf c. \]

Havaitaan myös, että matriisilasku on assosiatiivinen, eli voidaan suluttaa lauseke eri tavalla riippuen tulkinnasta. Tulos on sama riippumatta tulkinnasta: \[ \vec{\mathbf f}^T M \mathbf c = (\vec{\mathbf f}^T M) \mathbf c = \vec{\mathbf f}^T (M \mathbf c). \]

Tulkinta sen sijaan tulee olemaan avain tietokonegrafiikan pitämiseksi hanskassa ja hanskat tallessa.

Kehyksen sijasta voitaisiin ajatella ja kirjoittaa vastaavasti pelkällä kannalla \(\vec{\mathbf b}\) ja pelkkiä suuntia ilmaisevilla vektoreilla, esimerkiksi \(\vec{\mathbf b}^T M \mathbf v\).

3-ulotteisen maailman sijasta voidaan ajatella 2-ulotteista paperiin piirtämisen helpottamiseksi. Kaikki toimii muuten samoin, mutta matriiseissa ja vektoreissa on yksi rivi/sarake vähemmän 2D:ssä kuin 3D:ssä.

Lisäksi suurin osa kaikesta tästä toimii samalla tavoin \(n\)-ulotteisessa avaruudessa, \(n>3\), jos tarpeen on.

Näillä ajatuksilla lähdetään katsomaan, mitä erilaisilla matriiseilla \(M\) voitaisiin tehdä.

Lineaari- ja affiinikuvaukset.

Lineaarikuvaus

Kerrataan alkupuolelta lineaarikuvauksen määritelmä:

Lineaarikuvaus on funktio \(\mathcal L: V \rightarrow W\) vektoriavaruudesta \(V\) vektoriavaruuteen \(W\), jolle pätee vektoriavaruuksien laskutoimituksilla seuraavaa:

  • Kuvaus säilyttää mittakaavaerot eli vektorien suhteelliset pituudet \[\mathcal L (av) = a\mathcal L(v) \quad \forall a \in \mathbb F, v \in V.\]
  • Kuvaus säilyttää vektorien summavaikutuksen eli \[\mathcal L (u + v) = \mathcal L (u) + \mathcal L (v) \quad \forall u,v \in V.\]

Näitä kahta sääntöä sanotaan tarkasteltavan menettelyn lineaarisuudeksi.

Ne tarkoittavat, että kuvaus tai operaatio "säilyttää vektoriavaruuden rakenteen" eli "vektorien geometrian".

Avaruudet \(V\) ja \(W\) voivat olla erilaiset, kunhan ne ovat molemmat vektoriavaruuksia ja niiden kerroinkunta on yhteensopiva, esimerkiksi molemmissa \(\mathbb R\).

Avaruuksissa voi olla eri määrä ulottuvuuksia, ja niiden sisältämät oliot voivat olla tyypiltään aivan erilaisia, kunhan ne käyttäytyvät kuten kunnon vektorit.

Tällä kurssilla nähdään esimerkki, jossa on yhdessä avaruudessa 3D-pisteitä ja toisessa kolmannen asteen polynomeja.

Kuvaus voi olla myös suljettu operaatio avaruudesta takaisin itseensä.

Esimerkiksi 3D-maailman mallien sijoitteleminen tullaan tekemään kuvauksilla \(\mathcal L: \mathbb R^4 \rightarrow \mathbb R^4\), missä sekä lähtö- että maaliavaruutena on "\(\mathbb R^4\)" eli jotakuinkin edellä kuvatut koordinaattiesitykset mallia \([x\ y\ z\ w]^T\).

Halkaistaan pari hiusta tässä välissä

Sanottiin "jotakuinkin \(\mathbb R^4\)", jotta ei tässä kohtaa tarvitse halkaista hiuksia siitä, sovitaanko \(\mathbb R^4\):ään Euklidinen rakenne ja karteesinen koordinaatisto, kuten joskus on tapana ilman eri mainintaa.

Halkaistaan se hius kuitenkin.

Ohjelmoijan pitää olla tarkkana olioiden tyypeistä, joten ollaanpa.

Tässä monisteessa on aiemmin käytetty joukkojen karteesista tuloa eli esimerkiksi \(\mathbb R^4 = \mathbb R \times \mathbb R \times \mathbb R \times \mathbb R\) niin, että joukon alkiot ovat järjestettyjä nelikkoja \((r_1,r_2,r_3,r_4)\), \(r_i \in \mathbb R, i=1,2,3,4\).

Tässä ei ole mukana mitään sopimuksia laskutoimituksista nelikoiden välillä!

Näin ollen ei ole mitään rakennetta sovittu, eikä \(\mathbb R^4\) siis ole mikään "avaruus", jonka rakennetta voitaisiin tutkia.

Yleensä oppikirjan tai tekstin konteksti voi olla sellainen, että \(\mathbb R^4\) tulkitaan koordinaattiesitykseksi euklidisessa avaruudessa, jossa on siis kiinni jokin oletettu origo ja karteesiset, toisiaan vastaan kohtisuorat kantasuunnat, joiden kaikkien pituus on 1.

Vektoreiden yhteenlasku ja skaalaaminen ajatellaan silloin ilman eri mainintaa määritellyksi alkioittain eli koordinaateittain tehtäväksi, ihan kuin pystyvektorien matriisilaskut.

Insinöörikirjallisuudessa saatetaan olettaa myös ilman selityksiä, että \(\mathbb R^4\):n koordinaatit ovat sarakematriiseja \([r_1\ r_2\ r_3\ r_4]^T\), jolloin matriisilaskujen notaatio on mielekäs.

Mukana on yleensä oletus siitä, että "kohtisuora" tai "olioiden välinen kulma" tai "olion absoluuttinen pituus" tarkoittaa ylipäätään jotakin.

Erityisesti ilman mainintoja oletetaan yleensä "euklidinen sisätulo", jossa saadaan kohtisuoruus yhtälönä \(\mathbf a^T \mathbf b = 0\) ja vektorin pituus Pythagoraan sääntönä \(\sqrt{\mathbf a^T \mathbf a}\).

Jälkiviisaasti tässä monisteessa olisi voitu käyttää eri symbolia, kuten \(\mathbb E_4\) tai muuta sopivaa, tarkoittamaan \(\mathbb R^4\):n nelikoille määriteltyä euklidista rakennetta ja saman tien myös esitysmuotoa pystymatriisina.

Tämä ajatus olisi varmaan hyvä olla mukana jo alusta alkaen, joten merkitään se nyt tällaisena ylimääräisenä tarpeena halkaista hius. Korjataan ehkä johonkin myöhempään versioon.

Laskut tehdään tuollaisessa avaruudessa \(\mathbb E_4\) aivan samoin kuin aiemmassa luvussa kuvatuissa matriisiesityksissä mallia \([r_1\ r_2\ r_3\ r_4]^T\).

Oli siis melkein mielekästä sanoa, että \([r_1\ r_2\ r_3\ r_4]^T\) on "jotakuinkin" avaruuden \(\mathbb R^4\) alkio.

Grafiikassa tarvitaan vinokulmaisia ja keskenään eri pituisia kantavektoreita, joten meidän pitää olla hieman tarkempia kuin pelkkä euklidisen rakenteen sopiminen mahdollistaa.

Hius on halkaistu - sitten eteenpäin avaruudessa \(\mathbb E_4\) tai \(\mathbb R^4\), kunhan ollaan kartalla esitysmuodoista, olioista, tyypeistä ja operaatioista niiden välillä!

Lineaarikuvauksen matriisi

Kiinnitetään merkinnät ja oliot

Otetaan 3D-avaruuden kanta \(\vec{\mathbf b} = [\vec b_1\ \vec b_2\ \vec b_3]^T\).

Voidaan siis mallintaa vain 3D-suuntia, ei pisteitä.

Otetaan kiinni suuntavektori \(\vec v\) ja sen kordinaatit \(\mathbf c = [c_1\ c_2\ c_3]^T\) niin, että \(\vec v = \vec{\mathbf b}^T \mathbf c\).

Otetaan lineaarikuvaus \(\mathcal L\), joka kuvaa 3D-suuntavektorit 3D-suuntavektoreiksi eli on suljettu lasku 3D-suunnille.

Käytetään tyypillistä merkintää, jossa merkitään nuolella funktion vaikutus sen parametriin:

\[ \vec v \rightarrow \mathcal L(\vec v). \]

Korjataan lähdemateriaalin merkinnät

MIT:n kalvosarjassa on säännönmukaisesti väärä nuoli \(\implies\), jonka merkitys on yleensä ihan eri kuin nuolen \(\rightarrow\).

Tuplanuoli \(\implies\) nimittäin luetaan yleensä "johtaa siihen, että" tai "vain silloin, kun" tai vastaavaa.

Sen sijaan yksittäinen nuoli \(\rightarrow\) luetaan "muuntuu" tai jotain muuta vastaavaa.

Eli tässähän halutaan sanoa, että "vee muuntuu Äl veeksi" tai tarkemmin "vektori vee kuvautuu vektoriksi Äl vee".

Älä mene sekaisin.

Kirjoita mieluummin kalvosarjan häröt kaavat itsellesi uudelleen oikeanlaisilla merkintätavoilla.

Siitä oppii.

Tässä monisteessa on yritetty pureskella asiaa vähän valmiimmaksi.

Opettajaa huolettaa kuitenkin kysymys, oppiiko siitä, että vain näkee ilman, että tekee ja miettii itse!

Ehkä tähän tekstiin kuitenkin tarvitsee hajoilla hieman vähemmän kuin matkan varrella osittain rikki menneisiin PowerPointteihin?

Lasketaan matriiseilla ja vektoreilla

Kirjoitetaan kaavasta \(\vec v \rightarrow \mathcal L(\vec v)\) lopputulema matriiseilla:

\[ \begin{align} \mathcal L(\vec v) & = \mathcal L ( \vec{\mathbf b}^T{\mathbf c}) \\ & = \mathcal L (\vec b_1 c_1 + \vec b_2 c_2 + \vec b_3 c_3) \\ & = \mathcal L (c_1 \vec b_1 + c_2 \vec b_2 + c_3 \vec b_3) \\ & = \mathcal L (c_1 \vec b_1 + (c_2 \vec b_2 + c_3 \vec b_3)) \\ & = \mathcal L (c_1 \vec b_1) + \mathcal L (c_2 \vec b_2 + c_3 \vec b_3 ) \\ & = \mathcal L (c_1 \vec b_1) + \mathcal L (c_2 \vec b_2) + \mathcal L ( c_3 \vec b_3)\\ & = c_1 \mathcal L(\vec b_1) + c_2 \mathcal L(\vec b_2) + c_3 \mathcal L(\vec b_3) \\ & = \mathcal L(\vec b_1) c_1 + \mathcal L(\vec b_2) c_2 + \mathcal L(\vec b_3) c_3 \\ & = \begin{bmatrix}\mathcal L(\vec b_1) & \mathcal L(\vec b_2) & \mathcal L(\vec b_3)\end{bmatrix} \begin{bmatrix} c_1 \\ c_2 \\ c_3 \end{bmatrix} \\ & = [\mathcal L(\vec b_1)\ \mathcal L(\vec b_2)\ \mathcal L(\vec b_3)] \mathbf c \\ & = : \mathcal L(\vec{\mathbf b})^T \mathbf c. \end{align} \]

Tässä on tehty kullakin rivillä sellainen operaatio, josta meillä on tehty sopimus aiemmin.

Käytössä on vektorin skaalaus oikealta/vasemmalta, vektorisumman assosiatiivisuus, lineaarikuvauksen molemmat ominaisuudet ja mekaaninen matriisikertolasku.

Lopussa on määritelty uusi merkintätapa \(\mathcal L(\vec{\mathbf b})\) sille, että kaikki kantakolmikon alkiot kuvattiin \(\mathcal L\):llä.

Matematiikan oppikirjassa välivaiheet olisi jätetty täydennettäväksi joko omassa päässäsi tai kynällä ja paperilla, mikäli jokin vaihe ei mahtuisi päähän yhtä aikaa muiden kanssa.

Lasketaan matriiseilla vähän lisää

Lineaarikuvaus \(\vec v \rightarrow \mathcal L ( \vec v)\) voidaan tehdä niin, että vektorin koordinaatit pysyvät samana.

Silloin kuvataan kanta \([\vec b_1\ \vec b_2\ \vec b_3]^T \rightarrow [\mathcal L (\vec b_1) \ \mathcal L (\vec b_2) \ \mathcal L (\vec b_3) ]^T\) ja mikä tahansa kannan suhteen koordinaatteina ilmaistu vektori kuvautuu siinä mukana.

Myös kuvatut kantavektorit \(\mathcal L (\vec b_1)\), \(\mathcal L (\vec b_2)\) ja \(\mathcal L (\vec b_3)\) voidaan esittää koordinaatteina alkuperäisen kannan suhteen.

Tehdään se jokaiselle 3D-kantasuunnalle:

\[ \mathcal L (\vec b_1) = \begin{bmatrix}\vec b_1 & \vec b_2 & \vec b_3 \end{bmatrix} \begin{bmatrix} M_{1,1} \\ M_{2,1} \\ M_{3,1} \end{bmatrix} \]

joillekin koordinaateille \(M_{1,1}, M_{2,1}, M_{3,1} \in \mathbb R\). Samoin

\[ \mathcal L (\vec b_2) = \begin{bmatrix}\vec b_1 & \vec b_2 & \vec b_3 \end{bmatrix} \begin{bmatrix} M_{1,2} \\ M_{2,2} \\ M_{3,2} \end{bmatrix} \] ja \[ \mathcal L (\vec b_3) = \begin{bmatrix}\vec b_1 & \vec b_2 & \vec b_3 \end{bmatrix} \begin{bmatrix} M_{1,3} \\ M_{2,3} \\ M_{3,3} \end{bmatrix} \] joillekin koordinaateille \(M_{1,2}, M_{2,2}, M_{3,2}, M_{1,3}, M_{2,3}, M_{3,3} \in \mathbb R\).

Kerätään johtopäätös

Edellä valitut koordinaattisymbolit mallia \(M_{i,j}\) enteilivät lopullista havaintoa.

Kannan muuntaminen lineaarikuvauksella voidaan näköjään kirjoittaa matriisilaskuna \[ \mathcal L (\vec{\mathbf b}^T) = \begin{bmatrix}\vec b_1 & \vec b_2 & \vec b_3 \end{bmatrix} \begin{bmatrix} M_{1,1} & M_{1,2} & M_{1,3} \\ M_{2,1} & M_{2,2} & M_{2,3} \\ M_{3,1} & M_{3,2} & M_{3,3} \end{bmatrix} = \vec{\mathbf b}^T M \] ja vektorin muuntaminen ihan vain kirjoittamalla loppuun alkuperäinen koordinaattivektori \[ \mathcal L (\vec v) = \mathcal L (\vec{\mathbf b}^T\mathbf c) = \begin{bmatrix}\vec b_1 & \vec b_2 & \vec b_3 \end{bmatrix} \begin{bmatrix} M_{1,1} & M_{1,2} & M_{1,3} \\ M_{2,1} & M_{2,2} & M_{2,3} \\ M_{3,1} & M_{3,2} & M_{3,3} \end{bmatrix} \begin{bmatrix} c_1 \\ c_2 \\ c_3 \end{bmatrix} = \vec{\mathbf b}^T M \mathbf c \]

Matematiikan ala nimeltä lineaarinen algebra ja geometria aloittaa sitten jotakuinkin tästä pisteestä eteenpäin varmistelemaan, millaisia työkaluja voitaisiin missäkin tilanteissa käyttää varmasti ja turvallisesti.

Meille matematiikka lupaa muun muassa, että mitä tahansa lineaarikuvausta vastaa yksikäsitteinen matriisi ja toisin päin.

Meillä on siis lupa mallintaa lineaarikuvaus tietokoneessa tehtävänä reaalilukumatriisien kertolaskuna ja luottaa jollain hallitulla riskillä tuloksiin, joita lineaarialgebran oppikirjan yhteenvetosivuilla tai Wikipediassa uskotellaan todistetuiksi väittämiksi.

Henkilökohtainen riski pienenee sitä mukaa, mitä enemmän ehtii itse pyöritellä näitä asioita päässään, kynällä, paperilla, ja vaikkapa grafiikkaa tekevässä ohjelmakoodissa.

Tällä kurssilla tehdään näitä asioita aivan ensimmäiset 2 kuukautta, jos aiempaa taustaa lineaarialgebrasta tai grafiikkaohjelmoinnista ei ole.

Mitä lineaarikuvauksilla voidaan mallintaa

Lineaarikuvauksilla voidaan tehdä 3-ulotteisen avaruuden suuntavektoreille kiertoja, skaalauksia, peilauksia ja vääntöjä.

Näistä löytyy kuva esimerkiksi MIT:n kalvosarjasta.

Kuten nähty, vektoriavaruus tai sen lineaarikuvaukset eivät mallinna pisteitä riittävällä tavoin.

Jos samaistetaan piste siirtymävektoriin, jolla siihen tultaisiin origosta lähtien, niin lineaarikuvauksella voitaisiin tehdä samat kierrot ja etäisyyden skaalaukset kuin suunnillekin.

Lineaarikuvauksilla ei ole kuitenkaan mahdollista esittää suoraviivaista siirtymää pisteestä toiseen.

Jos ajatellaan siirtoa funktiona \(f:\mathbb R \rightarrow \mathbb R\), joka siirtää vaikka yhtäkin koordinaattia siirtymän \(t_x \in \mathbb R\) verran eli \(f(x) = x+t_x\), niin huomataan esimerkiksi, että \[ f(ax) = ax + t_x \ne a x+ at_x = a (x+t_x) = af(x). \]

Koordinaateinkaan ilmoitetun pisteen siirto ei ole lineaarikuvaus, koska ensimmäinenkään vaadittu ominaisuus ei toteudu.

Siirto on nimeltään affiini kuvaus, ja siirreltäviä pisteitä sisältävä avaruus affiini avaruus.

Lineaarikuvaukset kehyksessä

Meillä on jo sovittuna malli, jossa pisteet ja suunnat saadaan ilmoitettua kehyksen suhteen laittamalla ylimääräinen koordinaatti arvolla \(1\) tai \(0\).

Siitä kierähtää affiini avaruus helposti lineaariseksi, kun ensin vähän katsellaan, mitä matriisit tekevät meille.

Otetaan kehys \(\vec \mathbf f = [\vec b_1\ \vec b_2\ \vec b_3 \ \tilde o]^T\) ja kokeilun vuoksi mikä tahansa suunta \(\vec v = [v_x\ v_y\ v_z\ 0]\vec \mathbf f\) ja piste \(\tilde p = [p_x\ p_y\ p_z\ 1]\vec \mathbf f\).

Kokeillaan, miten suunnalle käy, jos se kerrotaan \(4 \times 4\) -matriisilla, jossa viimeinen rivi on \([0\ 0\ 0\ 1]\), viimeinen sarake \([0\ 0\ 0\ 1]^T\) ja vasemmassa yläkulmassa on 3-ulotteisten suuntien lineaarikuvausta \(\mathcal L\) vastaava \(3 \times 3\) alimatriisi:

\[ \begin{align} & \begin{bmatrix} \vec b_1 & \vec b_2 & \vec b_3 & \tilde o \end{bmatrix} \begin{bmatrix} M_{1,1} & M_{1,2} & M_{1,3} & 0 \\ M_{2,1} & M_{2,2} & M_{2,3} & 0 \\ M_{3,1} & M_{3,2} & M_{3,3} & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} v_x \\ v_y \\v_z \\ 0 \end{bmatrix} = \ldots \\ & \ldots = v_x \mathcal L ( \vec b_1) + v_y \mathcal L ( \vec b_2) + v_z \mathcal L ( \vec b_3) \\ & = \begin{bmatrix} \mathcal L (\vec b_1) & \mathcal L (\vec b_2) & \mathcal L (\vec b_3) & \tilde o \end{bmatrix} \begin{bmatrix} v_x \\ v_y \\v_z \\ 0 \end{bmatrix} \end{align} \]

Mieluusti saisit itse järkeillä tarvittavat välivaiheet kolmen pisteen kohdalle. Lopputulemana pitäisi saada ihan mekaanisella matriisilaskulla tämä, että 3-ulotteiset lineaarikuvaukset toimivat 4-ulotteisena kuvatuille suunnille, kun ne kerrotaan lohkomatriisilla \[ \begin{bmatrix} M & \mathbf 0 \\ \mathbf 0 & [1] \end{bmatrix}, \] missä \(M\) on 3-ulotteista lineaarikuvausta edustava alimatriisi, \(\mathbf 0\) nollia sisältävää lohko ja \([1]\) alimatriisi aivan kuin se on kirjoitettu.

Sitten kokeillaan, mitä edellinen lasku tekee pisteelle:

\[ \begin{align} & \begin{bmatrix} \vec b_1 & \vec b_2 & \vec b_3 & \tilde o \end{bmatrix} \begin{bmatrix} M_{1,1} & M_{1,2} & M_{1,3} & 0 \\ M_{2,1} & M_{2,2} & M_{2,3} & 0 \\ M_{3,1} & M_{3,2} & M_{3,3} & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} p_x \\ p_y \\p_z \\ 1 \end{bmatrix} = \ldots \\ & \ldots = \tilde o + p_x \mathcal L ( \vec b_1) + p_y \mathcal L ( \vec b_2) + p_z \mathcal L ( \vec b_3) \\ & = \begin{bmatrix} \mathcal L (\vec b_1) & \mathcal L (\vec b_2) & \mathcal L (\vec b_3) & \tilde o \end{bmatrix} \begin{bmatrix} p_x \\ p_y \\p_z \\ 1 \end{bmatrix} \end{align} \] Tässä kuvauksessa piste pysyy pisteenä eli neljäs koordinaatti on edelleen \(1\).

Piste on edelleen annettu saman origon suhteen kuin ennenkin.

Kehyksen kantavektorit on tietysti kuvautuneet samalla tavoin kuin suuntien kuvaamisessa.

Näin ollen siirtymävektori kehyksen paikallisesta origosta pisteeseen on kuvautunut samalla tavoin.

Nyt meillä on malli, jossa voidaan tehdä lineaarimuunnokset eli kierrot, skaalaukset, peilaukset ja väännöt myös aidosti pistettä kuvaavalle oliolle.

Siirtokuvaus matriisina

Hauskuus ei lopu tähän, vaan jatkuu seuraavalla matriisilaskulla. Tehdään se ensin suunnalle:

\[ \begin{align} & \begin{bmatrix} \vec b_1 & \vec b_2 & \vec b_3 & \tilde o \end{bmatrix} \begin{bmatrix} 1 & 0 & 0 & M_{1,4} \\ 0 & 1 & 0 & M_{2,4} \\ 0 & 0 & 1 & M_{3,4} \\ 0 & 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} v_x \\ v_y \\v_z \\ 0 \end{bmatrix} = \ldots \\ & \ldots = v_x \vec b_1 + v_y \vec b_2 + v_z \vec b_3 \\ & = \begin{bmatrix} \vec b_1 & \vec b_2 & \vec b_3 & \tilde \omega \end{bmatrix} \begin{bmatrix} v_x \\ v_y \\v_z \\ 0 \end{bmatrix} \end{align} \],

missä \(\tilde \omega\) on jotain muuta kuin alkuperäinen origo \(\tilde o\), mutta suuntavektori ei muuttunut miksikään tässä muunnoksessa.

Lohkomatriisina voitaisiin kirjoittaa tämä muunnos \[ \begin{bmatrix} I_3 & T \\ \mathbf 0 & [1] \end{bmatrix}, \] missä \(I_3\) kuvaa \(3\times 3\) -identiteettimatriisia, \(T = [T_x\ T_y\ T_z]^T = [M_{1,4}\ M_{2,4}\ M_{3,4}]^T\) on tiettyä merkitystä enteilevin symbolein kirjoitettu \(3 \times 1\) -alimatriisi, \(\mathbf 0\) edelleen nollia sisältävää lohko ja \([1]\) tavallinen ykkönen.

Jälleen kokeillaan, mitä edellinen lasku tekee pisteelle:

\[ \begin{align} & \begin{bmatrix} \vec b_1 & \vec b_2 & \vec b_3 & \tilde o \end{bmatrix} \begin{bmatrix} 1 & 0 & 0 & T_x \\ 0 & 1 & 0 & T_y \\ 0 & 0 & 1 & T_z \\ 0 & 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} p_x \\ p_y \\ p_z \\ 1 \end{bmatrix} = \ldots \\ & \ldots = \tilde o + (p_x \vec b_1 + p_y \vec b_2 + p_z \vec b_3) + (T_x \vec b_1 + T_y \vec b_2 + T_z \vec b_3) \\ & = \begin{bmatrix} \vec b_1 & \vec b_2 & \vec b_3 & \tilde o + \vec t \end{bmatrix} \begin{bmatrix} p_x \\ p_y \\p_z \\ 1 \end{bmatrix} \end{align} \] missä \(\vec t = [\vec b_1\ \vec b_2\ \vec b_3]T\).

Havainto: Piste pysyy pisteenä ja siirtyy komponenttien \(T_x\), \(T_y\), \(T_z\) verran kehyksen kantavektorien määräämiin suuntiin.

Kokonaissiirros on kirjoitettu tässä symbolilla \(\vec t = [\vec b_1\ \vec b_2\ \vec b_3]T = T_x \vec b_1 + T_y \vec b_2 + T_z \vec b_3\).

Viimeinen rivi on toinen näkökulma samaan asiaan: Origo siirtyy, ja koordinaateilla ilmoitettu piste sen mukana.

Symboleissa enteilevästi käytetty T-kirjain viittaa englannin sanaan "translation" eli sijainnin vaihtaminen.

Affiinikuvaus matriisina

3-ulotteisen avaruuden sijainneille ja suunnille voidaan ilmeisesti tehdä \(4 \times 4\) -matriiseilla kaikki affiinissa avaruudessa tarvittavat kuvaukset:

  • pisteiden ja suuntien lineaariset muunnokset
  • pisteiden siirtäminen.

Lineaariset kuvaukset ja siirto tehdään toisistaan riippumattomilla osilla \(4 \times 4\) -matriisia.

Matriisi voidaan kirjoittaa lohkoina lineaarisesta \(3 \times 3\) -alimatriisista \(L\), siirtoa kuvaavasta \(3 \times 1\) alimatriisista \(T\) ja rivistä, jolla on nollia ja 1 seuraavasti: \[M = \begin{bmatrix} L & T \\ \mathbf 0 & 1 \end{bmatrix} \]

Kun nämä kirjoitetaan auki \(4 \times 4\) -matriisiksi \(M\), voidaan nähdä ihan mekaanisesta matriisilaskusta, kuinka nätisti alkiot \(0\) ja \(1\) neljäntenä koordinaattina pitävät suuntien ja pisteiden mallit ja niihin vaikuttavat matriisin lohkot erillään:

\[ \begin{bmatrix} \vec b_1 & \vec b_2 & \vec b_3 & \tilde o \end{bmatrix} \begin{bmatrix} M_{1,1} & M_{1,2} & M_{1,3} & M_{1,4} \\ M_{2,1} & M_{2,2} & M_{2,3} & M_{2,4} \\ M_{3,1} & M_{3,2} & M_{3,3} & M_{3,4} \\ 0 & 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x \\ y \\z \\ w \end{bmatrix}. \]

Muistetaan, että lohkomatriisiin voi piirtää viivat helpottamaan osien hahmottamista erillisinä: \[ M = \left[ \begin{array}{ccc|c} M_{1,1} & M_{1,2} & M_{1,3} & M_{1,4} \\ M_{2,1} & M_{2,2} & M_{2,3} & M_{2,4} \\ M_{3,1} & M_{3,2} & M_{3,3} & M_{3,4} \\ \hline 0 & 0 & 0 & 1 \end{array} \right] = \left[ \begin{array}{ccc|c} L_{1,1} & L_{1,2} & L_{1,3} & T_{x} \\ L_{2,1} & L_{2,2} & L_{2,3} & T_{y} \\ L_{3,1} & L_{3,2} & L_{3,3} & T_{z} \\ \hline 0 & 0 & 0 & 1 \end{array} \right]. \]

3-ulotteisen avaruuden affiinit kuvaukset toimivat ilmeisesti jollain tapaa samoin kuin 4-ulotteisen avaruuden lineaarikuvaukset.   Ne voidaan tehdä matriisilaskulla esityksessä, jossa on kehys ja 4-koordinaattiset koordinaattivektorit kuvaamassa suuntia ja pisteitä.

Grafiikan hallinta perustuu ymmärrykseen siitä, miten rakennetaan tilanteeseen sopiva matriisi \(M\), joka ajatellaan kaavaan \(\vec \mathbf f ^T M \mathbf c\) kuvaamaan sopivasti joko vasemmalle puolelle kirjoitetun kehyksen \(\vec \mathbf f\) tai oikealle puolelle kirjoitetut koordinaatit \(\mathbf c\).   Rakentelua auttaa havainto siitä, että matriisilaskuja voidaan yhdistellä peräkkäin, joten päästään yhdistelemään myös pisteiden ja suuntien affiineja kuvauksia!

2-ulotteiset affiinit muunnokset

2-ulotteiselle kehykselle \(\mathbf f = [\vec b_1\ \vec b_2\ \tilde o]^T\) voidaan määritellä vastaavalla tavalla 2-ulotteisen suunnan ja pisteen koordinaattiesitykset \([v_x\ v_y\ 0]^T\) ja \([p_x\ p_y\ 1]^T\).

Muunnosmatriisit ovat silloin \(3 \times 3\) -matriiseja muotoa \[ M = \left[ \begin{array}{cc|c} M_{1,1} & M_{1,2} & M_{1,3} \\ M_{2,1} & M_{2,2} & M_{2,3} \\ \hline 0 & 0 & 1 \end{array} \right] = \left[ \begin{array}{cc|c} L_{1,1} & L_{1,2} & T_{x} \\ L_{2,1} & L_{2,2} & T_{y} \\ \hline 0 & 0 & 1 \end{array} \right]. \]

Näillä täytyy osata laskea vaikka unissaan, ja yhteys paperiin piirretyille 2D-kehyksille toistensa suhteen täytyy olla selvillä.

Kevään 2019 luennoilla on tehty aiheesta matriisilaskua ryhmätyönä sekä kehollisia harjoitteita laskutoimitusten vaikutuksen havainnollistamiseksi oikeakätisen 3D-koordinaatiston pisteelle.

Kerrataan ja opetellaan!

Esimerkkejä käyttökelpoisista muunnoksista ja matriiseista

Otsikon mukainen sisältö löytyy kevään 2019 kalvosarjasta ja luentovideoilta hyvin.

Ei siis tuplata sisältöä nyt tässä.

Luentoesimerkeissä käytiin läpi kierto \(z\)-akselin ympäri, skaalaus sekä näiden käänteismuunnokset.

Etenkin MIT:n mallikoodin vecmath-kirjastoa on syytä selata ja tutkia, kuinka matriisit, vektorit ja 3D-affiinimuunnokset on toteutettu C++:lla ja millainen rajapinta luokista on julkaistu sovellusohjelman käyttöön.

Koodissa on tärkeimmät peruselementit, jotka tarvitaan melkein kaikessa grafiikassa.

Rajapinta on geneerinen, ja hyvin saman näköinen kuin esimerkiksi modernin OpenGL:n varjostinohjelmointikielten rajapinta.

Suorat ja käyrät

Pientä algebraa pisteillekin

Parametrisoitu siirtymä

Tarkkaan ottaen pisteen skaalausta ei edelleenkään haluttaisi pusertaa mielekkääksi operaatioksi, koska todellisen maailman piste pysyy paikoillaan, jos sitä ei siirretä, mihin operaatioon tarvitaan siirtymä eli vektori.

Mielekkäänä voitaisiin kuitenkin pitää esimerkiksi suoraviivaisen siirtymän puoliväliä tai jotakin muuta pistettä, johon päästäisiin kulkemalla vain osa matkasta.

Esimerkki:

Matka \(\vec v\) pisteestä \(\tilde p\) pisteeseen \(\tilde q\) voidaan laskea aiemmilla sopimuksilla: \(\vec v = \tilde q - \tilde p\).

Puolet tästä matkasta on \(0.5 \vec v\). Siinä kohtaa on tultu pisteeseen \(\tilde p + 0.5 \vec v = \tilde p + 0.5 ( \tilde q - \tilde p )\).

Neljäsosa matkasta on \(0.25 \vec v\), jolloin oltaisiin pisteessä \(\tilde p + 0.25 ( \tilde q - \tilde p )\).

\(98\) prosenttia matkasta on \(0.98 \vec v\), mikä vie pisteeseen \(\tilde p + 0.98 ( \tilde q - \tilde p )\) ja niin edelleen.

Merkitään kuljettua osuutta symbolilla \(t \in [0,1] \subset \mathbb R\).   Tämä luetaan niin, että "\(t\) kuuluu välille nollayks ärrästä".   Se tarkoittaa, että \(t\) on reaaliluku, joka on vähintään \(0\) ja enintään \(1\).   Näinhän pitää olla, jos \(t\) kuvaa jotakin osuutta yhdestä kokonaisuudesta.   Symboli \(\subset\) on vaakasuuntaan piirretty kuppi.   Se avautuu kohti joukkoa, josta kupin pohjalle merkitty joukko on osajoukko.   Tässä merkintä täsmentää, että \([0,1]\) on "lukusuoran" \(\mathbb R\) pätkä eikä mitään ihmeellisempää.

Symbolin t-kirjain voidaan yhdistää englannin sanaan "time", koska tasaisella nopeudella kävelty osuus matkan pituudesta on sama kuin osuus matka-ajasta.

Esimerkiksi jos tasavauhtinen kävely kotoa yliopistolle kestää \(24\) minuuttia, niin neljäsosa matkasta on tehty \(0.25 \cdot 24=6\) minuutin kohdalla. Jos reitti on yhteensä \(2\) kilometriä, niin tuo 6 minuutissa kuljettu matka on \(0.25 \cdot 2 = 0.5\) kilometriä.

Voinet ymmärtää, että tällä idealla on suora yhteys esimerkiksi ajan suhteen tehtäviin animaatioihin tietokonegrafiikassa.

Sovitaan nyt, että pisteillä saa laskea algebrallista kertolaskua myös silloin, kun tulkintana on osittain kuljettu välimatka:

\[ \tilde p + t ( \tilde q - \tilde p ) = \tilde p + t \tilde q - t \tilde p = (1 - t) \tilde p + t \tilde q, \]

missä \(t\in [0,1]\)

Nuolia piirtämällä voi todeta, että tämä toimii tulkinnan mukaisesti.

Suora tai säde

Lausekkeessa \(\tilde p + t ( \tilde q - \tilde p )\) ei ole mitään epäilyttävää, vaikka parametrin \(t\) annettaisiin saada mikä tahansa arvo \(t \in \mathbb R\).   Silloin mahdollistettaisiin kulkeminen samalla suunnan \(\tilde q - \tilde p\) suuntaisella suoralla myös ohi päätepisteen \(\tilde q\), kun \(t>1\), tai ohi lähtöpisteen \(\tilde p\), kun \(t<0\).   Yleisesti ottaen mikä tahansa avaruuden suora voidaan esittää parametriesityksenä, jossa on kiinnitetty jokin piste \(\tilde R_o\) ja suunta \(\vec R_d\).   Suoran parametrisoitu yhtälö on silloin \(\tilde R_o + t \vec R_d\), missä \(t \in \mathbb R\).   Tätä käytetään muun muassa mallina yhden valonsäteen kulkutielle, kun muodostetaan kuvia säteenseuranta -nimisellä menetelmällä.   Tässä olikin johdattelevasti valittu symboleiksi \(\tilde R_o\) englannin sanaan "ray origin" liittyen ja \(\vec R_d\) englannin sanaan "ray direction" liittyen.

Painotettu painopiste

Laajennetaan pisteiden välimaastoon kuljeskelua vielä yhdellä mielekkäällä tulkinnalla.

Sovitaan, että voidaan laskea \(n\):lle eri pisteelle painotettu summa \(\tilde s = \sum_{i=1}^n w_i \tilde p_i\) sellaisessa tapauksessa, että \(w_i \in [0,1] \subset \mathbb R\) ja \(\sum_{i=1}^n w_i = 1\).

Sanotaan, että tällainen \(\tilde s\) on pisteiden \(\tilde p_1, \ldots, \tilde p_n\) painokertoimilla \(w_1, \ldots, w_n\) painotettu massakeskipiste tai painopiste.

Esimerkiksi kolmion kärkipisteille \(\tilde A, \tilde B, \tilde C\) voisi laskea \(\tilde s = \frac{1}{3}\tilde A + \frac{1}{3}\tilde B + \frac{1}{3}\tilde C\).

Silloin löytyisi piste \(\tilde s\), josta ripustamalla kolmion muotoinen, tasainen, levy pysyisi suurin piirtein vaakatasossa painovoiman vetäessä kolmion kaikkia kohtia tasaisesti alaspäin.

Eri kertoimilla voitaisiin mallintaa suhdelukuja eri kärkipisteisiin asetetuille lisäpainoille.

Esimerkiksi painopiste \(\tilde r = \frac{1}{10}\tilde A + \frac{2}{10}\tilde B + \frac{7}{10}\tilde C\) olisi lähempänä pistettä \(\tilde C\) kuin edellisen esimerkin piste \(\tilde s\), koska nyt mallinnettiin kolmion kärkipisteeseen \(\tilde C\) painoksi seitsemän kertaa massiivisempi möhkäle kuin kärkipisteessä \(\tilde A\).

Myös piste \(\tilde B\) on nyt kaksi kertaa painavampi kuin \(\tilde A\), joten tukipiste on siirtynyt myös kohti kärkeä \(\tilde B\) vaikka ei niin paljon kuin kohti painavinta kärkeä \(\tilde C\).

Tämän käyttäytymisen meille lupaavat fyysikot ja matemaatikot yhdessä.

Toisin kuin oikeassa maailmassa, voidaan ajatella myös kärkiä, jotka eivät paina yhtään mitään, jolloin niiden vaikutus painopisteeseen on 0.

Esimerkiksi kolmiossa painopiste \(\tilde q = \frac{1}{10} \tilde A + \frac{9}{10} \tilde B + 0 \tilde C\) vastaa edellisessä luvussa esiteltyä suoraviivaista siirtymää kahden kärkipisteen \(\tilde A\) ja \(\tilde B\) välillä, kun piste \(\tilde C\):n vaikutus on \(0\).

Sama temppu on mielekästä tehdä mille tahansa määrälle pisteitä.

Tällä kurssilla tutustutaan käyrien reittien ja muotojen mallintamiseen "kuutiomutkilla", jotka voidaan ajatella neljän kontrollipisteen \(\tilde P_1, \tilde P_2, \tilde P_3, \tilde P_4\) painotetuksi massakeskipisteeksi.

Mutkia matkaan saadaan, kun painojen suhdeluvut \(w_1(t), w_2(t), w_3(t), w_4(t)\) määritetään sopivalla tavalla matkaosuutta kuvaavan parametrin \(t \in [0,1]\) mukaisesti.

Loppupuolella kurssia käytetään kolmen pisteen painotettua summaa mallintamaan pisteen sijaintia kolmion sisäpisteissä.

Käyrän parametriesitys

Käyrän arkihavainto ja tavoitteet grafiikassa

Intuitiivisesti käyrä on jokin mahdollisesti kaareva reitti, jota pitkin voidaan ajatella liikutettavan pistettä avaruudessa.

Esimerkiksi käyrää pitkin voi liikkua kynän kärki, joka piirtää kyseisen käyrän paperiin.

Reaalimaailman esimerkki käyrästä on taivutettu rautalanka tai taipuisa mutka (englanniksi "spline"), jollaista pitkin piirrettiin kaarevien esineiden suunnittelupiirrustuksia ennen tietokoneaikaa.

Suorakin on ihan hyvä käyrä - se ei vain kaareudu mihinkään suuntaan.

Grafiikassa tyypillistä on laittaa animoitavat kappaleet, kamerat, valonlähteet ja muut oliot kulkemaan animaattorin määrittämiä käyriä reittejä pitkin.

Käyrillä voidaan mallintaa myös hahmojen asennot, nivelten väliset kulmat, värit ja muu visualisoitava informaatio ajan suhteen.

Mallinnettavien olioiden pinnanmuodot ovat usein kaarevia, jolloin nekin voidaan määritellä käyrien avulla.

Esimerkiksi animaatioelokuvien cameo-sankari "Utahin teepannu" on mallinnettu tietyllä tapaa toisiinsa yhdistettyjen, risteävien, käyrien avulla (ns. tensor Bezier patch -menettely).

Käyrän parametriesitys

Matemaattinen malli käyrälle on sisäisesti 1-ulotteinen olio.

Sillä on pituus ja muoto, mutta ei "paksuutta" mihinkään suuntaan eli leveyttä tai tilavuutta.

Animaatioiden ja pintojen mallintamiseksi grafiikassa mallinnetaan myös hetkellinen suunta ja "kallistus" käyrän kuvaamalla liikeradalla.

Käyrä voidaan ajatella alkavaksi yhdessä pisteessä ja loppuvaksi toisessa pisteessä.

Mikä tahansa piste käyrällä vastaa jonkin funktion arvoa, joka kuvaa käyrää pitkin kuljetun suhteellisen osuuden \(t \in [0,1] \subset \mathbb R\) pisteeksi avaruudessa, johon käyrä on upotettu.

Piste voidaan kuvata koordinaatteina.

Esimerkiksi 2-ulotteinen käyrä vastaa jotakin funktiota \(C':[0,1]\rightarrow \mathbb R^2\) ja 3-ulotteinen käyrä funktiota \(C:[0,1]\rightarrow \mathbb R^3\).

Koordinaattien funktiot ovat toisistaan erilliset, joten voidaan jakaa esimerkiksi 3-ulotteinen käyrä koordinaateittain funktioiksi \(C_x:[0,1]\rightarrow \mathbb R\), \(C_y:[0,1]\rightarrow \mathbb R\) ja \(C_z:[0,1]\rightarrow \mathbb R\).

Koordinaateittaiset funktiot voidaan kirjoittaa pystyvektoriksi tavalliseen tapaan:

\[ C(t)= \begin{bmatrix} C_x(t) \\ C_y(t) \\ C_z(t) \end{bmatrix}. \]

Alku- ja päätepiste voivat olla samat, jolloin käyrä muodostaa suljetun silmukan.

Esimerkiksi \(xy\)-tasolla makaava ympyrä on suljettu käyrä, jonka voidaan ajatella seuraavan trigonometrisia funktioita yksikköympyrällä, kun sisäkulma käy läpi arvot \([0,2\pi]\) ja pyörähdys aloitetaan positiiviselta \(x\)-akselilta yksikön päästä origosta.

Ympyrän säde \(r\) ja parametrisointi välille \(t \in [0,1]\) hoituvat kertolaskuilla:

\[ C(r,t)= \begin{bmatrix} C_x(r,t) \\ C_y(r,t) \\ C_z(r,t) \end{bmatrix} = \begin{bmatrix} r \cos (2 \pi t) \\ r \sin (2 \pi t) \\ 0 \end{bmatrix}. \]

Kurssimme Assignment 1 -tehtävässä on annettu \(xy\)-tason ympyrän toteutus mallina tietorakenteista ja yksityiskohdista, joita oletetaan noudatettavan omia käyräkoodeja tehtäessä.

Ympyrän mallikoodi on myös täysin valmis siihen, että sitä käytetään "rinkelipinnan" eli toruksen luomiseen tehtäväohjeessa kerrotuin menettelyin.

Kolmioiden indeksejä voi olla vaikea saada kohdalleen ilman pienten esimerkkiverkkojen käymistä läpi käsipelillä kynällä ja paperilla.

Polynomit ja mutkat

Polynomi on funktio, jossa on summattuna vakiokertoimilla kerrottuja yhden parametrin potensseja:

\[ p(t)=\sum_{i=0}^n a_i t^i. \]

Polynomin suurinta potenssia sanotaan sen asteluvuksi.

Polynomit vektoriavaruutena

Polynomeille \(p(t)=\sum_{i=0}^n a_i t^i\) ja \(q(x)=\sum_{i=0}^n b_i t^i\) ja vakiokertoimelle \(s \in \mathbb R\) voidaan määritellä suljettu summa ja skalaarikertolasku vastaavien vakiokertoimien summana ja skaalauksena:

\[ (p + q) (x) := \sum_{i=0}^n (a_i + b_i) t^i \] ja \[ (s p) (x) := \sum_{i=0}^n s a_i t^i. \]

Näillä määritelmillä \(n\)-asteiset polynomit ovat vektoriavaruus.

Matematiikan kursseilla lisää syvyyttä tähän ja muihin funktioavaruuksiin.

Hyväksytään nyt näppärä lopputulos, että polynomeille voidaan valita erilaisia kantoja ja vaihdella niiden välillä lineaarikuvauksilla, kuten millä tahansa vektoreiksi havaituilla olioilla.

Kuutiolliset polynomit

Tietokonegrafiikassa on tavallista mallintaa käyriä kolmannen asteen polynomeilla.

Toinen nimitys kolmannen asteen polynomille on kuutiollinen polynomi, koska korkein asteluku 3 liittyy myös kuution tilavuuteen.

Ne ovat yleisten polynomien vektoriavaruuden 4-ulotteinen aliavaruus.

Kuutiollinen polynomi voidaan aina kirjoittaa polynomien koulumatematiikasta tutussa "kanonisessa muodossa":

\[ p(t)=a_0 + a_1 t + a_2 t^2 + a_3 t^3. \]

Vektoriavaruudessa voidaan kirjoittaa sama matriisilaskuna

\[ p(t) = \begin{bmatrix}1 & t & t^2 & t^3 \end{bmatrix} \begin{bmatrix}a_0 \\ a_1 \\ a_2 \\ a_3 \end{bmatrix} \]

tai

\[ p(t) = \begin{bmatrix}a_0 & a_1 & a_2 & a_3 \end{bmatrix} \begin{bmatrix}1 \\ t \\ t^2 \\ t^3 \end{bmatrix}, \] jossa kertoimet ovat koordinaatteja ja polynomit \(T_0(t)=1\), \(T_1(t)=t\), \(T_2(t)=t^2\) ja \(T_3(t)=t^3\) ovat potenssikanta.

Tämä käy vektoriavaruuden kannaksi, koska sen alkiot ovat keskenään lineaarisesti riippumattomia ja niistä saadaan mikä tahansa kuutiollinen polynomi skaalattuna summana.

Kantanelikko voidaan kirjoittaa pystymatriisina samoin kuin avaruuden vektorikannat, \(\mathbf T(t) = [1\ t\ t^2\ t^3]^T\).

Mikä tahansa kuutiollinen polynomi saadaan koordinaattinelikon \(\mathbf a = [a_0\ a_1\ a_2\ a_3]^T\) ja potenssikannan matriisitulona \(\mathbf a^T \mathbf T(t)\) tai \(\mathbf T(t)^T \mathbf a\).

Kevään 2019 luennolla kokeiltiin potenssikannan polynomeja ja niiden lineaarikombinaatioita tällaisella aika näppärällä demonstraatiovehkeellä: https://www.desmos.com/calculator

Bernsteinin kanta

Venäläinen matemaatikko Sergei Natanovich Bernstein tutki funktioiden ja approksimoinnin teoriaa 1900-luvun alkupuolella.

Hän käytti kaavaa, jolla mihin tahansa \(n\)-ulotteiseen polynomiavaruuteen muodostuu kantavektorit tietyillä grafiikkaankin soveltuvilla ominaisuuksilla.

Nykyään rakennelma on hänen mukaansa nimetty, Bernsteinin kanta.

Kuutiollisten polynomien avaruudelle Bernsteinin kantavektorit ovat \[ \begin{align} B_1(t) &= ( 1-t)^3, \\ B_2(t) &= 3t(1-t)^2, \\ B_3(t) &= 3t^2(1-t), \\ B_4(t) &= t^3. \end{align} \]

Kirjoitetaan Bernsteinin kantavektorit pystymatriisiksi \(\mathbf B (t)\), ja todetaan saman tien, että ne saadaan lineaarikuvauksella eli kannanvaihdolla yksinkertaisesta potenssikannasta:

\[ \begin{bmatrix} B_1(t) \\ B_2(t) \\ B_3(t) \\ B_4(t) \end{bmatrix} = \begin{bmatrix} ( 1-t)^3 \\ 3t(1-t)^2 \\ 3t^2(1-t) \\ t^3 \end{bmatrix} = \ldots = \begin{bmatrix} 1 & -3 & 3 & -1 \\ 0 & 3 & -6 & 3 \\ 0 & 0 & 3 & -3 \\ 0 & 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} 1 \\ t \\ t^2 \\ t^3 \end{bmatrix} \]

Se on kiva juttu lineaarialgebrassa.

Kolme pistettä on kohta, jonka tarkkaavainen lukija täydentää itse.

Siinähän pitäisi laskea potenssit auki ja kerätä \(t\):n potenssien kertoimet, että voi uskoa matriisin sisällön oikeaksi.

Bernsteinin kanta painofunktioina

Bernsteinin kantapolynomeilla on monta mukavaa ominaisuutta.

Muun muassa välillä \(t \in [0,1]\) jokainen Bernsteinin kantapolynomi on ei-negatiivinen, ja polynomien summa on kaikilla \(t\):n arvoilla 1.

Ne ovat siis "ykkösen ositus" (englanniksi "partition of unity").

Tästä johtuen Bernsteinin kantapolynomien arvoja voidaan käyttää painoina pisteiden painopisteen laskemisessa.

Painot myös muuttuvat \(t\):n parametrina sopivasti pisteiden approksimointia ajatellen.

Välin \([0,1]\) alussa, kun \(t=0\), vain \(B_1(0)=1\) vaikuttaa. Lopussa, kun \(t=1\), vain \(B_4(1)=1\) vaikuttaa.

Paino \(B_1\) laskee "kuutiollisesti" välillä \([0,1]\). \(B_4\) nousee kuutiollisesti.

\(B_2\) ja \(B_3\) antavat välillä nousevan ja laskevan väliaikaisen painon, kumpikin vuorollaan.

Painot muuttuvat symmetrisesti välin keskipisteen \(t=0.5\) suhteen.

Bernsteinin kantapolynomit on hyvä hahmotella kuvaksi, josta ominaisuudet näkyvät.

MIT:n kalvosarjassa tämä on tehty kuutiollisille polynomeille.

Wikipediassa on valmiiksi piirreltynä muitakin Bernsteinin kantoja.

Itse kannattaa kuitenkin aina lopulta piirtää tärkeimmät kuvansa - joko kynällä tai jollain sopivalla softalla.

Bezier-käyrät

Tietokonegrafiikan perusteiden historia vie ranskalaisten autovalmistajien suunnitteluosastoille ja matematiikkaa tuntevien insinöörien piirrustuspöydille.

Pierre Étienne Bézier toimi insinöörinä Renault'lla ja teki 1960-luvulla tunnetuksi Bernsteinin kantapolynomeihin perustuvan tavan mallintaa käyriä ja kaarevia pintoja.

Siitä alkaen suunnittelu- ja mallinnusohjelmistoissa on vakio-ominaisuutena mahdollisuus piirtää "Bezier-käyriä".

Paul de Casteljeau oli kuitenkin käyttänyt samoja käyriä autojen suunnitteluun Citroënillä jo aiemmin.

Hän kehitti vuonna 1959 käyrän osittamiseen tai pisteittäiseen piirtämiseen sopivan metodin, joka tunnetaan hänen nimellään "de Casteljaun algoritmina".

Kuutiolliset Bezier-käyrät näyttäytyvät mallintajalle pätkinä, joissa kontrollipisteet yhdistyvät toisiinsa sellaista reittiä pitkin, johon voi vaikuttaa kahdella lisäkontrollipistellä.

Teknisesti ottaen jokaisella Bezier-käyrän pätkällä parametri \(t\in [0,1]\) määrittää Bernsteinin kantafunktioiden kautta painopisteen neljän kontrollipisteen välille.

Bernsteinin kantafunktioiden ominaisuuksista seuraa, että pätkän päätepisteet interpoloituvat täysin ja välillä olevat 2 kontrollipistettä approksimoituvat pienemmillä painoilla.

Käyrän suunta kunkin pätkän päätepisteessä määräytyy ensimmäisen kontrollipisteen ja edellisen pätkän viimeisen kontrollipisteen mukaisesti.

Sileän käyrän saa pakottamalla pätkän päätepisteiden välittömät naapurikontrollipisteet samalle suoralle tai jopa samalle etäisyydelle toisistaan.

Terävän kulmapisteen puolestaan saa, kun laittaa naapurikontrollit pois samalta suoralta.

Lineaarialgebran ihanuutta on, että Bezier-mutka voidaan kirjoittaa Bernsteinin kantafunktioiden painottamana kontrollipisteiden massakeskipisteenä matriisikertolaskuna:

\[ \begin{bmatrix} P_x(t) \\ P_y(t) \\ P_z(t) \\ P_w(t) \end{bmatrix} = G B \mathbf T (t) = \begin{bmatrix} P_{x,1} & P_{x,2} & P_{x,3} & P_{x,4}\\ P_{y,1} & P_{y,2} & P_{y,3} & P_{y,4}\\ P_{z,1} & P_{z,2} & P_{z,3} & P_{z,4}\\ P_{w,1} & P_{w,2} & P_{w,3} & P_{w,4} \end{bmatrix} \begin{bmatrix} 1 & -3 & 3 & -1 \\ 0 & 3 & -6 & 3 \\ 0 & 0 & 3 & -3 \\ 0 & 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} 1 \\ t \\ t^2 \\ t^3 \end{bmatrix}, \]

missä \(G\) on geometriamatriisi, jossa on pystyvektoreina koordinaatit painotettavista kontrollipisteistä \(\tilde P_1\), \(\tilde P_2\), \(\tilde P_3\) ja \(\tilde P_4\).

Kannanvaihtomatriisille on annettu nimi \(B\).

Geometriamatriisin ominaisuuksia

Matriisissa \(G\) on oltava niin monta saraketta kuin approksimoivassa funktioavaruudessa on kantafunktioita.

Kuutiollisille Bezier-käyrille siis \(G\) on \(n \times 4\) -matriisi.

Riveillä voi olla mikä tahansa määrä approksimoitavia suureita.

Yhdelläkin rivillä voi approksimoida esimerkiksi teatterin esiripun korkeutta ajan suhteen: \[ \begin{bmatrix} A_{1} & A_{2} & A_{3} & A_{4} \end{bmatrix} \begin{bmatrix} 1 & -3 & 3 & -1 \\ 0 & 3 & -6 & 3 \\ 0 & 0 & 3 & -3 \\ 0 & 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} 1 \\ t \\ t^2 \\ t^3 \end{bmatrix}. \]

2-ulotteiselle käyrälle riittäisivät 2-ulotteiset kontrollipisteet: \[ \begin{bmatrix} P_{x,1} & P_{x,2} & P_{x,3} & P_{x,4}\\ P_{y,1} & P_{y,2} & P_{y,3} & P_{y,4} \end{bmatrix} \begin{bmatrix} 1 & -3 & 3 & -1 \\ 0 & 3 & -6 & 3 \\ 0 & 0 & 3 & -3 \\ 0 & 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} 1 \\ t \\ t^2 \\ t^3 \end{bmatrix}. \]

Toisaalta on mahdollista käyttää kaikkeen samaa \(4 \times 4\) -matriisien kertolaskua, jos merkitään pisteiden käyrälasku homogeenisilla koordinaateilla.

Ainahan on mahdollista merkitä 2-ulotteisille pisteille \(z=0\), ja homogeeninen koordinaatti voidaan aina merkitä \(w=1\), kun on kyse pisteistä.

Matriisilasku on assosiatiivinen, joten käyrän kaikkien pisteiden \(\tilde p (t)\) affiini muunnos \(M\) jossakin kehyksessä \(\mathbf{\vec f}\) voidaan tehdä laskemalla matriisilasku geometrialle \(G\), jolloin osio \(B \textbf T(t)\) ei tarvitse muunnosta:

\[ \begin{align} M \begin{bmatrix} P_x(t) \\ P_y(t) \\ P_z(t) \\ P_w(t) \end{bmatrix} & = M \left( \begin{bmatrix} P_{x,1} & P_{x,2} & P_{x,3} & P_{x,4}\\ P_{y,1} & P_{y,2} & P_{y,3} & P_{y,4}\\ P_{z,1} & P_{z,2} & P_{z,3} & P_{z,4}\\ P_{w,1} & P_{w,2} & P_{w,3} & P_{w,4} \end{bmatrix} \begin{bmatrix} 1 & -3 & 3 & -1 \\ 0 & 3 & -6 & 3 \\ 0 & 0 & 3 & -3 \\ 0 & 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} 1 \\ t \\ t^2 \\ t^3 \end{bmatrix} \right) \\ & = \left( M \begin{bmatrix} P_{x,1} & P_{x,2} & P_{x,3} & P_{x,4}\\ P_{y,1} & P_{y,2} & P_{y,3} & P_{y,4}\\ P_{z,1} & P_{z,2} & P_{z,3} & P_{z,4}\\ P_{w,1} & P_{w,2} & P_{w,3} & P_{w,4} \end{bmatrix} \right) \begin{bmatrix} 1 & -3 & 3 & -1 \\ 0 & 3 & -6 & 3 \\ 0 & 0 & 3 & -3 \\ 0 & 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} 1 \\ t \\ t^2 \\ t^3 \end{bmatrix} \end{align} \]

Toki koordinaatit ovat aina jonkin kehyksen \(\mathbf{\vec f}\) mukaiset, joten käyrä muuntuu kehyksen mukana normaalisti: \[ \mathbf{\vec f}^T (M G B \mathbf T (t)) = (\mathbf{\vec f}^T M) (G B \mathbf T (t)). \]

Painottaminen homogeenisilla koordinaateilla

Jos jokaisen kontrollipisteen homogeeninen koordinaatti \(P_{w,i}=1\), niin liukulukujen tarkkuuden puitteissa myös tulokseen jää \(P_w(t)=1\).

Sehän vain summaa Bernsteinin kantapolynomit, joiden ominaisuutena on ykkösen jakaminen eli summautuminen arvoon 1.

Jos kuitenkin kontrollipisteiden \(w\)-koordinaatit ovat muuta kuin \(1\), niin silloin tehdään eri painotus Bernsteinin kantaan eli "venytetään" sen akseleita koordinaatin \(w\) laskemisessa.

Vaikutus ei näy käyrän muissa koordinaateissa \([P_x(t)\ P_y(t)\ P_z(t)]^T\) ennen kuin ne homogenoidaan eli jaetaan kaikki koordinaatit \(w\)-koordinaatilla.

Homogenoinnin tuloksessa jälleen \(w=1\), mutta muiden koordinaattien arvot riippuvat siitä, mikä \(w\) oli ennen homogenointia.

Huomaa, että homogenoinnissa tehdään jakolasku, joten suhdeluku \(w<1\) kasvattaa ja \(w>1\) pienentää muita koordinaatteja.

Tämä liittyy homogeenisten koordinaattien projektio-ominaisuuksiin, joista katsottiin kevään 2019 luennolla hieman alustavaa kuvaa Wikipediasta (kohdasta "homogeneous coordinates").

Assignment 1 -tehtävässä riittää tehdä tavalliset, painottamattomat käyrät.

Jos haluat lisätehtävänä toteuttaa painotetut, niin lisää niille omanlaisensa tiedostoformaatti, jotta alkuperäiset esimerkkitiedostot kuitenkin toimivat yhä sellaisenaan. Eli kuten yleensä, niin ei rikota rajapintaa, kun laajennetaan sitä!

Homogenointiin palataan viimeistään ennen kameran simuloimista, koska siinä tarvitsee muodostaa perspektiiviprojektio, joka on homogeenisten koordinaattien sisäänrakennettu ominaisuus.

Tällä tavoin painottamalla saadaan suhteellinen Bezier-käyrä ("rational Bezier curve"), jolla on enemmän ilmaisuvoimaa kuin .

TODO: Käyrän derivaatat, Frenet'n kehys

TODO: B-splinet, kannanvaihdot, jne. ks. MIT:n kalvosarja

TODO: vaiheessa, ehkä joskus -osio;

TODO: saahan nähdä, ehtiikö kirjoitella polynomeista ja splineistä enemmän. Kalvosarjat sinänsä OK, vaikka aika rumat.

"Toinen mielipide", l. Veskun Matriisit ja 3D -luento

"Kolmas mielipide" ja hyödyllisen näköistä lisälukemistoa kaikille yliopistolaisille: Matikkapakki

Kaikki tähän asti pisteistä ja suunnista todettu pätee euklidisessa avaruudessa.

Euklidisessa avaruudessa on kuitenkin määritelty myös kahden suunnan välinen kulma, jolloin voidaan ylipäätään puhua kohtisuoruuden käsitteestä.

Euklidinen avaruus voidaan samaistaa karteesisen koordinaatiston koordinaattiesityksiin.

Lineaarialgebran oppikirjoissa on tapana käyttää lähes ensimmäisenä esimerkkinä vektoriavaruudesta euklidista avaruutta.

Tällöin sanotaan, että karteesisen koordinaatiston koordinaattiesitys \(\mathbf x = (x_1, x_2, \ldots, x_n) \in \mathbb R^n\) on koordinaattivektori. Skalaarikunnaksi valitaan \(\mathbb R\). Kahden vektorin summaksi määritellään alkioittainen summa ja skalaarikertolaskuksi alkioittainen tulo skalaarin kanssa.

Euklidisen avaruuden niin sanottu standardikanta ovat karteesisen koordinaatiston suuntavektorit.

Kahdelle vektorille \(x,y \in \mathbb R^n\) määritellään myös pistetulo \[ \mathbf x \cdot \mathbf y = \sum_{i=0}^n x_i y_i. \] eli kahden alkion koordinaattien tulojen summa.

Pistetulo on grafiikassa tärkeä, koska sen avulla lasketaan projektiot, vektorien väliset kulmat, kohtisuoruudet, säteiden leilkkaukset ja ties mitä! TODO: Tämän paikka on kuitenkin jossain muualla kuin tässä, missä vielä esitellään peruskäsitteitä...(?) Sinne samaan paikkaan sitten ristitulo ja muuta mitä tarvii.

(TODO...)

TODO (jonakin vuonna): Euklidinen avaruus tiettyihin kantanuoliin kiinnitettyinä koordinaatteina, karteesinen koordinaatisto työkaluna euk avaruuteen. polynomiavaruus

Voi olla, että 2019 mennään jenkkikalvoilla.

sisätuloavaruuden kannasta jotain?

Sanotaan, että kanta on ortonormaali, kun sen vektorit ovat keskenään kohtisuorassa ja mittakaavayksikön mittaisia.

Tämä tietystikin vain silloin, kun meillä on sellainen avaruus, jossa kohtisuoruus merkitsee jotakin selkeää.

Yleisesti ottaen kannan ei tarvitse olla ortogonaalinen, eikä normaali: yhtä hyvin voidaan valita keskenään viistossa olevat kantavektorit, joiden pituudet ovat muuta kuin \(1\) mittayksikkö.

Geometrian esittäminen

Matemaattisia esitystapoja

Piste, jana, monikulmio (erityisesti kolmio).

Suora, taso, leikkaukset.

Käyriä, pintoja.

Polynomiapproksimaatiot, splinet

Tietokone ja diskreetit esitysmuodot

Murtoviivat, kolmioverkot

Mallit ja näkymät

Sijainnit

Näkymägraafi

Kamera, projektio

Materiaalit, valo, heijastuminen

Säteenheitto ja -seuranta

Englanti-suomi -sanastoa ja etymologiaa

Tässä on vähän aloitettu termikäännöksiä englannista suomeksi.

TODO: more, more, more, ...

1D = 1-ulotteinen. Esimerkiksi suora tai käyrän sisäinen parametriesitys.

2D = 2-ulotteinen. Esimerkiksi tasainen tai kaareva pinta.

3D = 3-ulotteinen. Arkihavainto maailmasta. Voi olla suoran ja tason tapaan upoksissa useampiulotteisessa avaruudessa, kuten homogeenisen koordinaatiston pisteet.

3-space = 3-ulotteinen avaruus, "3D-avaruus". En ole kuullut käytettävän sanaa "kolmiavaruus", joka olisi kyllä nätimpi suomennos kuin 3D-avaruus. Google löytää itse asiassa yli 10 suomenkielistä kurssimateriaalia tai vastaavaa, joissa puhutaan kolmiavaruudesta. Tästä voi tulla oma suosikkisuomennokseni.

approximation = approksimointi eli likimääräisen ratkaisun määrittäminen. Esimerkiksi mitattujen pisteiden väliin sovitettu jatkuva käyrä tai pinta.

basis = kanta.

basis function = kantafunktio. Kantavektori avaruudessa, jonka vektorit ovat funktioita, esimerkiksi polynomeja.

basis vector = kantavektori.

continuous = jatkuva. Asia, joka ei sisällä yllättäviä, äärettömän nopeita hyppäyksiä. Eräs opettajani kuvasi asian kerran niin hyvin, että jaan sen eteenpäin: "Käyrä on jatkuva, jos sen voi piirtää nostamatta kynää paperista". Samoin funktio on jatkuva, jos sen kuvaajan \(y=f(x)\) voi piirtää \(xy\)-tasolle nostamatta kynää paperista. Matemaattinen määritelmä käydään läpi matematiikan kursseilla. Topologia on matematiikan ala, joka tutkii jatkuvuuden olemusta ja sovelluksia. Matemaattinen analyysi käsittelee asiaa funktioiden ja niiden muutosnopeuksien (derivaattojen) sekä "kertymien" (integraalien) suhteen.

coordinate = koordinaatti. Yksi lukuarvo pisteen sijainnin koordinaattiesityksessä. Grafiikassa yhden kantavektorin kerroin.

coordinate system = koordinaatisto. Tapa, jolla voi määrittää sijainteja ja/tai suuntia lukuarvoilla. Tällä kurssilla lineaariavaruuden kantavektorien määrittämä eli suoraviivainen. Yleisesti ottaen voi olla käyräviivainen, esim. pituus- ja leveyspiirit.

coordinate vector = koordinaattivektori. Kaikkien koordinaattien järjestetty kokoelma.

cross product = ristitulo.

cubic = kuutiollinen. Kuutioon liittyvä. Esimerkiksi kuutiollinen polynomi sisältää termin \(x^3\), mikä on sellaisen kuution tilavuus, jonka sivun pituus on \(x\). "Kuutiollinen" ilmaisee ilmiön isoimman ulottuvuuden. Neliulotteisen hyperkuution tilavuutta \(x^4\) ei voi ilmentää kuutiollisella polynomilla.

curvature = kaareutuminen, kaarevuus.

curve = käyrä.

derivative = derivaatta. Sana suoraan suomennettuna on "johdannainen", "johdettu". Kiitos kevään 2019 opiskelijalle, joka linkitti artikkelin, jossa tämän kummallisen "johdettu funktio" -nimen käyttöönotosta vieritellään syytä sinänsä ansioituneelle matemaatikolle Joseph-Luis Lagrangelle.

differential = "erotuksellinen". Adjektiivina: asia, joka liittyy eroon esimerkiksi hetken ja seuraavan hetken välillä, esimerkiksi nopeus paikkaa kuvaavan funktion derivaattana tai mäen jyrkkyys pisteestä A pisteeseen B siirryttäessä. Subjektiivina: "differentiaali", matemaattinen menettely edellä mainitun käyttäytymisen mallintamiseen.

dot product = pistetulo.

face = tahko (geometriassa). Monikulmion muotoinen osa kappaleen pinnasta.

frame = kehys eli paikallinen koordinaatisto.

Frenet frame = Frenet'n kehys, eli paikallinen koordinaatisto joka viittaa erityisesti liikkuvan kohteen sijaintiin ja suuntautumiseen avaruudessa.

frustum = kahden tason väliinsä leikkaama osuus geometrisesta muodosta, "katkaistu muoto"; grafiikassa lähi- ja kaukotasojen väliin jäävä "katkaistu näkymäpyramidi"

homogeneous coordinate = homogeeninen koordinaatti.

inner product = sisätulo.

line = suora.

linear = "suoraviivainen".

linear combination = lineaarikombinaatio. Skaalattujen vektorien summa.

linear map = lineaarikuvaus.

linear space = lineaariavaruus eli vektoriavaruus.

local coordinate system = paikallinen koordinaatisto eli kehys (grafiikassa).

matrix = matriisi.

mesh = verkko. Grafiikassa ja CAD-mallinnuksessa monikulmioista tai muista elementeistä koostuva malli 3D-kappaleelle.

non-uniform = "epätasainen(?)", epätasavälinen(?). Viittaa NURBS-käyrän nimessä sanoihin "non-uniform" eli siihen, että parametrin \(t\) kulku käyrän joissain ikkunoissa voi olla mallintajan valinnan mukaan "nopeampi" tai "hitaampi" kuin toisissa. NURBSissa voi olla eri mittaisia "solmuja" ("knot"), joista osa voi olla 0, mikä vastaa kontrollipisteen monistamista tämän kurssin Assignment 1:n vaaditussa perustoteutuksessa.

normal = normaali. Adjektiivina tarkoittaa standardin mittatikun mittaista vektoria eli sellaista, jonka pituus on tasan 1 yksikköä. Substantiivina grafiikassa tarkoittaa (1) suuntaa, joka osoittaa pinnasta ulospäin tai (2) suuntaa, joka osoittaa käyrässä sisäänpäin kaarevuuteen nähden.

normalized = normalisoitu. Asia, joka on tehty jollain tapaa "normaaliksi". Karteesisessa koordinaatistossa vektori, jonka pistetulo itsensä kanssa on 1, vastaten euklidista pituutta 1 mittayksikkö.

optimisation (ameriikassa) optimization (briteissä) = optimointi. Asioidentilan parantaminen; matemaattisesti funktion minimi- tai maksimikohdan eli ääriarvon etsiminen; tarpeen monissa edistyneemmissä grafiikka-algoritmeissa kuten LOD:ssä, IK:ssa jne. Myös: koodin optimointi eli tietorakenteiden ja algoritmien asettelu niin, että suorituskyky paranee.

orientation = suuntautuminen. Grafiikassa tarkoittaa asemointia, johon kappaleen tai kameran suunta, kallistus ja kierto on aseteltu suhteessa ympäröivään maailmaan. Suuntautuminen tai "suuntaus" on eri kuin sijaintipaikka. Vastaa kehyksen kantavektoreita, riippumatta kehyksen origon sijainnista.

origin = origo. Piste, joka täytyy kiinnittää koordinaatiston luomiseksi. Etymologisesti "lähde" (jos muistan oikein, latinasta, Googleta varuilta itsekin).

orthogonal = kohtisuora. Euklidisen eli antiikin kreikan ajoilta periytyvän geometriamallin mukaisesti ajateltu erityinen suhde kahden suunnan välillä avaruudessa - sellainen, jossa muodostuu täsmälleen sama kulma molemmille puolille kahden suoran leikkauspistettä. Nykyisessä abstraktissa matematiikassa määritelty tilanteeksi, jossa sisätuloavaruuden vektorien välinen sisätulo on 0. Esimerkiksi euklidisen avaruuden karteesisessa koordinaatistossa koordinaattivektorit \(\mathbf a\) ja \(\mathbf b\) ovat kohtisuoria, kun \(\mathbf a^T \mathbf b = 0\).

orthonormal = ortonormaali. Yhtä aikaa kohtisuora ja normaali. Esimerkiksi ortonormaali kanta tai muunnos.

plane = pinta. Kaksiulotteinen avaruus.

point = piste. Sijaintipaikka avaruudessa, joko 3D-maailmassa tai matemaatikon luomassa abstraktissa avaruudessa.

polynomial = polynomi.

quadratic = neliöllinen eli "kvadraattinen". Neliöön liittyvä. Esimerkiksi neliöllinen polynomi sisältää termin \(x^2\), mikä on sellaisen neliön pinta-ala, jonka sivun pituus on \(x\). "Neliöllinen" viittaa isoimpaan ulottuvuuteen käsiteltävässä asiassa. Kolmiulotteisen kuution tilavuutta \(x^3\) ei voi ilmentää neliöllisellä polynomilla.

raster = rasteri. Grafiikassa pienistä neliskulmaisista kuvaelementeistä eli pikseleistä muodostuva kuva tai näyttölaite.

rasterization = rasterointi. Kuvanmuodostusmenetelmä, jossa määritetään suoraan 2-ulotteiseen rasterikuvaan ne pisteet, joiden alueelle kuvio (esimerkiksi kolmio) tulee piirtää. Edellyttää perspektiiviprojektion tekemistä ja näkyvien pintojen määrittämistä esimerkiksi etäisyyspuskurin avulla.

rational = ositettu, suhdelukuna ilmaistu. Esimerkiksi lukua \(\frac{3}{4}\) sanotaan rationaaliluvuksi, koska se mallintaa neljään osaan jakamista ja kolmen murto-osan ottamista. Grafiikassa homogeenisten koordinaattien neljännellä koordinaatilla \(w\) voidaan painottaa pisteitä painotetun summan laskennassa, kun lopuksi homogenoidaan. Esimerkiksi NURBS-käyrän nimessä kirjain "R" viittaa sanaan "rational", mikä tarkoittaa suhteellisten koordinaattien käyttämistä käyrän määrittelevässä laskentakaavassa.

ray = säde. "Puolisuora", jolla lähtee jostakin pisteestä ja jatkuu suoraviivaisesti äärettömiin.

ray casting = säteenheitto. Kuvanmuodostusmenetelmä, jossa lähetetään katselusäteitä kameran polttopisteestä kohti näkymää.

ray tracing = säteenseuranta. Kuvanmuodostusmenetelmä, jossa heitettyä sädettä seurataan rekursiivisesti peiliheijastussuuntaan, taittumissuuntaan läpinäkyvän kappaleen sisään ja mahdollisesti muihin suuntiin esim. Monte Carlo -näytteistyksellä.

rendering = kuvan muodostaminen. Puhekielessä helposti "renderöinti", mutta vältetään virallisissa yhteyksissä anglismeja!

smoothness = sileys.

spline = "mutka", yleisemmin anglismina "spline-käyrä" tai puhekielessä "splaini". Englanninkielisen Wikipedia-sivun mukaan sanaa on käytetty 1800-luvulta alkaen pitkien, ohuiden ja taipuisien "päreiden" nimenä. Matematiikassa vakiintunut tarkoittamaan sileää approksimaatiokäyrää. Yksi esimerkki ovat Bernsteinin polynomit ja B-splinet. Älkäämme suomentako B-mutkaksi vaan ihan voidaan puhua "biisplainista". Harvoja sanoja, joilla ei ole oikeampaa suomennosta!

tangent = tangentti. Käyrän tai pinnan pisteittäinen ominaisuus, joka kuvaa hetkellistä liikenopeutta. Newtonin lakien mukaan esineet kulkevat "tangentin suuntaan", jos niihin ei vaikuta mikään voima.

tangent plane = tangenttitaso. Määrittyy pinnan pisteittäisenä ominaisuutena, kun määritetään kaksi erisuuntaista tangenttia.

unit = yksikkö. Substantiivina: mittayksikkö johonkin mittaustarkoitukseen. Myös: lukumäärä tai skalaari arvoltaan 1. Adjektiivina: tasan yhden yksikön mittainen.

unit vector = yksikkövektori. Vektori, jonka pituus on 1. Edellyttää etäisyyden käsitteen määrittelyä ja mittakaavan kiinnittämistä - grafiikassa käytännössä karteesista koordinaatistoa. Euklidisen avaruuden koordinaattivektoreille \(||\mathbf a|| = \sqrt{\mathbf a^T \mathbf a} = 1\), kun \(\mathbf a\) on yksikkövektori. Mikä tahansa \(\vec v\) saadaan yksikkövektoriksi laskemalla \(\frac{\vec v}{||\vec v||}\), jos pituus on määritelty käsite mallinnettavassa avaruudessa.

vector = vektori. Etymologisesti "kantaja", "suoraviivainen reitti". Kuormitettu sana voi tarkoittaa asiayhteydestä riippuen jotakin seuraavista:

  • Abstraktin lineaariavaruuden alkio, esimerkiksi polynomi, euklidisen avaruuden \(\mathbb R^{17}\) piste tai muuta villimpää. Käyttäytyy tällöin aina kuten vektori, eli skaalautuu, summautuu suljetusti ja muuntuu lineaarikuvauksella säilyttäen avaruuden suoraviivaisen rakenteen.
  • Siirtymä 3D-avaruudessa kahden pisteen välillä.
  • Suunta 3D-avaruudessa, esimerkiksi kappaleen orientaatio, pinnan ulkonormaali, käyrän tangentti tai hiukkasen nopeus.
  • Insinöörimatematiikassa ja laskentaohjelmistoissa liukuluvuista koostuva taulukko.
  • C++:n standardi taulukkorakenne mille tahansa alkiotyypille.
  • Paljon muuta, grafiikkaan liittymätöntä, esim. "hyökkäysvektori".

vector space = vektoriavaruus eli lineaariavaruus.

velocity = nopeus. Esimerkiksi mallinnetun kappaleen hetkellinen nopeus animaatiossa.

vertex = kärkipiste / kärki. Suomeksi kommunikoidessa muista sanoa "kärkipiste", älä käytä anglismia "verteksi".

view frustum = katkaistu näkymäpyramidi eli z-puskuroidussa rasteroinnissa käytetty lähi- ja kaukotasojen väliin jäävä osuus neliskanttisesta pyramidista, joka avautuu neulansilmäkameran silmästä näkymän katselusuuntaa kohti.

Derivaatta-sanasta… Dosentti Matti Lehtinen sivuaa sanan etymologiaa tässä artikkelissa: https://matematiikkalehtisolmu.fi/2009/1/derivaatta.pdf. Toinen Lehtisen artikkeli, jossa asiaa käsitellään (eikä oikeastaan tuoda mitään uutta): https://matematiikkalehtisolmu.fi/1998/2/lehtinen/.

26 Feb 19

These are the current permissions for this document; please modify if needed. You can always modify these permissions from the manage page.