Division on Zero

Discuss any Chipmunk bugs here.

Re: Division on Zero

Postby ShiftZ » Thu Oct 07, 2010 5:06 am

One more... no, not div by zero. Got invalid floating point operation on cpSpaceHash.c: 230 while trying to add a new shape in scene:

static inline int
floor_int(cpFloat f)
{
int i = (int)f;
...

it caused by uninitialized values of shape->bb.
Initialization has been commented for some reason cpShape.c:65
// cpShapeCacheBB(shape);

shape may have huge bb size and filll whole hash space, also may lead to very long loop casescpSpaceHash:245.
ShiftZ
 
Posts: 114
Joined: Sat Mar 07, 2009 7:23 am

Re: Division on Zero

Postby slembcke » Thu Oct 07, 2010 8:34 am

This should be fixed in trunk as of a couple weeks ago. I had intended to move it so that the bounding box wouldn't be calculated until the shape was actually added to the space. (This was causing some other bug) It seems I missed a couple of cases though.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
User avatar
slembcke
Site Admin
 
Posts: 4164
Joined: Tue Aug 14, 2007 7:13 pm

Re: Division on Zero

Postby ShiftZ » Wed Apr 06, 2011 9:28 am

Anyone know how to trap floating point exception on iPhone.
I had no success. All i can do is just check if floating point exception flag is raised, but it's usless without exact raising location.
ShiftZ
 
Posts: 114
Joined: Sat Mar 07, 2009 7:23 am

Re: Division on Zero

Postby ShiftZ » Fri Sep 23, 2011 7:39 am

slembcke
Hi, again constanly catching floating point exception.

cpPolyShape.c:
cpPolyShapeSegmentQuery(cpPolyShape *poly, cpVect a, cpVect b, cpSegmentQueryInfo *info)

Code: Select all
cpFloat an = cpvdot(a, n);
if(axes[i].d > an) continue;
      
cpFloat bn = cpvdot(b, n);
cpFloat t = (axes[i].d - an)/(bn - an);


If vector a and b enough distant from center (0, 0) and pretty close to each other, then quite likely bn and an would be equal due to lack of float precision. For example :
a.x -132.42502 float
a.y -91.492790 float

b.x -134.37552 float
b.y -90.621086 float

n.x 0.40801811 float
n.y 0.91297394 float

gives equal bn an and division by zero as result. Note that a and b are pretty common values, it's not an exotic case. More distant values gives div by zero more often. I think there should be a way to avoid such inconsistence.
ShiftZ
 
Posts: 114
Joined: Sat Mar 07, 2009 7:23 am

Re: Division on Zero

Postby ShiftZ » Fri Sep 23, 2011 9:53 am

slembcke
Well, anyway, it is missing extra condition check
Code: Select all
 if (an == bn) continue;

in case if ab segment is parallel to polygon edge.


The only thing that i cannot understand is that:
Code: Select all
if(axes[i].d > an) continue;

What does it mean? Why it is working?
Last edited by ShiftZ on Fri Sep 23, 2011 9:59 am, edited 1 time in total.
ShiftZ
 
Posts: 114
Joined: Sat Mar 07, 2009 7:23 am

Re: Division on Zero

Postby slembcke » Fri Sep 23, 2011 9:55 am

Hmm. That's sort of nasty. I'll have to rearrange some of those ops to use the available precision better. It's hitting that surface very nearly parallel to it's surface causing the dot products to be nearly equal even when the line segment size is not particularly small.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
User avatar
slembcke
Site Admin
 
Posts: 4164
Joined: Tue Aug 14, 2007 7:13 pm

Re: Division on Zero

Postby slembcke » Fri Sep 23, 2011 10:05 am

Code: Select all
if(axes[i].d > an) continue;


That checks if the starting point of the segment query is already behind that particular axis. Queries aren't checked against the interior of shapes, so it needs to reject those cases.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
User avatar
slembcke
Site Admin
 
Posts: 4164
Joined: Tue Aug 14, 2007 7:13 pm

Re: Division on Zero

Postby ShiftZ » Fri Sep 23, 2011 10:05 am

slembcke wrote:Hmm. That's sort of nasty. I'll have to rearrange some of those ops to use the available precision better.

You can localize calculation of t, but actually there is no need to do that since very close an and bn unlikly hit the poly edge. All you need to fix it is just to add extra condition check:

Code: Select all
cpFloat an = cpvdot(a, n);
if(axes[i].d > an) continue;
     
cpFloat bn = cpvdot(b, n);
if (an == bn) continue; // Parallel surfaces or very close to parallel
cpFloat t = (axes[i].d - an)/(bn - an);


However this wont fix a rare case of distant segment close to parallel, but still crossing the edge. It wont hit and this will be a bug. To fix it you'll have to calculate t relative one of the poly vertex. Something link:
float an = (a - v[i]) dot n;
float bn = (b - v[i]) dot n;
float t = an / (bn - an);
ShiftZ
 
Posts: 114
Joined: Sat Mar 07, 2009 7:23 am

Re: Division on Zero

Postby ShiftZ » Tue Feb 14, 2012 4:22 am

Hey, another division by zero here

Code: Select all
cpBB.h:
static inline cpFloat cpBBSegmentQuery(cpBB bb, cpVect a, cpVect b)
{
   cpFloat idx = 1.0f/(b.x - a.x);
   cpFloat tx1 = (bb.l == a.x ? -INFINITY : (bb.l - a.x)*idx);
   cpFloat tx2 = (bb.r == a.x ?  INFINITY : (bb.r - a.x)*idx);
   cpFloat txmin = cpfmin(tx1, tx2);
   cpFloat txmax = cpfmax(tx1, tx2);
   
   cpFloat idy = 1.0f/(b.y - a.y);
   cpFloat ty1 = (bb.b == a.y ? -INFINITY : (bb.b - a.y)*idy);
   cpFloat ty2 = (bb.t == a.y ?  INFINITY : (bb.t - a.y)*idy);
   cpFloat tymin = cpfmin(ty1, ty2);
   cpFloat tymax = cpfmax(ty1, ty2);

1.0f/(b.x - a.x) and 1.0f/(b.y - a.y);
ShiftZ
 
Posts: 114
Joined: Sat Mar 07, 2009 7:23 am

Re: Division on Zero

Postby slembcke » Tue Feb 14, 2012 9:21 am

Yes, those were intended to produce infinity for horizontal or vertical lines.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
User avatar
slembcke
Site Admin
 
Posts: 4164
Joined: Tue Aug 14, 2007 7:13 pm

PreviousNext

Return to Bugs

Who is online

Users browsing this forum: No registered users and 1 guest

cron