Welcome! Log In Create A New Profile

Advanced

Math Problems with NaN

Posted by g_man 
Math Problems with NaN
December 03, 2010 06:15AM
I have a problem in my game that I have been stumbling over for quite a while, but I just can't seem to figure it out. I'm getting a NaN value for reasons I can't seem to find. I made a program to send a bunch a variables to my computer, and I even stepped through the program, and no luck. I ended up with a real number.
Here is the code that does most of the computations. The function sendDataToAddress sends the string provided to my computer. Also, each time through the function the value functionNumber holds a value that increases each time that applyGravity is called. This is displayed on my results. Here it is:
void applyGravity(int pX,int pY, bullet *bullet,float G){
	
	#if DEBUG == 1
		char *debugPtr = (char *)malloc(500);	//Just to be sure
		static unsigned int functionNumber;
		functionNumber++;
		sprintf(debugPtr,"In The Begginning of %d\naccel: %f\naccelAng: %f\n",functionNumber,bullet->getAccel(),bullet->getAccelAng());
		sendDataToAddress(debugPtr,strlen(debugPtr));
		memset(debugPtr,'\0',500);	//Just to make sure everyting is 0
	#endif
	
	float accel, accelAng = 0;
	float oldAccel,oldAccelAng,newAccel,newAccelAng;
	//Find acceleration
	accel = (G)/(calcDistance(bullet->getX(),bullet->getY(),pX,pY)*calcDistance(bullet->getX(),bullet->getY(),pX,pY));
	
	while (bullet->getAccelAng()>2*M_PI) bullet->setAccelAng(bullet->getAccelAng()-2*M_PI);
	while (bullet->getAccelAng()<0) bullet->setAccelAng(bullet->getAccelAng()+2*M_PI);
	
	if(bullet->getX()!=pX){
	//Find the angle of acceleration
	if(bullet->getAccelAng() > 135*(M_PI/180) && bullet->getAccelAng() < 225*(M_PI/180)){
	accelAng = M_PI+asin(
	
	(pY-bullet->getY())/
	(calcDistance(bullet->getX(),bullet->getY(),pX,pY)));
	if(bullet->getX()getX()-pX)/
	(calcDistance(bullet->getX(),bullet->getY(),pX,pY)));
	if(bullet->getY()>pY){
		accelAng = 0-accelAng;
	}
	}
	//Done with finding values
	} 
	
	#if DEBUG == 1
		//Sends all variables used in the first half to the computer for examination
		sprintf(debugPtr,"After first Half of %d:\naccel: %f\naccelAng: %f\noldAccel: %f\noldAccelAng: %f\nnewAccel: %f\nnewAccelAng: %f\nPlanetX: %d\nPlanetY: %d\nBallX: %f\nBallY: %f\n",functionNumber,accel,accelAng,oldAccel,oldAccelAng,newAccel,newAccelAng,pX,pY,bullet->getX(),bullet->getY());
		sendDataToAddress(debugPtr,strlen(debugPtr));
		memset(debugPtr,'\0',500);	//Just to make sure everyting is 0
	#endif
	
	//I need to combine the velocity values with the current ones
	float newAccelX;
	float newAccelY;
	float oldAccelX;
	float oldAccelY;
	
	newAccel = accel;
	newAccelAng = accelAng;
	
	oldAccel = bullet->getAccel();
	oldAccelAng = bullet->getAccelAng();
	
	
	
	oldAccelX = oldAccel*cos(oldAccelAng);
	oldAccelY = oldAccel*sin(oldAccelAng);
	
	newAccelX = newAccel*cos(newAccelAng);
	newAccelY = newAccel*sin(newAccelAng);
	newAccelX+= oldAccelX;
	newAccelY+= oldAccelY;
	
	newAccel = sqrt(newAccelX*newAccelX+newAccelY*newAccelY);
	newAccelAng = asin(newAccelY/newAccel);
	
	if(newAccelX<0)
	newAccelAng=(M_PI/2+(M_PI/2-newAccelAng));
	
	#if DEBUG == 1
		//Sends Variables from the second Half
		sprintf(debugPtr,"After second Half of %d:\nnewAccelX: %f\nnewAccelY: %f\nnewAccel: %f\nnewAccelAng: %f\noldAccelX: %f\noldAccelY: %f\n\n",functionNumber,newAccelX,newAccelY,newAccel,newAccelAng,oldAccelX,oldAccelY);
		sendDataToAddress(debugPtr,strlen(debugPtr));
		memset(debugPtr,'\0',500);	//Just to make sure everyting is 0
	#endif	
	
	bullet->setAccel(newAccel);
	bullet->setAccelAng(newAccelAng);
}
This function is called here:
for(i=0;i<levelList[lvlnum].numPlanets;i++){		//For every planet onscreen
				if(calcDistance(shootingBullet.getX(),shootingBullet.getY(),levelList[lvlnum].planetX,levelList[lvlnum].planetY)<levelList[lvlnum].planetD){	//If the bullet is in the planets range
					applyGravity(levelList[lvlnum].planetX,levelList[lvlnum].planetY, &shootingBullet,levelList[lvlnum].planetG);				//Apply gravity for the planet
				}
				if(calcDistance(shootingBullet.getX(),shootingBullet.getY(),levelList[lvlnum].planetX,levelList[lvlnum].planetY)<levelList[lvlnum].planetR){	//If the bullet hits the planet
					bulletAlive = false;								//The bullet isn't alive
					shootingBullet.resetBullet(initX,initY,.000000001,0,0,0);	//Set the bullet back at the initial position, the reason for the speed is that bullets don't like speed 0
				}	
			}
Because the bullit is within the distance two planets, applyGravity should be called twice, and it is. Here is the data that my computer returned:
In The Begginning of 15
accel: 0.000000
accelAng: 2.839309
After first Half of 15:
accel: 0.476158
accelAng: 0.618352
oldAccel: 0.000000
oldAccelAng: 0.000000
newAccel: 0.000000
newAccelAng: 0.000000
PlanetX: 320
PlanetY: 240
BallX: 221.921234
BallY: 310.286469
After second Half of 15:
newAccelX: 0.387990
newAccelY: 0.276026
newAccel: 0.476158
newAccelAng: 0.618352
oldAccelX: -0.000000
oldAccelY: 0.000000

In The Begginning of 16
accel: 0.476158
accelAng: 0.618352
After first Half of 16:
accel: 1.069831
accelAng: nan
oldAccel: 0.000000
oldAccelAng: 0.000000
newAccel: 0.000000
newAccelAng: 0.000000
PlanetX: 150
PlanetY: 300
BallX: 221.921234
BallY: 310.286469
After second Half of 16:
newAccelX: nan
newAccelY: nan
newAccel: nan
newAccelAng: nan
oldAccelX: 0.387990
oldAccelY: 0.276026

Again, what I don't get is that in the 16th time accelAng is nan, but if you take the values from the beginning of the 16th time through and step through the first half of applyGravity then the result isn't nan. Thank you in advance
Re: Math Problems with NaN
December 03, 2010 09:07AM
Your code is pretty hard to read; I would calculate the bullet's distance from the planet once and store it in variable.

You have:
accelAng = M_PI+asin(...)

The input to asin must be a floating point value in the interval [-1,+1]. Try validating your input.
Sorry, only registered users may post in this forum.

Click here to login