eli minulla sdl+opengl ohjelma. käytän hiirtä kameran kääntämiseen tyyliin
int mx,my,mxOld,myOld; mxOld=mx; myOld=my; SDL_GetMouseState(&mx,&my); if(mx>mxOld||mx==SCREEN_W-1) xangle += 0.01; if(mx<mxOld||mx==0) xangle -= 0.01;
ohjelma toimii muuten hyvin mutta sitten jonkin ajan kuluttua ohjelma kaatuu ihan yhtäkkiä.
eli mistä tämä johtuu? ja miten sen voi korjata
Auttaiskohan jos pitäis mx:n välillä [0;360] tähän tyyliin:
if (mx > 360) mx -= 360; if (mx < 0) mx += 360;
Zach kirjoitti:
Auttaiskohan jos pitäis mx:n välillä [0;360] tähän tyyliin:
if (mx > 360) mx -= 360; if (mx < 0) mx += 360;
Kannattaa käyttää radiaanit. Kaikki trigonometriset funktiot käyttävät niitä.
aWW kirjoitti:
Kannattaa käyttää radiaanit. Kaikki trigonometriset funktiot käyttävät niitä.
OpenGL vaatii kuitenkin asteita, eli kameran suunnalle kannattaa käyttää siihen tarkoitukseen niitä. Tietenkin omia laskelmia tehdessä radiaanejakin tarvitaan. Siksipä joskus on hyvä pitää yllä sekä rad- että deg-arvoja, ja kun toinen muuttuu, niin toinen lasketaan uudestaan.
Jakojäännös lienee fiksumpi idea kuin nuo if
:t... jos mx
on vaikka 1080 ja miinustat siitä 360, se on silti 720 joka on yli 360. Eli:
mx %= 360;
Tämä kaiken lisäksi muuttaa 360 astetta nollaksi, joka lienee fiksua?
Ja ehkä vielä anglex tuon mx:n tilalla, sehän ilmeisesti sen kulman säilyttää...
1) Jakojäännös ei toimi liukuluvuilla. Valitan.
2) Koska luku ei kerralla kuitenkaan nouse yli 360 astetta, if
kelpaa hyvin (laitathan väliin vielä elsen :), ja vaikka nousisikin ("anglex += (mx-mxOld)*0.01"), while
auttaa.
Erittäin luotettava nopeustestipajani (heh) kertoo, että seuraavista (kokonaisluvuilla toimivista) koodeista while on nopeampi:
a = (8 * b) + 1; a = a % b;
a = (8 * b) + 1; while (a >= b) a -= b;
Eli jos a on alle 9-kertainen, while voittaa, ja vielä pienempi luku luonnollisesti nopeuttaa sen toimintaa. Liukuluvuilla while on "merkittävästi" eli pikkuisen hitaampi, mutta muita vaihtoehtoja ei taida olla.
Koko kamerankääntösysteemi vielä toisella tavalla:
SDL_GetMouseState(&mx, &my); xangle = ((2.0 * mx) / (SCREEN_W-1)) - 1.0); // -1.0 .. 1.0, hiiren sijainnin mukaan xangle *= max_kulma;
Metabolix kirjoitti:
1) Jakojäännös ei toimi liukuluvuilla. Valitan.
Jopas on tyhmä rajoitus. Onneksi en pahemmin käytä C:tä enää mihinkään... Mutta ainakin minä näen tuossa koodissa kokonaisluvun int mx
.
Ja väitän, että tuo nopeus riippuu aika paljon koneesta. Mutta kuitenkin nopeusero lienee sen verran pieni, ettei sillä hirveästi väliä ole. Kirjoittaa while
- tai vaikka for
-loopin tai jakojäännöksen, kumpi sitten itselle näyttää selkeämmältä.
Deewiant kirjoitti:
Mutta ainakin minä näen tuossa koodissa kokonaisluvun
int mx
.
En nyt kyllä näkisi, että sitä jakojäännöstä tarvittaisiin hiiren koordinaatteihin. float(?) anglex tossa tarvii pitää rajoissa.
Zach kirjoitti:
Deewiant kirjoitti:
Mutta ainakin minä näen tuossa koodissa kokonaisluvun
int mx
.En nyt kyllä näkisi, että sitä jakojäännöstä tarvittaisiin hiiren koordinaatteihin. float(?) anglex tossa tarvii pitää rajoissa.
Jep. Mäki kattelin että eikös se ennemmin se täytyis pitää?
Eli sitten vaikka
if(xangle>360)xangle-=360; if(xangle<0)xangle+=360;
tai jotenkin noin.
Deewiant: Jos et omaa funkkaria osaa tehdä niin kannattaisi opetella kieli paremmin.
Deewiant kirjoitti:
Ja väitän, että tuo nopeus riippuu aika paljon koneesta.
Tietenkin, mutta nopeuksien suhde on todennäköisesti suunnilleen sama, ja sehän tässä ratkaisee. Kyllä se on jo aika vakiintunutta kykoneilla, kauanko tietty operaatio vie, ja tunnetusti jakolaskut ovat hitaampia.
Megant kirjoitti:
Deewiant: Jos et omaa funkkaria osaa tehdä niin kannattaisi opetella kieli paremmin.
Huono flame.
C:ssä tai C++:ssa ei voi ylikuormittaa operaattoreita perustyypeille, joten en voi mitenkään kirjoittaa "0.5 % 0.5
" ja saada sitä toimimaan. Tottakai voin tehdä oman funktion ja sitten kirjoittaa tyyliin "floatModulo(0.5, 0.5)
", tai jopa määrittää jonkin turhan luokan ja käyttää sitä tyyliin "Modulo(0.5) % Modulo(0.5)
". Mutta miksi tehdä niin? Turhaa ajantuhlausta se vain olisi:
Ensinnäkin ihan ANSI-C:n math.h
:ssa on määritelty fmod()-funkkari, joka hoitaa homman todennäköisesti piljoona kertaa nopeammin ja fiksummin kuin mikään itsekyhäämäni.
Toiseksikin löytyy kieli, jossa on sisäänrakennettu liukulukujakojäännös ja josta kaiken lisäksi pidän enemmän (jos jotakuta kiinnostaa, kieli on D).
Aihe on jo aika vanha, joten et voi enää vastata siihen.