Slagskygge
Plan
Grafikk
Børre Stenseth
Matematikk>Plan

Plan

Plan

Det er slik at dersom vi kjenner to vektorer som danner en vinkel forskjellig fra 0 eller 180 grader med hverandre i et plan så er planet entydig bestemt. Det betyr at dersom vi kjenner tre punkter som ikke ligger på linje så er planet entydig bestemt. Og normalen til planet er bestemt av kryssproduktet til de to vektorene.

plan1

Den generelle formen for et plan er

Ax+By+Cz+D=0 

der vektoren |A B C| er normalen til planet. Vi drar ikke bevis eller utledninger eller nærmere begrunnelse for dette. Merk at normalen beregnes etter høyrehåndsregelen. Dette er viktig når vi skal oppgi normaler i OpenGL. Siden OpenGL skiller mellom forside og bakside på flater, er det viktig at vi oppgir normaler på en systematisk måte. D kan finnes ved innsetting av et punkt i planet i den generelle planligningen.

Minner om definisjonen av kryssproduktet:

    AXB=(a2b3-a3b2, a3b1-a1b3, a1b2-a2b1)
    

La oss eksemplifisere:

Eksempel 1.

plan2

Anta P1 =(0,0,0), P2=(2,0,0) og P3=(0,3,0)

      N=P1P2 X P1P3= [2,0,0] X [0,3,0] 
= [0·0-0·3 , 0·0-2·0 , 2·3-0·0]
= [0,0,6]

Planet:

6z+D=0.

Substituerer for P1, og får 0+D=0, som gir D=0.

Planligningen blir 6z=0, eller like godt z=0.

Eksempel 2.

plan3

Anta P1 =(0,1,0), P2=(1,0,0) og P3=(0,0,1)

N=P1P3 X P1P2= [0,-1,1] X [1,-1,0]
       = [-1·0-1·(-1),1·1-0·0
      ,0·(-1)-(-1)·1]
= [1,1,1]

Planet: x+y+z+D=0.

Setter inn for P1, og får 1+D=0, som gir D=-1.

Planligningen blir x+y+z-1=0

Plan og linje

Vi vil forsøke å løse det generelle problemet med å finne skjæring mellom en linje gjennom punktene O og Q og et plan som er beskrevet med punktene P1, P2 og P3. Vi tar for gitt at P1, P2 og P3 ikke ligger på linje, slik at vi kan være sikre på at de tre punktene bestemmer et plan.

plan4

Vi forutsetter i fortsetningen at vi har funnet planligninga slik som vist ovenfor:

    Ax+By+Cz+D=0
    

Vi kan relatere problemet til den problemstillingen som melder seg dersom vi skal beregne slagskygge. Tilsvarende analyse er nyttig for å forstå raytracing. Vi tenker oss at O er posisjonen til en lyskilde og Q er hjørnet på en flate som skal kaste skygge på planet. For enkelthets skyld tenker vi oss at lyskilden er plassert i origo, dvs. O er origo. Vi taper ikke noe generalitet i dette siden vi vet at vi kan transformere til et vilkårlig origo.

Linja fra origo gjennom Q kan vi beskrive parametrisk slik:

    P(t)=t·Q
    

eller for hver komponent:

    x(t)=t·Qx
    y(t)=t·Qy
    z(t)=t·Qz
    

Problemet vårt reduseres til å finne ut for hvilken t-verdi linja skjærer planet. Vi setter inn i planligninga og får:

    A·t·Qx+B·t·Qy+C·t·Qz+D=0
    

Løst med hensyn på t:

    t=-D/(A·Qx+B·Qy+C·Qz)
    

Vi finner linjas skjæring med planet uttrykt med Q og plankoeffisientene.

   x=-D·Qx/(A·Qx+B·Qy+C·Qz)

   y=-D·Qy/(A·Qx+B·Qy+C·Qz)

   z=-D·Qz/(A·Qx+B·Qy+C·Qz)

   

Merk at planligninga ikke sier oss noe om planets utstrekning. Vi har derfor ikke informasjon i uttrykket ovenfor som kan si oss om skjæringspunktet faller innenfor et avgrenset polygon i planet.

Vi har imidlertid informasjon om hvordan punktet Q ligger i forhold til planet. Planet ligger lenger fra origo en Q bare dersom t >1.

Vi ser litt nærmere på uttrykket ovenfor. Det hadde vært ønskelig å kunne uttrykke sammenhengen mellom skjæringspunktet og Q i matriseform. Dersom vi får til det, kan vi ha følgende tegnestrategi for uttegning av et polygon og dets slagskygge på et plan:

   // tegn polygonet
   DrawPolygon(p)
   <sett opp en transformasjonsmatrise basert på ligninga for planet >
   // tegn slagskyggen
   DrawPolygon(p)
   

Spørsmålet blir da hvordan transformasjonsmatrisa skal se ut. Den skal realisere sammenhengen mellom Q og skjæringspunktet, S, mellom linja fra origo gjennom Q og planet.

Sammenhengen ovenfor kan uttrykkes slik i matriseform:

           |-D 0  0  0| |Qx| |-DQx        |
   S=M*Q=  |0  -D 0  0|*|Qy|=|-DQy        |
           |0  0  -D 0| |Qz| |-DQz        |
           |A  B  C  0| |1 | |AQx+BQy+CQz |
   

For at dette skal bli riktig må vi forutsette at resultatvektoren homogeniseres, dvs. at de tre første koordinatene divideres med den siste. Se modulen Homogenisering. I OpenGL er det slik og vi kan realisere en tegnestrategi som skissert ovenfor.

   DrawPolygon(p)
   float m[]={...}
   glPushMatrix()
   glMultMatrix(m)
   DrawPolygon(p)
   glPopMatrix()
   

Slagskygge er videre behandlet i modulen Slagskygge.

Klippeplan i OpenGL

OpenGL gir oss en mulighet for å sette opp (midlertidige) klippeplan under uttegning av en figur. Hvis vi f.eks. ønsker å tegne ut en halvkule, kan vi sette opp et klippeplan som deler en hel kule og tegne ut den hele kula.

Oppsetting av et klippeplan gjøres ved funksjonen:

   glClipPlane(GL_CLIP_PLANEi,koeffisienter som beskriver planet);
   

Konstanten GL_CLIP_PLANEi sier oss at vi skal bruke klippeplan i. i er et tall i området [0..n] som holder styr på de i alt n+1 mulige klippeplanene. n skal være minst 5 i en OpenGL-implementasjon.

Koeffisientene som beskriver planet er A,B,C,D slik vi har beskrevet plan ovenfor.

Et eksempel på uttegning av en halvkule:

// set up clip plane
double clip_plane1[]={0.0,0.0,-1.0,0.5};
gl.glClipPlane(GL_CLIP_PLANE1,clip_plane1);
gl.glEnable(GL_CLIP_PLANE1);
// draw sphere
long qd=glu.gluNewQuadric();
glu.gluSphere(qd,3.0f,20,20);
glu.gluDeleteQuadric(qd);
gl.glDisable(GL_CLIP_PLANE1);
   
halvkule

Merk at de individuelle klippeplanene må/kan skrus av og på.

[1]
Demoprogram(JOGL/Netbeans): https://svnit.hiof.no/svn/psource/JOGL/clipplane1
Påskeegg, er et av flere eksempler som benytter klippeplan.
Referanser
  1. The OpenGL Programming Guide, 6 editionDave Schreiner, Mason Woo,Jackie Neider,Tom Davies2007Addison-Wesley Professional0321481003www.opengl.org/documentation/red_book/14-03-2010
Vedlikehold
Revidert april 2003, Børre Stenseth
Matematikk>Plan
til toppen