Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: SDL-kysymyksiä

Sivun loppuun

Shark90 [05.01.2009 12:24:39]

#

On ollut pitkä tauko ohjelmoinnista ja on unohtanut kaikenlaista, niin jattelin tulla tänne kysymään muutamaa kysymystä.

Ensinnäkin olisi yksi ongelma tuon SDL:än, lisäkirjastojen ja C++ kanssa. Kääntäjä gcc.

Elikkäs esim. SDL:ssa on määritelty setpixel-funktio. Funktio käyttää noita SDL:än omia muuttujia muuttujinaan, ja niiden pitää olla kokonaislukuja, kuten myös int-muuttujien, joita käytetään itse ohjelman funktiossa.

Mikä ratkaisu ongelmaan, kun pitää käyttää desimaaleja muuttujien arvoina? Double muuttujan muuttaminen laskennan jälkeen int:ksi ei ole ratkaisu, koska tämä aiheuttaa epätarkkuutta.

Yritin vaihtaa SDL:n kirjastoista ne muuttujan doubleiksi, mutta silloin ei toimi...

No toinen harmaita hiuksia aiheuttaa kysymys koskee yksinkertasta autopelin ohjelmointia. Siis ihan mustalle taustalle piirrettäisiin auto SDL:n avulla, ja löysin hyvän funktion jolla saa auton kuvaa pyöritettyä keskipisteensä ympäri (rotozoomin kanssa touhuamalla).

Siis kiihtyvyyden, ja jonkun asteisen kitkan olen oppinut tekemään, mutta asiaa pitää lähestyä vähän eri tavalla ilmeisesti...

Elikkäs auton piäisi edetä aina siihen suuntaan mihin keula osoittaa. Miten tämän toteuttaa? Eli siis jos auto aluksi on täysin oikealle, niin painamalla auton ollesa vauhdissa vasemmalle, auton kuvaa kännettäisiin asteen vasemmalle, ja suunta muuttuisi myös nyt y-akselilla. Tähän jotain esimerkkiä olisi kiva saada?

ville-v [05.01.2009 12:42:49]

#

Shark90 kirjoitti:

Elikkäs esim. SDL:ssa on määritelty setpixel-funktio. Funktio käyttää noita SDL:än omia muuttujia muuttujinaan, ja niiden pitää olla kokonaislukuja, kuten myös int-muuttujien, joita käytetään itse ohjelman funktiossa.

Mikä ratkaisu ongelmaan, kun pitää käyttää desimaaleja muuttujien arvoina? Double muuttujan muuttaminen laskennan jälkeen int:ksi ei ole ratkaisu, koska tämä aiheuttaa epätarkkuutta.

Jos sinulla on kaksi kaappia, ja laitat henkarin niiden väliin, henkari ei ole minkään kaapin sisällä. Kuva näkyy näytössä pikselin tarkkuudella.

Voit kyllä muuttaa pikselin väriä tai piirtää vaikka neljän vierekkäisen pikselin ryhmän, jolloin se näyttää olevan kahden pikselin välissä.

Tzaeru [05.01.2009 14:12:58]

#

Shark90 kirjoitti:

Elikkäs esim. SDL:ssa on määritelty setpixel-funktio. Funktio käyttää noita SDL:än omia muuttujia muuttujinaan, ja niiden pitää olla kokonaislukuja, kuten myös int-muuttujien, joita käytetään itse ohjelman funktiossa.

Mikä ratkaisu ongelmaan, kun pitää käyttää desimaaleja muuttujien arvoina? Double muuttujan muuttaminen laskennan jälkeen int:ksi ei ole ratkaisu, koska tämä aiheuttaa epätarkkuutta.

Epätarkkuutta voi vähän purkasti vähentää vaikka miinustamalla 0.5 luvusta ennen typecastausta intiksi, koska typecastaus intiksi pyöristää aina ylöspäin. Vähentämällä 0.5 takaa pyöristyksen lähimpään kokonaislukuun.

Toinen tapa on sitten luoda vähän järkevämpi illuusio useammasta pikselistä, vaikkapa blurrilla/pehmennyksellä/antialisoinnilla, miksi sitä nyt ikinä haluataankaan kutsua.

Shark90 kirjoitti:

Elikkäs auton piäisi edetä aina siihen suuntaan mihin keula osoittaa. Miten tämän toteuttaa? Eli siis jos auto aluksi on täysin oikealle, niin painamalla auton ollesa vauhdissa vasemmalle, auton kuvaa kännettäisiin asteen vasemmalle, ja suunta muuttuisi myös nyt y-akselilla. Tähän jotain esimerkkiä olisi kiva saada?

https://www.ohjelmointiputka.net/oppaat/opas.php?tunnus=mat3 on ehkä jännittävää luottavaa.

Jos auton nopeus on vaikka 50 km/h ja se kääntyy asteen vasemmalle olettaen, että täysin oikealle menevä suunta on 0 astetta, on y-akselin mukainen suunta sin(1)*nopeus, joka olisi ~0,87km/h ja vastaavasti x-akselin mukainen nopeus olisi cos(1)*nopeus, ts. 49,99.

Pythagoraan lauseella näkee että nopeus on todellakin 50 kilometriä tunnissa tuossa vaiheessa.

Yleisestikin trigonometria on oikein kätevää.

Metabolix [05.01.2009 14:41:37]

#

Tzaeru kirjoitti:

Epätarkkuutta voi vähän purkasti vähentää vaikka miinustamalla 0.5 luvusta ennen typecastausta intiksi, koska typecastaus intiksi pyöristää aina ylöspäin. Vähentämällä 0.5 takaa pyöristyksen lähimpään kokonaislukuun.

Ei. Typecast pyöristää aina pienempään, joten lukuun pitää lisätä puolikas. Mutta eivät ne pikselit tosiaan sillä kapeammiksi muutu, kuten jo mainittiinkin.

Edit. Tarkennuksena siis: "pienempi" viittaa itseisarvoltaan pienempään eli nollaa lähempänä olevaan, ja lisääminen koskee tietenkin vain ei-negatiivisia lukuja, joista tässä aiheessa luonnollisesti on kyse, kun pikselien paikat yleensä ilmaistaan sellaisilla.

TsaTsaTsaa [05.01.2009 14:50:08]

#

Metabolix kirjoitti:

Ei. Typecast pyöristää aina pienempään, joten lukuun pitää lisätä puolikas.

Ei. Typecast pyöristää aina nollaa kohti, joten positiiviseen lukuun pitää lisätä ja negatiivisesta vähentää puolikas.

Tzaeru [05.01.2009 14:56:54]

#

Metabolix kirjoitti:

Tzaeru kirjoitti:

Epätarkkuutta voi vähän purkasti vähentää vaikka miinustamalla 0.5 luvusta ennen typecastausta intiksi, koska typecastaus intiksi pyöristää aina ylöspäin. Vähentämällä 0.5 takaa pyöristyksen lähimpään kokonaislukuun.

Ei. Typecast pyöristää aina pienempään, joten lukuun pitää lisätä puolikas. Mutta eivät ne pikselit tosiaan sillä kapeammiksi muutu, kuten jo mainittiinkin.

:-o perin ovelasti muistelin taas omiani ja toki väärinpäin.

Toki tuo olikin se luonnollinen ja järkevä pyöristyssuunta.

Shark90 [05.01.2009 17:17:05]

#

Joo siis toi setpixel funktio oli vain esimerkki. Sama ongelma ihan normaalin bmp-kuvan piirron kanssa. Ja oikeastaan jokaisen SDL:n funktion kanssa, kuten lineRGBA:n.

Esim. tämä ei käänny https://www.ohjelmointiputka.net/koodivinkit/24061-c-pyörivä-3d-kuutio

Mutta muistaakseni sain muuten tuon kääntymään kun käytin gcc:tä, g++ sijasta... Mistä tämä johtuu?

Niin ja tuo pyöristäminen tulee oikeastaan ongelmaksi siinä vaiheessa, kun lisätään jokakerta loopissa esim. muuttujaa yhdellä, joka on aivan liikaa, pitäisi lisätä esim 0.1. Mutta muu loopin toiminta voi vaatia silti normaalilla nopeudella luuppaavaa silmukkaa, joten minkää delayn käyttö ei tulisi kysymykseen.

ville-v [05.01.2009 17:33:52]

#

Shark90 kirjoitti:

Mutta muistaakseni sain muuten tuon kääntymään kun käytin gcc:tä, g++ sijasta... Mistä tämä johtuu?

C:tä ei käännetä g++:lla.

Shark90 [05.01.2009 18:49:01]

#

ville-v kirjoitti:

Shark90 kirjoitti:

Mutta muistaakseni sain muuten tuon kääntymään kun käytin gcc:tä, g++ sijasta... Mistä tämä johtuu?

C:tä ei käännetä g++:lla.

Joo, tiedossa on. Tarkotin että c-kielen kääntäjällä onistuu kääntö *.c tiedostona, mutta g++:lla *.cpp tiedostona ei.

ville-v [05.01.2009 18:58:06]

#

Shark90 kirjoitti:

ville-v kirjoitti:

Shark90 kirjoitti:

Mutta muistaakseni sain muuten tuon kääntymään kun käytin gcc:tä, g++ sijasta... Mistä tämä johtuu?

C:tä ei käännetä g++:lla.

Joo, tiedossa on. Tarkotin että c-kielen kääntäjällä onistuu kääntö *.c tiedostona, mutta g++:lla *.cpp tiedostona ei.

Tiedostonimen vaihtaminen ei muuta kieltä, jolla ohjelma on koodattu. Jos C-koodi ei ole yhteensopiva C++:n kanssa, sitä pitää muokata.

Metabolix [06.01.2009 00:11:51]

#

Shark90 kirjoitti:

Niin ja tuo pyöristäminen tulee oikeastaan ongelmaksi siinä vaiheessa, kun lisätään jokakerta loopissa esim. muuttujaa yhdellä, joka on aivan liikaa, pitäisi lisätä esim 0.1.

Mikä nyt oli ongelmana, ettet voi käyttää laskennassa doublea ja pyöristää sitä piirtovaiheessa? Eihän pyöristyksen yhteydessä suinkaan tarvitse hukata alkuperäistä arvoa minnekään.

Shark90 [06.01.2009 13:33:49]

#

Jos loopissa on x+=0.1, ja sen pyöristää piirtoa varten, niin silloinhan se olisi sama asia kuin pistäisi x+=1.

Gaxx [06.01.2009 13:52:39]

#

Shark90 kirjoitti:

Jos loopissa on x+=0.1, ja sen pyöristää piirtoa varten, niin silloinhan se olisi sama asia kuin pistäisi x+=1.

ville-v kirjoitti:

Jos sinulla on kaksi kaappia, ja laitat henkarin niiden väliin, henkari ei ole minkään kaapin sisällä. ¨Kuva näkyy näytössä pikselin tarkkuudella.

Vaihtoehdoksi jää kymmenkertaistaa näytöntarkkuus, mutta se ei taida tulla kyseeseen tässä tapauksessa.

Metabolix [06.01.2009 15:53:44]

#

Shark90 kirjoitti:

Jos loopissa on x+=0.1, ja sen pyöristää piirtoa varten, niin silloinhan se olisi sama asia kuin pistäisi x+=1.

Eikä ole. Kun pyöristät sen vain piirtoa varten, tulee kuva aina kymmenen kertaa samaan kohti ja siirtyy vasta sitten yhden pikselin — eli tavallaan liikkuu hitaammin.

Voisit edes kokeilla asiaa, ennen kuin sanot noin ehdottomasti, ettei se toimi. Mikä seuraavassa koodissa sinusta menee pieleen?

#include <iostream>
#include <iomanip>
using namespace std;

int main() {
  double x;
  int piirto_x;
  for (x = 0; x < 2; x += 0.1) {
    piirto_x = (int) (x + 0.5);
    cout << "x: " << setw(3) << x << "; piirto_x: " << piirto_x << endl;
  }
  return 0;
}

Shark90 [07.01.2009 17:02:29]

#

Juu, oma virhe. Koodissa oli muutakin hämärää, mikä teki virheitä.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta