Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Fatal signal (SDL)

Sivun loppuun

ByteMan [11.12.2007 00:29:22]

#

mistä ihmeestä johtuu virheilmoitus

Fatal signal: Floating Point Exception (SDL Parachute Deployed)

??
kaikki pisteet ja pilkut ja osoittimet olen tarkistanut(mielestäni..) moneen kertaan, mutta en silti keksi missä ongelma on..
varsinainen pikselin piirtofunktion löysin täältä putkasta.. ja se toimikin kunnes yritin piirtää ympyröitä enkä täysiä ruudullisia..

#include <math.h>
#include <SDL/SDL.h>

void PiirraPikseli(SDL_Surface *naytto, int x, int y, Uint8 R, Uint8 G, Uint8 B);

int main(int argc, char *argv[])    {

    if(SDL_Init(SDL_INIT_VIDEO) < 0)    {

	return 0;
    }

    SDL_Surface *naytto;
    naytto = SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE);

//********************************************

    int x;
    int y;

double vari=0.0;
int piirto=0;
    for(x = 0; x < 640; x++)    {
        for(y = 0; y < 480; y++)    {

	    vari=( 6 / (300 - x) ^ 2  +  ( 250 - y ) ^ 2 );

	    if(vari>1) { vari=1; }

	    if(vari<0.15) { vari=0.0; }

	    vari=((vari)*255);

	    piirto=(int)(vari);

	    if(piirto>255) { piirto=255; }

	    PiirraPikseli(naytto, x, y, 255, 2, piirto);
        }
    }
    SDL_Flip(naytto);

    SDL_Delay(5000);
    SDL_FreeSurface(naytto);
    SDL_Quit();
    return 0;
}



void PiirraPikseli(SDL_Surface *naytto, int x, int y, Uint8 R, Uint8 G, Uint8 B)    {
    Uint32 color = SDL_MapRGB(naytto->format, R, G, B);
        {
            Uint32 *bufp;
            bufp = (Uint32 *)naytto->pixels + y*naytto->pitch/4 + x;
            *bufp = color;
        }


}

eli tällanen on sitten koodi, joka on kyseisen ongelman takana.

Deffi [11.12.2007 06:24:07]

#

vari=( 6 / (300 - x) ^ 2  +  ( 250 - y ) ^ 2 );

Kun x on 300, yrität jakaa nollalla ja tähänhän ei tietokone suostu.

hunajavohveli [11.12.2007 10:46:14]

#

Olet muuten varmaan tarkoittanut potenssia merkillä ^. C:ssä ^ on kuitenkin xor-operaattori. Potenssia varten löytyy math.h:sta pow()-funktio, jota käytetään siis: potenssi = pow(kantaluku, eksponentti);. Kun kyseessä on kokonaislukueksponentti, voi olla kuitenkin järkevämpää tehdä tuo ihan tavallisella kertolaskulla. Tosin kääntäjä varmaan optimoi pow():n automaattisesti sellaiseksi.

ByteMan [11.12.2007 16:41:18]

#

aarrgghh... mä luulin et tohon ei voi enää langeta.. :D

hunajavohveli : kieli onkin c++ eikä c, siispä "^"<-tuon pitäisi ihan potenssimerkki olla

no anywayz.. ihan mukavasti ohjelma kuitenki jumittaa, vaikka ei nollalla yrittäiskään jakaa..
missäköhän lienee vika..


edit: ei jumita enää, mutta luulin että ohjelma piirtää ympyröitä jollain väriliu'ulla eikä yksivärisiä viivoja..
tästä sit vaa, ehkä niistä vielä joskus ympyröitäkin saadaan.. :D

Megant [11.12.2007 16:52:13]

#

ByteMan kirjoitti:

kieli onkin c++ eikä c, siispä "^"<-tuon pitäisi ihan potenssimerkki olla

No eikä ole, vaan se xor.

Heikki [11.12.2007 16:52:28]

#

ByteMan kirjoitti:

hunajavohveli : kieli onkin c++ eikä c, siispä "^"<-tuon pitäisi ihan potenssimerkki olla

^ on xor-operaattori sekä C:ssä että C++:ssa. Esimerkki:

heikki@heikki-laptop:~/temp$ cat test.cpp
#include <iostream>

int main() {
	int foo;
	foo=3^2;   // 3^2=9?
	std::cout << foo << "\n";
	return 0;
}
heikki@heikki-laptop:~/temp$ g++ test.cpp -o test
heikki@heikki-laptop:~/temp$ ./test
1

Edit: Hidas :(

ByteMan [11.12.2007 17:05:05]

#

no hyvä on, olkoot sitten xor.. mutta ei toi ohjelma perus kertolaskullakaan toimi

hunajavohveli [11.12.2007 17:10:15]

#

vari=( 6 / (300 - x) ^ 2  +  ( 250 - y ) ^ 2 );

Jäipä äsken huomaamatta, että tuossa myös jaat kuutosen ensimmäisellä termillä. Mahdoitko tarkoittaa näin:

vari= 6 / ((300 - x) * (300 - x) + (250 - y) * (250 - y));

Edit: Tuo ei sitten ota nollalla jakoa huomioon. Sen voi joko tarkistaa manuaalisesti tai sitten lisätä jakajaan jonkin pienen vakion.

Metabolix [11.12.2007 21:02:05]

#

Voi olla selkeämpää ja tehokkaampaa käyttää toisen potenssin laskemiseen vaikkapa pientä apufunktiota. Järkevä ratkaisu voisi olla suunnilleen tällainen:

template <typename T>
inline T pow2(T t) {
	return t * t;
}

vari = a / (pow2(x - x0) + pow2(y - y0) + 0.001);

ByteMan [12.12.2007 00:55:55]

#

mahtavaa.. en tajua templateista tai inlinestä yhtään mitään.. =/
kuitenkin, korjailin noita vähän, ja nyt ohjelma jää jumiin, jos yrittää piirtää
640*480 kokoiselle alueelle. lisäksi ympyrän muoto loistaa poissaoloaan..
epätoivoissani lisäsin sinne vielä toimituksen, joka änkee lasketut arvot ensin
taulukkoon ja tulostaa sitten sieltä..
eipä sekään toiminut että sen puoleen.. =(
ja mitä en ole näköjään huomannu sanoo nii yritän metapalloi koodata.
huonolla menestyksellä, jos ette sitä itse huomanneet..

edit

#include <math.h>
#include <SDL/SDL.h>

void PiirraPikseli(SDL_Surface *naytto, int x, int y, Uint8 R, Uint8 G, Uint8 B);

int main(int argc, char *argv[])    {

    if(SDL_Init(SDL_INIT_VIDEO) < 0)    {

	return 0;
    }

    SDL_Surface *naytto;
    naytto = SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE);

//********************************************

    int x;
    int y;

double vari=0.0;
int piirto=0;
int taulukko[639][479];


    for(x = 0; x < 400; x++)    {
        for(y = 0; y < 400; y++)    {
	    //pallot[i].R / ((pallot[i].X - x) ^ 2 + (pallot[i].Y - y) ^ 2)
	    //alkuperäinen kaava..
            //yritän siis piirtää ympyrää pisteeseen (x,y)=(300,250)


	    vari=( 100 / ( ((300 - x)*(300 - x)) + ((250 - y)*(250-y)) + 0.1));

	    if(vari>1) { vari=1; }

	    if(vari<0.01) { vari=0.0; }

	    vari=((vari)*255);

	    piirto=(int)(vari);

	    if(piirto>255) { piirto=255; }
	    taulukko[x][y]=piirto;

	    //PiirraPikseli(naytto, x, y, 2, 2, piirto);
        }
    }

    for(x=0; x<400; x++){
	for(y=0; y<400; y++){
	    PiirraPikseli(naytto, x, y, 2, 2, taulukko[x][y]);
        }
    }

    SDL_Flip(naytto);

    SDL_Delay(5000);
    SDL_FreeSurface(naytto);
    SDL_Quit();
    return 0;
}



void PiirraPikseli(SDL_Surface *naytto, int x, int y, Uint8 R, Uint8 G, Uint8 B)    {
    Uint32 color = SDL_MapRGB(naytto->format, R, G, B);
        {
            Uint32 *bufp;
            bufp = (Uint32 *)naytto->pixels + y*naytto->pitch/4 + x;
            *bufp = color;
        }


}

Tzaeru [12.12.2007 01:30:46]

#

Väsyneenä jaksa perehtyä liikaa koodiin, mutta.. Jos ihmettelet, miksi se jumittaa kun kooksi tulee 640x480, niin oisko syy se, että "int taulukko[639][479];"-taulukkoon ei ihan noin paljoa dataa mahdu - isoin kuva olisi se 639x479.. ;)

Taulukon kokoa määritellessä numerointi menee tyyliin 1...loputon, eihän koko voi olla nolla. Sen sijaan tiettyyn alkioon viitatessa numerointi vaihtuu nollasta loputtomaan (0...loputon) - ehkäpä siksi, että kun viitataan alkioon 0, voidaan luontevasti lähteä suoraan muuttujan alusta. Kun viitataan ykköseen, lisätään taulukon koko ja kokeillaan siitä kohtaa muistia jne jne. En nyt oikeasti tiedä miten se toimii, mutta mutuna heittelen.

Joka tapauksessa. Alustuksessa 1 - loputon, alkioon viitatessa 0 - (loputon-1).

Minulle ainakin jää myös epäselväksi missä vaiheessa oikein yrität piirtää sen ympyrän.. Ympyrän saa helpoiten tyyliin x0 = sin(x1), y0 = cos(y1). Näin yksinkertaistaen.

ByteMan [14.12.2007 00:08:01]

#

ongelma ilmeneekin lähinnä jos yrittää piirtää taulukko, joka on paljoa suurempi kuin tuo toivotun pallon keskipiste
->eli siis arvolla x<301 ja y<251 homma toimii, mutta arvoilla x<400 ja y<300 homma jumittaa.. hämärää..

EDIT:
w00t se toimii, sain ympyränkin mukaan :D
se vain näyttää aika erikoiselta..
vika oli, kun olin imeisesti epähuomiossa poistanut yhden muuttujan vain siitä koodista jonka kopion tuonne yläpuolelle aiemmin. muuttujaa siis ei enää alustettu, mutta jos x>300 niin kys. muuttujan arvoa muutettiin..

en ole vieläkään aivan varma, missä se ympyrä lasketaan, mutta veikkaan sen olevan tuo väriarvojen laskemiskohta. se kun on miltei suoraan saatu tuolta opas-osiosta
löytyvästä metapallo-oppaasta.

edit2:: ainii, se toimii vain melkein, ympyrällä ei ole toiveitakaan päästä liikkumaan vielä toviin, puhumattakaan toisen ympyrän mukaan tulosta...
tästä on hyvä jatkaa :D


Sivun alkuun

Vastaus

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

Tietoa sivustosta