I am working on function to determine if a circle and a ray intersect each other. The base of the function comes from this website specifically this page. In the notes on the first page where the author discusses circle and ray intersection he lists this about determining if a circle and ray intersect
The exact behavior is determined by the expression within the square root b * b - 4 * a * c
If this is less than 0 then the line does not intersect the sphere.
If it equals 0 then the line is a tangent to the sphere intersecting it at one point, namely at u = -b/2a.
If it is greater then 0 the line intersects the sphere at two points.
This is where the problem in my code lies. It lies the comparison of the double bb4ac
in the function below.
bool CircleRayIntersect(double ip1_x, double ip1_y, double ip2_x, double ip2_y,
double isc_x, double isc_y, double isc_r,
double &out1_x, double &out1_y,
double &out2_x, double &out2_y)
{
double a,b,c;
double bb4ac;
double r = isc_r;
double dp_x;
double dp_y;
double mu_1;
double mu_2;
double p1_x = ip1_x;
double p1_y = ip1_y;
double p2_x = ip2_x;
double p2_y = ip2_y;
double sc_x = isc_x;
double sc_y = isc_y;
dp_x = p2_x - p1_x;
dp_y = p2_y - p1_y;
a = dp_x * dp_x + dp_y * dp_y;
b = 2 * (dp_x * (p1_x - sc_x) + dp_y * (p1_y - sc_y));
c = sc_x * sc_x + sc_y * sc_y ;
c += p1_x * p1_x + p1_y * p1_y;
c -= 2 * (sc_x * p1_x + sc_y * p1_y);
c -= r * r;
bb4ac = b * b - 4 * a * c;
// Checks to make sure that the line actually intersects
TRACE(" -- Checking a: %f\n", a);
TRACE(" -- Checking bb4ac: %f\n", bb4ac);
if (abs(a) < 1E-9 || bb4ac < 0.0)
{
if(bb4ac < 0.0)
{
TRACE("bb4ac is less than zero: %d < 0.0 = %d\n", bb4ac, (bb4ac < 0.0));
TRACE("bb4ac is less than zero: %f < 0.0 = %f\n", bb4ac, (bb4ac < 0.0));
}
if (abs(a) < 1E-9)
TRACE("abs(a) is less than zero\n");
mu_1 = 0;
mu_2 = 0;
TRACE("Ray does not intersect with circle!\n");
return FALSE;
}
mu_1 = (-b + sqrt(bb4ac)) / (2 * a);
mu_2 = (-b - sqrt(bb4ac)) / (2 * a);
out1_x = p1_x + (mu_1*(p2_x-p1_x));
out1_y = p1_y + (mu_1*(p2_y-p1_y));
out2_x = p1_x + (mu_2*(p2_x-p1_x));
out2_y = p1_y + (mu_2*(p2_y-p1_y));
return TRUE;
}
At some points, when this code is called with certain arguments bb4ac
ends up being equal to -0.0
. When this happens the checking of bb4ac
against the rules listed above becomes broken. Here is some sample output from the TRACE
statements when bb4ac
is -0.0
.
-- Checking a: 129.066667
-- Checking bb4ac: -0.000000
bb4ac is less than zero: 0 < 0.0 = -1114636288
bb4ac is less than zero: -0.000000 < 0.0 = 0.000000
Judging by the output of the TRACE
it looks like the if(..)
statement that compares bb4ac
with 0
does not interpret bb4ac
properly. Seeing that bb4ac
is printed as -1114636288
when interpreted with the %d
flag and -0.000
when interpreted with the %f
flag, I would have to think that bb4ac
is being interpreted into -1114636288
in the if
statement and not -0.000
.
How can I write the if statement to properly interpret bb4ac
as -0.000
? Why is it seeing it as that in the first place?