Matrisestakk
Transformasjoner
Matrise
Børre Stenseth
Matematikk>3D transf.

Romtransformasjoner

Hva
Applet failed to run. No Java plug-in was found.
Grunnleggende forklaring av romtransformasjoner, matriseoperasjoner og matrisestakking

Denne modulen behandler i hovedsak samme tema som modulen: 2D transf., men har som basis et koordinatsystem med tre akser.

Det er lurt å enes om n måte å tegne koordinatsystemet på. I dette materialet er alle resonnementer i rommet gjennomført i et høyrehåndssystem.

righthand Det vil si at dersom jeg legger den høyre hånda loddrett ned, som i karate, med fingrene langs den positive x-aksen, og krummer hånda mot y-aksen, vil tommelen peke opp langs den positive z-aksen.

Vi bruker homogene koordinater fra starten av. Det vil si at den generelle transformasjonsmatrisen er en 4x4 matrise, og den generelle vektorformen er en kolonnevektor med fire rader.

P2=M·P1
|x2|   |m11 m12 m13 m14|   |x1|
|y2|   |m21 m22 m23 m24|   |y1|
|z2| = |m31 m32 m33 m34| * |z1|
|1 |   |m41 m42 m43 m44|   |1 |

Translasjon

|1 0 0 tx|
|0 1 0 ty|
|0 0 1 tz|
|0 0 0 1 |

En translasjon i rommet er beskrevet ved tx, ty og tz. Vi ser lett at denne matrisen realiserer ligningene:

	x2=x1+tx
	y2=y1+ty
	z2=z1+tz

Skalering

|sx 0 0 0|
|0 sy 0 0|
|0 0 sz 0|
|0 0  0 1|

Skalering i rommet er beskrevet ved sx, sy og sz. Vi ser at denne matrisen realiserer følgende ligninger:

	x2=x1·sx
	y2=y1·sy
	z2=z1·sz

Rotasjon

Rotasjon er litt mer komplisert. Vi definerer tre ulike basisrotasjoner, en om hver av aksene.

axes

Om Z-aksen
|cos(v) -sin(v)  0   0|
|sin(v)  cos(v)  0   0|
|0         0     1   0|
|0         0     0   1|
Om X-aksen
|1    0        0    0|
|0  cos(v)  -sin(v) 0|
|0  sin(v)  cos(v)  0|
|0    0       0     1|
Om Y-aksen
|cos(v)  0  sin(v)  0|
|   0    1    0     0|
|-sin(v) 0  cos(v)  0|
|   0    0    0     1|

Geometri

Identitetsmatrisa

|1 0 0 0|
|0 1 0 0|
|0 0 1 0|
|0 0 0 1|

Igjen kan vi tolke den som:

  • skalering med 1 langs alle akser
  • rotasjon med 0, om alle akser
  • translasjon med 0 i alle akseretninger

Speiling

|1 0 0  0|
|0 1 0  0|
|0 0 -1 0|
|0 0 0  1|

Vi kan speile om de ulike planene ved å bruke skaleringsfaktor -1 på aksen som står normalt på planet. Merk spesielt matrisen til venstre. Den speiler om xy-planet, og endrer derved koordinatene fra et høyrehåndssystem til et venstrehåndssystem

Projeksjon

|1 0 0 0|
|0 1 0 0|
|0 0 0 0|
|0 0 0 1|
Vi har så langt kun konsentrert oss om å flytte rundt på punkter i planet og rommet. Vi skal senere bekymre oss for hvordan vi kan avbilde romfigurer på et plan. Det kan være nyttig å merke seg allerede nå at vi kan gjøre også dette ved hjelp av en matriseoperasjon. Vi kan projisere et punkt ortogonalt ned i et av hovedplanene ved å anvende en matrise som skalerer aksen normalt på planet med 0. Matrisen til venstre er en parallellprojeksjon ned i xy-planet.

Sammensatte operasjoner

De samme resonnementene vi førte i planet kan overføres til rommet. Igjen benytter vi oss av at vi kan lage sammensatte transformasjonsmatriser som representerer sammensatte geometriske transformasjoner.

I planet er situasjonen ganske oversiktlig og vi kan lett følge operasjonene grafisk. I rommet blir det fort komplisert, spesielt når vi roterer. En ganske krevende øvelse som ofte gjengis i grafisk litteratur er rotasjon om en vilkårlig akse. Vi drar ikke dette resonnementet her. Det er sjelden vi får bruk for å konstruere såpass kompliserte transformasjoner i hodet når vi programmerer. Som regel kan vi slippe unna med enklere løsninger dersom vi treffer noen fornuftige valg i beskrivelsen av de objektene vi vil framstille.

La oss ta et enkelt eksempel på rotasjon om en akse parallell til en av hovedaksene. Vi ønsker å rotere klossen på figuren 90 grader om en akse som går gjennom P og er loddrett på xy-planet. Klossen har sidekanter på 1. Etter operasjonen bør punktet Q (2,4,4) havne i Q2(1,3,4), og P(2,3,4) bør havne uforandret i P2(2,3,4).

figur1

Med vår kunnskap om transformasjoner må det være en god strategi å:

  1. flytte punktet P inn til z-aksen, matrisen T1
  2. rotere om z-aksen, matrisen R
  3. flytte klossen tilbake, matrisen T2

Vi husker fra kapittelet om 2D-transformasjoner at vi anvender matrisene i motsatt rekkefølge og multipliserer fra venstre. Vi lager altså matrisen M=T2·R·T1, og kan finne Q'=M·Q og P'=M·P.

  |1 0 0 2| |0 -1 0 0| |1 0 0 -2| |0 -1 0 5|
M=|0 1 0 3|*|1  0 0 0|*|0 1 0 -3|=|1 0  0 1|
  |0 0 1 0| |0  0 1 0| |0 0 1  0| |0 0  1 0|
  |0 0 0 1| |0  0 0 1| |0 0 0  1| |0 0  0 1|


       |0 -1 0 5| |2| |1|
Q2=M*Q=|1 0  0 1|*|4|=|3|
       |0 0  1 0| |4| |4|
       |0 0  0 1| |1| |1|


       |0 -1 0 5| |2| |2|
P2=M*P=|1 0  0 1|*|3|=|3|
       |0 0  1 0| |4| |4|
       |0 0  0 1| |1| |1|

Figuren eller koordinatsystemet
For å gjenta kort: Resonnementet ovenfor er basert på følgende:

Vi holdt fast i ideen om å flytte figuren. Rekkefølgen på matrisene er omvendt av den geometrisk logiske rekkefølgen, av grunner som vi drøftet tidligere for planoperasjoner.


Vi kan velge et annet resonnement som på en måte passer bedre til logikken med rekkefølgen av operasjoner. Det går som følger:

  1. Vi flytter origo ut til rotasjonsaksen, T2
  2. Vi roterer, R
  3. Vi flytter origo tilbake, T1

Med dette resonnementet blir rekkefølgen M=T2·R·T1 kanskje mer logisk.

I OpenGL

De aktuelle funksjonene i OpenGL:

  glLoadIdentity()
  glTanslatef(tx,ty,tz)
  glRotatef(v,x,y,z)
  glScalef(sx,sy,sz)
  

Merk at f-en i funksjonsnavnene angir at parametrene er i flytetall. Det finnes også heltallsvarianter av funksjonene. Merk videre at glRotate spesifiserer både rotasjonsvinkel (i grader) og rotasjonsakse. En rotasjon med 30 grader mot klokka om z-aksen blir således:

  glRotatef(30.0f,0.0f,0.0f,1.0f)
  

I tillegg til dette har OpenGL noen funksjoner som setter oss i stand til å manipulere transformasjonsmatrisene direkte.

  glLoadMatrixd(...)
  

lar oss sette matrisa direkte og

   glMultMatrixd(...)

lar oss multiplisere med en egendefinert matrise. Merk OpenGLs homogenisering av resultatet, se modulen Homogenisering

Vi kan også få tak i gjeldende matrise med den generelle glGetFloatv() funksjonen, f.eks. slik

  glGetFloatv(GL_MODELVIEW_MATRIX,..)

Rader og kolonner

Igjen har vi valget om vi vil skrive operasjonene som P2=M·P, med P og P2 som kolonnevektorer eller P2=P·M, med P og P2 som radvektorer.

Dersom vi velger den siste varianten blir de respektive basismatrisene:

Translasjon
|1   0  0 0|
|0   1  0 0|
|0   0  1 0|
|tx ty tz 1|
Skalering
|sx 0 0  0|
|0 sy 0  0|
|0  0 sz 0|
|0  0 0  1 |
Rotasjon om z-aksen
|cos  sin 0  0|
|-sin cos 0  0|
|0    0   1  0|
|0    0   0  1|
Rotasjon om x-aksen
|1  0    0   0|
|0 cos  sin  0|
|0 -sin cos  0|
|0  0    0   1|
Rotasjon om y-aksen
|cos  0  -sin 0|
|0    1  0    0|
|sin  0  cos  0|
|0    0   0   1|

En god del grafisk litteratur beskriver transformasjoner på denne måte. Se også transponering av matriser i modulen: Homogenisering.

Referanser

Dette stoffet er beskrevet i alle lærebøker i grafisk databehandling, se f.eks. Hearn kap 5, Foley kap 5 eller Hill kap 5.
Se også generelle matematikkbøker om lineær algebra.

Vedlikehold
Oppdatert juni 2002, Børre Stenseth
(Velkommen) Matematikk>3D transf. (Homogenisering)