OpenGL/Kamera maailmaa pyörittää

Muun muassa:

  • glTranslate
  • glRotate
  • yaw, pitch ja roll


Yaw, pitch ja roll matriisiksi muokkaa

Lentokoneiden yhteydessä käytetään suureita yaw, pitch ja roll. Ne ovat ehkä havainnollisin tapa ilmaista suunta numeroin. Joskus niitä kutsutaan hieman virheellisesti Eulerin kulmiksi. Yaw on kompassin suuntima eli kulma, joka ilmoittaa nokan suunnan kartalla. Pitch ilmaisee nousu/laskukulman. Roll tarkoittaa kiertoa rungon suuntaisen akselin ympäri.

Oletetaan, että xz-taso esittää maanpintaa. Yaw kiertää esinettä y-akselin, pitch uuden x-akselin ja roll uuden z-akselin ympäri. Tehdään siis kolme peräkkäistä glRotate-muunnosta oikeassa järjestyksessä:

glRotatef(roll, 0.0, 0.0, 1.0);
glRotatef(pitch, 1.0, 0.0, 0.0);
glRotatef(yaw, 0.0, 1.0, 0.0); // yaw suoritetaan ensin

Kameran tapauksessa kierrot tehdään luonnollisesti päinvastaiseen suuntaan:

glRotatef(-roll, 0.0, 0.0, 1.0);
glRotatef(-pitch, 1.0, 0.0, 0.0);
glRotatef(-yaw, 0.0, 1.0, 0.0);

Yllä ei ole menty yksityiskohtiin – mikä on nollakulma ja kiertääkö kulma myötä- ja vastapäivään?

Muita tapoja esittää kiertoa muokkaa

Ironisesti yaw, pitch ja roll ei sovi lentosimulaattoreihin. Kun lentokone lentää pystysuoraan ylöspäin, yaw tekee tismalleen samaa kuin roll. Ongelmaa kutsutaan nimellä gimbal lock. Yksi ratkaisu on säilyttää kierto matriisina: se toimii, mutta liukulukujen epätarkkuus aiheuttaa ongelmia. Parasta on käyttää kvaternioja (engl. quaternion) esittämään kiertoa. Niiden käytöstä kerrotaan kirjan toisen osan luvussa Kvaternio.

Yaw, pitch ja roll riittävät fysiikan mallinnukseen, jos kappaleilla ei ole pyörimisnopeutta. Ne riittävät myös ihmishahmon (tai ”kameramiehen”) silmin kuvattuihin tietokonepeleihin.

Kulmista muokkaa

Usein kulmat halutaan pitää välillä [0, 360[. Vaikka miinusmerkkisen liukuluvun jakojäännös vaikuttaa oudolta ajatukselta, se toimii halutulla tavalla:

kulma = kulma % 360.0;

C-kielen matemaatiikkakirjasto käyttää radiaaneja, OpenGL asteita. Koska 180° = π rad, muuntaminen käy yksinkertaisten vakioiden avulla.

const double pii = acos(-1.0);
const double asteet_radiaaneiksi = pii / 180.0;
const double radiaanit_asteiksi = 180.0 / pii;

Huomautuksia muokkaa

  • Pitäisi kokeilla, onko kolme glRotate-käskyä hitaampaa kuin matriisin muodostaminen käsin.
  • Steve Baker kertoo tarkemmin yaw, pitch ja roll -esitysmuodon ongelmasta kirjoituksessaan Euler angles are evil.