在 iPhone 应用程序中进行碰撞检测时不是数字错误 (NAN)
我有一组气球,我试图让它们像球一样相互弹开。 当我开始移动它们然后检测碰撞时,碰撞例程最终会返回气球速度的 NAN。 我最终得到的位置类似于 x=270, y= -nan(0x400000)。 我一整天都在查看代码,但仍然找不到错误,任何帮助将不胜感激。 这是代码:
- (void)MoveBalloons {
for (CurBalloon=1; CurBalloon <= NumBalloons; ++CurBalloon) {
//check for edge hCurBalloont
if (uBalloon[CurBalloon].pos.y > 456) {
uBalloon[CurBalloon].pos.y = 456;
uBalloon[CurBalloon].Vel_y = -uBalloon[CurBalloon].Vel_y;
}
if (uBalloon[CurBalloon].pos.y < 24) {
uBalloon[CurBalloon].pos.y = 24;
uBalloon[CurBalloon].Vel_y = -uBalloon[CurBalloon].Vel_y;
}
if (uBalloon[CurBalloon].pos.x > 289) {
uBalloon[CurBalloon].pos.x = 289;
uBalloon[CurBalloon].Vel_x = -uBalloon[CurBalloon].Vel_x;
}
if (uBalloon[CurBalloon].pos.x < 31) {
uBalloon[CurBalloon].pos.x = 31;
uBalloon[CurBalloon].Vel_x = -uBalloon[CurBalloon].Vel_x;
}
//call loop to go through the balloons for each touch.
//[self CollisionCheck];
NSUInteger h;
float dist, tempvelx, tempvely, temp2velx, temp2vely;;
for (h=1; h <= NumBalloons; ++h) {
//check if balloon is too close
if (CurBalloon == h) { //skip the check ifit's the same balloon
} else {
dist = distanceBetweenPoints(uBalloon[CurBalloon].pos, uBalloon[h].pos);
if (dist <= (kBalloonNear)) { //balloon's touching
tempvelx = uBalloon[CurBalloon].Vel_x;
tempvely = uBalloon[CurBalloon].Vel_y;
temp2velx = uBalloon[h].Vel_x;
temp2vely = uBalloon[h].Vel_y;
tempvelx = (uBalloon[CurBalloon].Vel_x - uBalloon[h].Vel_x) * (sinf(angleBetweenPoints(uBalloon[CurBalloon].pos,uBalloon[h].pos)))*(uBalloon[CurBalloon].Vel_x - uBalloon[h].Vel_x) * (sinf(angleBetweenPoints(uBalloon[CurBalloon].pos,uBalloon[h].pos))) - (uBalloon[CurBalloon].Vel_y - uBalloon[h].Vel_y) * sinf(angleBetweenPoints(uBalloon[CurBalloon].pos, uBalloon[h].pos)) * cosf(angleBetweenPoints(uBalloon[CurBalloon].pos, uBalloon[h].pos)) + uBalloon[h].Vel_x;
tempvely = (uBalloon[CurBalloon].Vel_y - uBalloon[h].Vel_y) * (cosf(angleBetweenPoints(uBalloon[CurBalloon].pos,uBalloon[h].pos))) * (uBalloon[CurBalloon].Vel_y - uBalloon[h].Vel_y) * (cosf(angleBetweenPoints(uBalloon[CurBalloon].pos,uBalloon[h].pos))) - (uBalloon[CurBalloon].Vel_x - uBalloon[h].Vel_x) * sinf(angleBetweenPoints(uBalloon[CurBalloon].pos, uBalloon[h].pos)) * cosf(angleBetweenPoints(uBalloon[CurBalloon].pos, uBalloon[h].pos)) + uBalloon[h].Vel_y;
temp2velx = (uBalloon[CurBalloon].Vel_x - uBalloon[h].Vel_x) * (cosf(angleBetweenPoints(uBalloon[CurBalloon].pos,uBalloon[h].pos))) * (uBalloon[CurBalloon].Vel_x - uBalloon[h].Vel_x) * (cosf(angleBetweenPoints(uBalloon[CurBalloon].pos,uBalloon[h].pos))) + (uBalloon[CurBalloon].Vel_y - uBalloon[h].Vel_y) * sinf(angleBetweenPoints(uBalloon[CurBalloon].pos, uBalloon[h].pos)) * cosf(angleBetweenPoints(uBalloon[CurBalloon].pos, uBalloon[h].pos)) + uBalloon[h].Vel_x;
temp2vely = (uBalloon[CurBalloon].Vel_y - uBalloon[h].Vel_y) * (sinf(angleBetweenPoints(uBalloon[CurBalloon].pos,uBalloon[h].pos)))*(uBalloon[CurBalloon].Vel_y - uBalloon[h].Vel_y) * (sinf(angleBetweenPoints(uBalloon[CurBalloon].pos,uBalloon[h].pos))) - (uBalloon[CurBalloon].Vel_x - uBalloon[h].Vel_x) * sinf(angleBetweenPoints(uBalloon[CurBalloon].pos, uBalloon[h].pos)) * cosf(angleBetweenPoints(uBalloon[CurBalloon].pos, uBalloon[h].pos)) + uBalloon[h].Vel_y;
uBalloon[CurBalloon].Vel_x = tempvelx;
uBalloon[CurBalloon].Vel_y = tempvely;
uBalloon[h].Vel_x = temp2velx; //set to old value of CurBalloon balloon.
uBalloon[h].Vel_y = temp2vely;
}
}
}
if (fabsf(uBalloon[CurBalloon].Vel_x) >= kBalloonMaxSpeed) uBalloon[CurBalloon].Vel_x = kBalloonMaxSpeed;
if (fabsf(uBalloon[CurBalloon].Vel_y) >= kBalloonMaxSpeed) uBalloon[CurBalloon].Vel_y = kBalloonMaxSpeed;
if (fabsf(uBalloon[CurBalloon].Vel_x) <= -kBalloonMaxSpeed) uBalloon[CurBalloon].Vel_x = -kBalloonMaxSpeed;
if (fabsf(uBalloon[CurBalloon].Vel_y) <= -kBalloonMaxSpeed) uBalloon[CurBalloon].Vel_y = -kBalloonMaxSpeed;
if (uBalloon[CurBalloon].Vel_y > KBalloonSpeed) { //if travellCurBalloonng fast, slow CurBalloont up fast to normal speed
uBalloon[CurBalloon].Vel_y = uBalloon[CurBalloon].Vel_y - kBalloonSlowRate;
}
if (uBalloon[CurBalloon].Vel_x > KBalloonSpeed) { //if travellCurBalloonng fast, slow CurBalloont up fast to normal speed
uBalloon[CurBalloon].Vel_x = uBalloon[CurBalloon].Vel_x - kBalloonSlowRate;
}
if (uBalloon[CurBalloon].Vel_y < KBalloonSpeed) { //if travellCurBalloonng fast, slow CurBalloont up fast to normal speed
uBalloon[CurBalloon].Vel_y = uBalloon[CurBalloon].Vel_y + kBalloonSlowRate;
}
if (uBalloon[CurBalloon].Vel_x < KBalloonSpeed) { //if travellCurBalloonng fast, slow CurBalloont up fast to normal speed
uBalloon[CurBalloon].Vel_x = uBalloon[CurBalloon].Vel_x + kBalloonSlowRate;
}
//slow to 0 if velocCurBalloonty CurBalloons CurBalloonnsCurBalloonde the slow rate
if (fabsf(uBalloon[CurBalloon].Vel_x) <= kBalloonSlowRate) uBalloon[CurBalloon].Vel_x = 0;
if (fabsf(uBalloon[CurBalloon].Vel_y) <= kBalloonSlowRate) uBalloon[CurBalloon].Vel_y = 0;
uBalloon[CurBalloon].Vel_x = uBalloon[CurBalloon].Vel_x - kBalloonFallRate; //keep movCurBalloonng down
//add velocCurBalloonty to poCurBalloonnts
uBalloon[CurBalloon].pos.y= uBalloon[CurBalloon].pos.y + uBalloon[CurBalloon].Vel_y;
uBalloon[CurBalloon].pos.x = uBalloon[CurBalloon].pos.x + uBalloon[CurBalloon].Vel_x;
}
}
这是用 c 编写的函数,用于距离和角度。 我什至确保永远不会有 sqrt(-1) 和除以 0:
CGFloat distanceBetweenPoints (CGPoint first, CGPoint second) {
CGFloat deltaX = second.x - first.x;
CGFloat deltaY = second.y - first.y;
if ((deltaX*deltaX + deltaY*deltaY ) == -1) {
return sqrtf(-.99);
} else {
return sqrtf(deltaX*deltaX + deltaY*deltaY );
}
}
CGFloat angleBetweenPoints(CGPoint first, CGPoint second) {
if (first.x - second.x == 0) {
return (pi / 2);
} else {
return atanf((first.y-second.y) / (first.x - second.x));
}
}
I have a set of balloons that I am trying to get to bounce off of each other like balls. When I start to move them and then detect collision, the routine for the collisions eventually returns a NAN for the velocity of the balloons. I end up with a position of something like x=270, y= -nan(0x400000). I've been looking at the code all day and I still can't find the error, any help would be appreciated. Here's the code:
- (void)MoveBalloons {
for (CurBalloon=1; CurBalloon <= NumBalloons; ++CurBalloon) {
//check for edge hCurBalloont
if (uBalloon[CurBalloon].pos.y > 456) {
uBalloon[CurBalloon].pos.y = 456;
uBalloon[CurBalloon].Vel_y = -uBalloon[CurBalloon].Vel_y;
}
if (uBalloon[CurBalloon].pos.y < 24) {
uBalloon[CurBalloon].pos.y = 24;
uBalloon[CurBalloon].Vel_y = -uBalloon[CurBalloon].Vel_y;
}
if (uBalloon[CurBalloon].pos.x > 289) {
uBalloon[CurBalloon].pos.x = 289;
uBalloon[CurBalloon].Vel_x = -uBalloon[CurBalloon].Vel_x;
}
if (uBalloon[CurBalloon].pos.x < 31) {
uBalloon[CurBalloon].pos.x = 31;
uBalloon[CurBalloon].Vel_x = -uBalloon[CurBalloon].Vel_x;
}
//call loop to go through the balloons for each touch.
//[self CollisionCheck];
NSUInteger h;
float dist, tempvelx, tempvely, temp2velx, temp2vely;;
for (h=1; h <= NumBalloons; ++h) {
//check if balloon is too close
if (CurBalloon == h) { //skip the check ifit's the same balloon
} else {
dist = distanceBetweenPoints(uBalloon[CurBalloon].pos, uBalloon[h].pos);
if (dist <= (kBalloonNear)) { //balloon's touching
tempvelx = uBalloon[CurBalloon].Vel_x;
tempvely = uBalloon[CurBalloon].Vel_y;
temp2velx = uBalloon[h].Vel_x;
temp2vely = uBalloon[h].Vel_y;
tempvelx = (uBalloon[CurBalloon].Vel_x - uBalloon[h].Vel_x) * (sinf(angleBetweenPoints(uBalloon[CurBalloon].pos,uBalloon[h].pos)))*(uBalloon[CurBalloon].Vel_x - uBalloon[h].Vel_x) * (sinf(angleBetweenPoints(uBalloon[CurBalloon].pos,uBalloon[h].pos))) - (uBalloon[CurBalloon].Vel_y - uBalloon[h].Vel_y) * sinf(angleBetweenPoints(uBalloon[CurBalloon].pos, uBalloon[h].pos)) * cosf(angleBetweenPoints(uBalloon[CurBalloon].pos, uBalloon[h].pos)) + uBalloon[h].Vel_x;
tempvely = (uBalloon[CurBalloon].Vel_y - uBalloon[h].Vel_y) * (cosf(angleBetweenPoints(uBalloon[CurBalloon].pos,uBalloon[h].pos))) * (uBalloon[CurBalloon].Vel_y - uBalloon[h].Vel_y) * (cosf(angleBetweenPoints(uBalloon[CurBalloon].pos,uBalloon[h].pos))) - (uBalloon[CurBalloon].Vel_x - uBalloon[h].Vel_x) * sinf(angleBetweenPoints(uBalloon[CurBalloon].pos, uBalloon[h].pos)) * cosf(angleBetweenPoints(uBalloon[CurBalloon].pos, uBalloon[h].pos)) + uBalloon[h].Vel_y;
temp2velx = (uBalloon[CurBalloon].Vel_x - uBalloon[h].Vel_x) * (cosf(angleBetweenPoints(uBalloon[CurBalloon].pos,uBalloon[h].pos))) * (uBalloon[CurBalloon].Vel_x - uBalloon[h].Vel_x) * (cosf(angleBetweenPoints(uBalloon[CurBalloon].pos,uBalloon[h].pos))) + (uBalloon[CurBalloon].Vel_y - uBalloon[h].Vel_y) * sinf(angleBetweenPoints(uBalloon[CurBalloon].pos, uBalloon[h].pos)) * cosf(angleBetweenPoints(uBalloon[CurBalloon].pos, uBalloon[h].pos)) + uBalloon[h].Vel_x;
temp2vely = (uBalloon[CurBalloon].Vel_y - uBalloon[h].Vel_y) * (sinf(angleBetweenPoints(uBalloon[CurBalloon].pos,uBalloon[h].pos)))*(uBalloon[CurBalloon].Vel_y - uBalloon[h].Vel_y) * (sinf(angleBetweenPoints(uBalloon[CurBalloon].pos,uBalloon[h].pos))) - (uBalloon[CurBalloon].Vel_x - uBalloon[h].Vel_x) * sinf(angleBetweenPoints(uBalloon[CurBalloon].pos, uBalloon[h].pos)) * cosf(angleBetweenPoints(uBalloon[CurBalloon].pos, uBalloon[h].pos)) + uBalloon[h].Vel_y;
uBalloon[CurBalloon].Vel_x = tempvelx;
uBalloon[CurBalloon].Vel_y = tempvely;
uBalloon[h].Vel_x = temp2velx; //set to old value of CurBalloon balloon.
uBalloon[h].Vel_y = temp2vely;
}
}
}
if (fabsf(uBalloon[CurBalloon].Vel_x) >= kBalloonMaxSpeed) uBalloon[CurBalloon].Vel_x = kBalloonMaxSpeed;
if (fabsf(uBalloon[CurBalloon].Vel_y) >= kBalloonMaxSpeed) uBalloon[CurBalloon].Vel_y = kBalloonMaxSpeed;
if (fabsf(uBalloon[CurBalloon].Vel_x) <= -kBalloonMaxSpeed) uBalloon[CurBalloon].Vel_x = -kBalloonMaxSpeed;
if (fabsf(uBalloon[CurBalloon].Vel_y) <= -kBalloonMaxSpeed) uBalloon[CurBalloon].Vel_y = -kBalloonMaxSpeed;
if (uBalloon[CurBalloon].Vel_y > KBalloonSpeed) { //if travellCurBalloonng fast, slow CurBalloont up fast to normal speed
uBalloon[CurBalloon].Vel_y = uBalloon[CurBalloon].Vel_y - kBalloonSlowRate;
}
if (uBalloon[CurBalloon].Vel_x > KBalloonSpeed) { //if travellCurBalloonng fast, slow CurBalloont up fast to normal speed
uBalloon[CurBalloon].Vel_x = uBalloon[CurBalloon].Vel_x - kBalloonSlowRate;
}
if (uBalloon[CurBalloon].Vel_y < KBalloonSpeed) { //if travellCurBalloonng fast, slow CurBalloont up fast to normal speed
uBalloon[CurBalloon].Vel_y = uBalloon[CurBalloon].Vel_y + kBalloonSlowRate;
}
if (uBalloon[CurBalloon].Vel_x < KBalloonSpeed) { //if travellCurBalloonng fast, slow CurBalloont up fast to normal speed
uBalloon[CurBalloon].Vel_x = uBalloon[CurBalloon].Vel_x + kBalloonSlowRate;
}
//slow to 0 if velocCurBalloonty CurBalloons CurBalloonnsCurBalloonde the slow rate
if (fabsf(uBalloon[CurBalloon].Vel_x) <= kBalloonSlowRate) uBalloon[CurBalloon].Vel_x = 0;
if (fabsf(uBalloon[CurBalloon].Vel_y) <= kBalloonSlowRate) uBalloon[CurBalloon].Vel_y = 0;
uBalloon[CurBalloon].Vel_x = uBalloon[CurBalloon].Vel_x - kBalloonFallRate; //keep movCurBalloonng down
//add velocCurBalloonty to poCurBalloonnts
uBalloon[CurBalloon].pos.y= uBalloon[CurBalloon].pos.y + uBalloon[CurBalloon].Vel_y;
uBalloon[CurBalloon].pos.x = uBalloon[CurBalloon].pos.x + uBalloon[CurBalloon].Vel_x;
}
}
Here's the functions written in c that are used for distance and the angle. I'm even making sure to never have a sqrt(-1) and division by 0:
CGFloat distanceBetweenPoints (CGPoint first, CGPoint second) {
CGFloat deltaX = second.x - first.x;
CGFloat deltaY = second.y - first.y;
if ((deltaX*deltaX + deltaY*deltaY ) == -1) {
return sqrtf(-.99);
} else {
return sqrtf(deltaX*deltaX + deltaY*deltaY );
}
}
CGFloat angleBetweenPoints(CGPoint first, CGPoint second) {
if (first.x - second.x == 0) {
return (pi / 2);
} else {
return atanf((first.y-second.y) / (first.x - second.x));
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我认为这是你的问题(或其中之一)。 你不能取负数的平方根(无论是-1还是-.99都没有关系)。
I think this is your problem (or one of them). You can't take the square root of a negative number (and it doesn't matter if it's -1 or -.99).
这可能不是错误的根源,但这个函数不太正确:
这将始终返回 -pi/2 和 +pi/2 之间的角度,并且如果
first.它可能返回不正确的结果。 x - secondary.x
非常小并且接近 0,但不完全是 0。相反,只需使用 atan2:atan2()
返回从 -pi 到 +pi 的完整角度范围,并适当处理边缘情况。 这可能不会影响您,因为您只是计算所得角度的正弦/余弦。 然而,您这样做的效率非常低——您调用angleBetweenPoints()
8 (!) 次,而结果却是相同的,并且需要 4sin( ) 和 4 个 cos() 。 您可以跳过所有三角学,只使用相似三角形的几何形状来获得相同的结果。
This probably isn't the source of your error, but this function isn't quite right:
This will always return an angle between -pi/2 and +pi/2, and it may return an incorrect result if
first.x - second.x
is very small and close to 0, but not exactly 0. Instead, just use atan2:atan2()
returns the full range of angles from -pi to +pi, and handles the edge cases appropriately. This probably won't affect you since you're just taking the sin/cos of the resulting angle. You're doing so in a very inefficient manner, however -- you're callingangleBetweenPoints()
8 (!) times when the result is the same very time, and taking 4sin()
s and 4cos()
s. You could skip all of the trigonometry and just use the geometry of similar triangles to get the same results.如果 uBalloon 是一个数组,则迭代次数应在 0:(n-1) 之间。
例如
If uBalloon is an array your iteration should be between 0:(n-1).
E.g.